gtranslator r3580 - in trunk: . data data/desktop data/mime data/pixmaps doc/reference help help/C m4 plugins plugins/alternate-language plugins/charmap plugins/dictionary plugins/fullscreen plugins/insert-tags plugins/open-tran plugins/source-code-view plugins/subversion po src src/dialogs src/plugin-system src/toolbareditor src/translation-memory src/translation-memory/berkeley



Author: psanxiao
Date: Tue Sep 16 07:58:13 2008
New Revision: 3580
URL: http://svn.gnome.org/viewvc/gtranslator?rev=3580&view=rev

Log:
Merge branch 'master' into svnbranch


Added:
   trunk/data/pixmaps/
   trunk/data/pixmaps/Makefile.am
   trunk/data/pixmaps/gtranslator-fuzzy-next.png
   trunk/data/pixmaps/gtranslator-fuzzy-prev.png
   trunk/data/pixmaps/gtranslator-plugin.png
      - copied, changed from r3579, /trunk/data/gtranslator-plugin.png
   trunk/data/pixmaps/gtranslator-untranslated-next.png
   trunk/data/pixmaps/gtranslator-untranslated-prev.png
   trunk/help/gtranslator.omf.in
   trunk/m4/
   trunk/m4/berkeley_db.m4
   trunk/m4/gtk-doc.m4
   trunk/plugins/dictionary/gnome-dictionary.png
   trunk/plugins/open-tran/inkscape.png
   trunk/plugins/open-tran/suse.png
   trunk/plugins/open-tran/xfce.png
   trunk/plugins/source-code-view/
   trunk/plugins/source-code-view/Makefile.am
   trunk/plugins/source-code-view/source-code-view-dialog.glade
   trunk/plugins/source-code-view/source-code-view-plugin.c
   trunk/plugins/source-code-view/source-code-view-plugin.h
   trunk/plugins/source-code-view/source-code-view.gtranslator-plugin.desktop.in
   trunk/plugins/source-code-view/viewer.c
   trunk/plugins/source-code-view/viewer.glade
   trunk/plugins/source-code-view/viewer.h
   trunk/plugins/subversion/
   trunk/plugins/subversion/Makefile.am
   trunk/plugins/subversion/async-command.c
   trunk/plugins/subversion/async-command.h
   trunk/plugins/subversion/checkout-dialog.c
   trunk/plugins/subversion/checkout-dialog.h
   trunk/plugins/subversion/command.c
   trunk/plugins/subversion/command.h
   trunk/plugins/subversion/commit-dialog.c
   trunk/plugins/subversion/commit-dialog.h
   trunk/plugins/subversion/diff-dialog.c
   trunk/plugins/subversion/diff-dialog.h
   trunk/plugins/subversion/subversion-enum-types.c.template
   trunk/plugins/subversion/subversion-enum-types.h.template
   trunk/plugins/subversion/subversion-icon.png
   trunk/plugins/subversion/subversion-plugin.c
   trunk/plugins/subversion/subversion-plugin.h
   trunk/plugins/subversion/subversion-utils.c
   trunk/plugins/subversion/subversion-utils.h
   trunk/plugins/subversion/subversion.glade
   trunk/plugins/subversion/subversion.gtranslator-plugin.desktop.in
   trunk/plugins/subversion/svn-add-command.c
   trunk/plugins/subversion/svn-add-command.h
   trunk/plugins/subversion/svn-cat-command.c
   trunk/plugins/subversion/svn-cat-command.h
   trunk/plugins/subversion/svn-checkout-command.c
   trunk/plugins/subversion/svn-checkout-command.h
   trunk/plugins/subversion/svn-command.c
   trunk/plugins/subversion/svn-command.h
   trunk/plugins/subversion/svn-commit-command.c
   trunk/plugins/subversion/svn-commit-command.h
   trunk/plugins/subversion/svn-diff-command.c
   trunk/plugins/subversion/svn-diff-command.h
   trunk/plugins/subversion/svn-resolve-command.c
   trunk/plugins/subversion/svn-resolve-command.h
   trunk/plugins/subversion/svn-status-command.c
   trunk/plugins/subversion/svn-status-command.h
   trunk/plugins/subversion/svn-status.c
   trunk/plugins/subversion/svn-status.h
   trunk/plugins/subversion/svn-update-command.c
   trunk/plugins/subversion/svn-update-command.h
   trunk/plugins/subversion/update-dialog.c
   trunk/plugins/subversion/update-dialog.h
   trunk/plugins/subversion/vcs-status-tree-view.c
   trunk/plugins/subversion/vcs-status-tree-view.h
   trunk/src/context.c
   trunk/src/context.h
   trunk/src/debug.h
   trunk/src/dialogs/assistant.c
   trunk/src/dialogs/assistant.h
   trunk/src/dialogs/jump-dialog.c
   trunk/src/dialogs/jump-dialog.glade
   trunk/src/dialogs/jump-dialog.h
   trunk/src/translation-memory/
   trunk/src/translation-memory/Makefile.am
   trunk/src/translation-memory/berkeley/
   trunk/src/translation-memory/berkeley/Makefile.am
   trunk/src/translation-memory/berkeley/berkeley.c
   trunk/src/translation-memory/berkeley/berkeley.h
   trunk/src/translation-memory/berkeley/db-base.c
   trunk/src/translation-memory/berkeley/db-base.h
   trunk/src/translation-memory/berkeley/db-keys.c
   trunk/src/translation-memory/berkeley/db-keys.h
   trunk/src/translation-memory/berkeley/db-orig.c
   trunk/src/translation-memory/berkeley/db-orig.h
   trunk/src/translation-memory/berkeley/db-trans.c
   trunk/src/translation-memory/berkeley/db-trans.h
   trunk/src/translation-memory/berkeley/db-words.c
   trunk/src/translation-memory/berkeley/db-words.h
   trunk/src/translation-memory/translation-memory-ui.c
   trunk/src/translation-memory/translation-memory-ui.h
   trunk/src/translation-memory/translation-memory.c
   trunk/src/translation-memory/translation-memory.h
Removed:
   trunk/data/gtranslator-plugin.png
   trunk/help/C/Makefile.am
   trunk/help/C/gtranslator-C.omf
   trunk/install-sh
   trunk/src/comment.c
   trunk/src/comment.h
   trunk/src/dialogs/bookmarks-dialog.glade
Modified:
   trunk/ChangeLog
   trunk/INSTALL
   trunk/Makefile.am
   trunk/configure.ac
   trunk/data/ChangeLog
   trunk/data/Makefile.am
   trunk/data/desktop/Makefile.am
   trunk/data/desktop/gtranslator.desktop.in.in
   trunk/data/gtr-toolbar.xml
   trunk/data/gtranslator-ui.xml
   trunk/data/mime/Makefile.am
   trunk/data/po.lang
   trunk/doc/reference/Makefile.am
   trunk/doc/reference/gtranslator-docs.sgml
   trunk/doc/reference/gtranslator.types
   trunk/help/C/gtranslator.xml
   trunk/help/Makefile.am
   trunk/plugins/Makefile.am
   trunk/plugins/alternate-language/alternate-language-panel.c
   trunk/plugins/alternate-language/alternate-language-plugin.c
   trunk/plugins/charmap/Makefile.am
   trunk/plugins/charmap/charmap-plugin.c
   trunk/plugins/dictionary/Makefile.am
   trunk/plugins/dictionary/dict-panel.c
   trunk/plugins/dictionary/dict-panel.h
   trunk/plugins/dictionary/dict.gtranslator-plugin.desktop.in
   trunk/plugins/dictionary/dictionary-plugin.c
   trunk/plugins/dictionary/gdict-sidebar.c
   trunk/plugins/fullscreen/fullscreen-plugin.c
   trunk/plugins/insert-tags/insert-tags-plugin.c
   trunk/plugins/open-tran/Makefile.am
   trunk/plugins/open-tran/open-tran-dialog.glade
   trunk/plugins/open-tran/open-tran-panel.c
   trunk/plugins/open-tran/open-tran-plugin.c
   trunk/po/ChangeLog
   trunk/po/POTFILES.in
   trunk/po/POTFILES.skip
   trunk/po/de.po
   trunk/po/gl.po
   trunk/src/ChangeLog
   trunk/src/Makefile.am
   trunk/src/actions-edit.c
   trunk/src/actions-file.c
   trunk/src/actions-go.c
   trunk/src/actions-help.c
   trunk/src/actions-search.c
   trunk/src/actions-view.c
   trunk/src/actions.h
   trunk/src/application.c
   trunk/src/application.h
   trunk/src/dialogs/Makefile.am
   trunk/src/dialogs/close-confirmation-dialog.c
   trunk/src/dialogs/comment-dialog.c
   trunk/src/dialogs/file-dialogs.c
   trunk/src/dialogs/file-dialogs.h
   trunk/src/dialogs/header-dialog.c
   trunk/src/dialogs/header-dialog.glade
   trunk/src/dialogs/preferences-dialog.c
   trunk/src/dialogs/preferences-dialog.glade
   trunk/src/dialogs/preferences-dialog.h
   trunk/src/dialogs/profile-dialog.c
   trunk/src/dialogs/profile-dialog.glade
   trunk/src/dialogs/profile-dialog.h
   trunk/src/dialogs/search-dialog.c
   trunk/src/dialogs/search-dialog.glade
   trunk/src/draw-spaces.c
   trunk/src/header.c
   trunk/src/header.h
   trunk/src/history-entry.c
   trunk/src/main.c
   trunk/src/message-area.c
   trunk/src/message-area.h
   trunk/src/message-table.c
   trunk/src/msg.c
   trunk/src/msg.h
   trunk/src/notebook.c
   trunk/src/notebook.h
   trunk/src/plugin-system/module.c
   trunk/src/plugin-system/module.h
   trunk/src/plugin-system/plugin-info-priv.h
   trunk/src/plugin-system/plugin-info.c
   trunk/src/plugin-system/plugin-info.h
   trunk/src/plugin-system/plugin-manager.c
   trunk/src/plugin-system/plugin.c
   trunk/src/plugin-system/plugin.h
   trunk/src/plugin-system/plugins-engine.c
   trunk/src/plugin-system/plugins-engine.h
   trunk/src/plugin-system/update-from-gedit.sh
   trunk/src/po.c
   trunk/src/po.h
   trunk/src/prefs-manager-app.c
   trunk/src/prefs-manager.c
   trunk/src/prefs-manager.h
   trunk/src/profile.c
   trunk/src/profile.h
   trunk/src/statusbar.c
   trunk/src/statusbar.h
   trunk/src/tab.c
   trunk/src/tab.h
   trunk/src/toolbareditor/egg-editable-toolbar.c
   trunk/src/toolbareditor/egg-editable-toolbar.h
   trunk/src/toolbareditor/egg-toolbar-editor.c
   trunk/src/toolbareditor/egg-toolbar-editor.h
   trunk/src/toolbareditor/egg-toolbars-model.c
   trunk/src/toolbareditor/egg-toolbars-model.h
   trunk/src/toolbareditor/eggtreemultidnd.c
   trunk/src/toolbareditor/eggtreemultidnd.h
   trunk/src/utils.c
   trunk/src/utils.h
   trunk/src/view.c
   trunk/src/view.h
   trunk/src/window.c
   trunk/src/window.h

Modified: trunk/INSTALL
==============================================================================
--- trunk/INSTALL	(original)
+++ trunk/INSTALL	Tue Sep 16 07:58:13 2008
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006 Free Software Foundation, Inc.
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
 
 This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
@@ -10,10 +10,7 @@
 Basic Installation
 ==================
 
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package.  The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
+These are generic installation instructions.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
@@ -26,9 +23,9 @@
 
    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
+the results of its tests to speed up reconfiguring.  (Caching is
 disabled by default to prevent problems with accidental use of stale
-cache files.
+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
@@ -38,17 +35,20 @@
 may remove or edit it.
 
    The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
+`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.
+     `./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' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
 
   2. Type `make' to compile the package.
 
@@ -78,7 +78,7 @@
 by setting variables in the command line or in the environment.  Here
 is an example:
 
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
 
    *Note Defining Variables::, for more details.
 
@@ -87,15 +87,17 @@
 
 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 can use GNU `make'.  `cd' to the
+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 `..'.
 
-   With a non-GNU `make', it is safer 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.
+   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
 ==================
@@ -188,12 +190,12 @@
      ./configure CC=/usr/local2/bin/gcc
 
 causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
+overridden in the site shell script).  Here is a another example:
 
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug.  Until the bug is fixed you can use this workaround:
+     /bin/bash ./configure CONFIG_SHELL=/bin/bash
 
-     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
 
 `configure' Invocation
 ======================

Modified: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am	(original)
+++ trunk/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -1,14 +1,17 @@
 ## the main Makefile.am
 
-SUBDIRS = data doc help man src plugins po
+SUBDIRS = data help man src doc plugins po
 
 EXTRA_DIST= \
 		DEPENDS \
 		HACKING \
 		gtranslator.spec.in \
 		gtranslator.spec \
-		intltool-extract.in \
-		intltool-merge.in \
-		intltool-update.in \
 		omf.make \
-		xmldocs.make
+		xmldocs.make \
+		gnome-doc-utils.make
+
+DISTCLEANFILES = 		\
+	gnome-doc-utils.make    
+
+DISTCHECK_CONFIGURE_FLAGS = --disable-scrollkeeper --enable-gtk-doc
\ No newline at end of file

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Tue Sep 16 07:58:13 2008
@@ -8,7 +8,9 @@
 	http://bugzilla.gnome.org/enter_bug.cgi?product=gtranslator)
 
 AC_CONFIG_SRCDIR(src/main.c)
+AC_CONFIG_MACRO_DIR([m4])
 AM_CONFIG_HEADER(config.h)
+AC_CONFIG_MACRO_DIR ([m4])
 
 GTR_API_VERSION=2.0
 AC_SUBST(GTR_API_VERSION)
@@ -36,6 +38,7 @@
 AC_ISC_POSIX
 AM_PROG_LIBTOOL
 AC_TYPE_SIGNAL
+GNOME_DOC_INIT
 GTK_DOC_CHECK([1.0])
 
 dnl -------------------------------------------------------------------
@@ -78,8 +81,13 @@
 SOURCEVIEW_REQUIRED=2.0.0
 GDL_REQUIRED=0.6.0
 LIBGUCHARMAP_OPTIONAL=1.6.0
-GDICT_OPTIONAL=0.10.8
+GDICT_OPTIONAL=0.11.0
 GTKSPELL_OPTIONAL=2.0.2
+SVN_MAJOR=1
+SVN_MINOR=5
+SVN_PATCH=0
+LIBSVN_OPTIONAL=$SVN_MAJOR.$SVN_MINOR.$SVN_PATCH
+LIBSOUP_OPTIONAL=2.4.0
 
 AC_SUBST(GTK_REQUIRED)
 AC_SUBST(GLIB_REQUIRED)
@@ -143,6 +151,17 @@
 ])
 
 dnl -------------------------------------------------------------------
+dnl Check for libdb >= 4.3
+dnl -------------------------------------------------------------------
+AX_BERKELEY_DB(4.3, [
+	AC_DEFINE([HAVE_DB_BERKELEY], 1, [A usable libdb library was found])
+	AC_DEFINE_UNQUOTED(DB_HEADER, ["$DB_HEADER"])
+	LDFLAGS="$LDFLAGS $DB_LIBS"
+],[
+	AC_MSG_ERROR([Cannot find Berkeley DB >= 4.3])
+])
+
+dnl -------------------------------------------------------------------
 dnl Check for gtkspell >= 2.0 and use it if found
 dnl -------------------------------------------------------------------
 have_gtkspell=no
@@ -240,16 +259,187 @@
 
 AM_CONDITIONAL(USE_CHARMAP, test x"$have_gucharmap" = "xyes")
 
+dnl  **********************************************************
+dnl  check if we have svn libraries to build subversion plugin
+dnl  (stolen from kdevelop ;-)
+dnl  **********************************************************
+
+AC_MSG_CHECKING(for Subversion svn-config)
+AC_ARG_WITH(subversion-dir,
+		AC_HELP_STRING([--with-subversion-dir=DIR],[where Subversion is installed]),
+		[
+				SVNCONFIG="$withval/bin/svn-config"
+		])
+
+if test -z "$SVNCONFIG"; then
+		_SVNCONFIG="`svn-config --prefix 2> /dev/null`"
+		if test -n "$_SVNCONFIG"; then
+				SVNCONFIG="$_SVNCONFIG/bin/svn-config"
+		fi
+fi
+
+AC_SUBST(SVNCONFIG)
+if test -x "$SVNCONFIG"; then
+		SVNLD="`$SVNCONFIG --ldflags 2> /dev/null`"
+		SVN_LIB="`$SVNCONFIG --libs --cflags 2> /dev/null` -lsvn_client-1 -lsvn_subr-1"
+		dnl ugly hack for subversion svn-config problems in 0.14.x, to be removed when svn-config is fixed
+		SVN_INCLUDE="`$SVNCONFIG --includes 2> /dev/null` -I$_SVNCONFIG/include/subversion-1/"
+		AC_MSG_RESULT(yes)
+else
+		AC_MSG_RESULT(not found)
+		
+		dnl just a fallback to debian's config so that it works for me :)
+		AC_ARG_WITH(svn-include,
+								AC_HELP_STRING([--with-svn-include=DIR],[Use the given path to the subversion headers.]),
+								[
+								if test "$withval" != "yes" -a "$withval" != ""; then
+										SVN_INCLUDES=$withval
+								fi
+								])
+		if test -z "$SVN_INCLUDES"; then
+			SVN_INCLUDES="/usr/local/include /usr/include"
+		fi
+		AC_MSG_CHECKING([for Subversion headers])
+		SVN_INCLUDE=""
+		for VALUE in $SVN_INCLUDES ; do
+				if test -f $VALUE/subversion-1/svn_types.h ; then
+						SVN_INCLUDE=$VALUE/subversion-1
+						break
+				fi
+				if test -f $VALUE/svn_types.h ; then
+						SVN_INCLUDE=$VALUE
+						break
+				fi
+		done
+		if test $SVN_INCLUDE ; then
+				AC_MSG_RESULT([found])
+		else
+				AC_MSG_RESULT([not found])
+		fi
+		SVN_LIBS="/usr/local/lib /usr/lib"
+		AC_ARG_WITH(svn-lib,
+						AC_HELP_STRING([--with-svn-lib=DIR],[Use the given path to the subversion libraries.]),
+						[
+							if test "$withval" != "yes" -a "$withval" != ""; then
+								SVN_LIBS=$withval
+							fi
+						])
+		AC_MSG_CHECKING([for Subversion libraries])
+		SVN_LIB=""
+		for VALUE in $SVN_LIBS ; do
+				if ls $VALUE/libsvn_client-1.* 1>/dev/null 2>&1; then
+						SVN_LIB=$VALUE
+						break
+				fi
+		done
+		if test $SVN_LIB ; then
+				AC_MSG_RESULT([found])
+		else
+				AC_MSG_RESULT([not found])
+		fi
+fi
+
+dnl ******************************************************************
+dnl Check for extra libs required by subversion.
+dnl FIXME: This should actually be done by subversion and not by us.
+dnl ******************************************************************
+
+AC_ARG_ENABLE(plugin-subversion,
+  AC_HELP_STRING([--disable-plugin-subversion],[Disable subversion support in GTranslator.]),
+  [ if test "$enableval" = "no"; then
+        user_disabled_subversion=1
+    fi ],
+  [ user_disabled_subversion=0 ] )
+
+AC_MSG_CHECKING(if subversion support is disabled)
+if test "$user_disabled_subversion" = 1; then
+	AC_MSG_RESULT(yes)
+	SVN_INCLUDE=""
+	SVN_LIB=""
+else
+	AC_MSG_RESULT(no)
+fi
+
+if test -n "$SVN_INCLUDE" ; then
+	dnl ------------------------------------
+	dnl APR. Required by subversion (devel)
+	dnl ------------------------------------
+	have_atr=no
+	PKG_CHECK_MODULES(APR,                            \
+		apr-1, have_apr=yes, have_apr=no)
+	if test x"$have_apr" = "xno"; then
+		SVN_INCLUDE=""
+	fi
+	
+	dnl -----------------------------------------
+	dnl APR util. Required by subversion (devel)
+	dnl------------------------------------------
+	have_atr_util=no
+	PKG_CHECK_MODULES(APR_UTILS,                            \
+		apr-util-1, have_apr_util=yes, have_apr_util=no)
+	if test x"$have_apr_util" = "xno"; then
+		SVN_INCLUDE=""
+	fi
+	
+	dnl -----------------------------------------
+	dnl NEON. Required by subversion (devel)
+	dnl------------------------------------------
+	have_neon=no
+	PKG_CHECK_MODULES(NEON,                            \
+                neon, have_neon=yes, have_neon=no)
+        if test x"$have_neon" = "xno"; then
+		SVN_INCLUDE=""
+	fi
+
+	dnl Make sure our SVN version is high enough
+	dnl Eww, eww, eww, this is dirty
+	AC_MSG_CHECKING([for subversion >= $LIBSVN_OPTIONAL])
+	AC_LANG(C)
+	dnl Temporarily set CFLAGS so that include dirs are found
+	CFLAGS_TMP=$CFLAGS
+	CFLAGS="-I$SVN_INCLUDE $APR_CFLAGS"
+	AC_COMPILE_IFELSE(
+		[AC_LANG_PROGRAM([[#include <svn_version.h>]],
+			[[
+				#if (SVN_VER_MAJOR < $SVN_MAJOR) || (SVN_VER_MINOR < $SVN_MINOR) || (SVN_VER_PATCH < $SVN_PATCH)
+				#	error "Version too low"
+				#endif
+			]])], AC_MSG_RESULT(yes), have_svn_version=no)
+	if test x"$have_svn_version" = "xno"; then
+		AC_MSG_RESULT(no)
+		SVN_INCLUDE=""
+	fi
+	CFLAGS=$CFLAGS_TMP
+fi
+
+dnl ------------------------------------------
+dnl Finally prepare subversion build flags
+dnl ------------------------------------------
+
+if test -n "$SVN_INCLUDE" ; then
+	SVN_INCLUDE="-I$SVN_INCLUDE"
+	if test x != "x$SVN_LIB" ; then
+	    SVN_LIB="-L$SVN_LIB $APR_LIBS $APR_UTILS_LIBS -lsvn_client-1 -lsvn_subr-1"
+	else
+	    SVN_LIB="$APR_LIBS $APR_UTILS_LIBS -lsvn_client-1 -lsvn_subr-1"
+	fi
+	SVN_CFLAGS="$APR_CFLAGS $APR_UTILS_CFLAGS"
+fi
+
+AM_CONDITIONAL(BUILD_SVN, [test -n "$SVN_INCLUDE"])
+AC_SUBST(SVN_INCLUDE)
+AC_SUBST(SVN_LIB)
+AC_SUBST(SVN_CFLAGS)
 
 dnl -------------------------------------------------------------------
 dnl Enable debug builds.
 dnl -------------------------------------------------------------------
 AC_ARG_ENABLE(debug,
-	[  --enable-debug              Turn on debugging flags (default=yes)],
+	AC_HELP_STRING([--enable-debug],[Turn on debugging flags (default=yes)]),
 	,enable_debug=yes)
 AC_MSG_CHECKING([if a debug friendly version should be build])
 if test "x$enable_debug" = "xyes" ; then
-	CFLAGS="$CFLAGS -ggdb "
+	CFLAGS="$CFLAGS -ggdb -DDEBUG"
 else
 	CFLAGS="`echo $CFLAGS|sed -e s/-g.//g -e s/-ggdb//g`"
 fi
@@ -274,13 +464,13 @@
 data/desktop/gtranslator.desktop.in
 data/mime/Makefile
 data/mime/gtranslator.keys_template
+data/pixmaps/Makefile
 data/scripts/Makefile
 doc/Makefile
 doc/reference/Makefile
 doc/reference/version.xml
 doc/UMTF/Makefile
 help/Makefile
-help/C/Makefile
 man/Makefile
 man/gtranslator.1
 po/Makefile.in
@@ -291,10 +481,14 @@
 plugins/fullscreen/Makefile
 plugins/insert-tags/Makefile
 plugins/open-tran/Makefile
+plugins/source-code-view/Makefile
+plugins/subversion/Makefile
 src/Makefile
 src/dialogs/Makefile
 src/toolbareditor/Makefile
 src/plugin-system/Makefile
+src/translation-memory/Makefile
+src/translation-memory/berkeley/Makefile
 ])
 
 dnl ------------------------------------------------------------------
@@ -310,13 +504,54 @@
 debug friendly build	  :	${enable_debug:-no}
 build with deprecation 	  :	${enable_deprecated:-no}
 compilation flags      	  :	${CFLAGS}
+------------------------------------------------------------------
+"
+if [ test -n "$SVN_INCLUDE" ]; then
+        echo "Building subversion plugin: ............................YES"
+else
+        echo "Building subversion plugin: ............................NO"
+		echo "        Requires apr (>= 0.9.4); http://subversion.org";
+		echo "        Requires apr-util (>= 0.9.4); http://subversion.org";
+		echo "        Requires neon (>= 0.24.5); http://subversion.org";
+		echo "        Requires subversion (>= 1.5.0); http://subversion.org";
+
+fi
+
+if [ test x"$have_gucharmap" = "xyes" ]; then
+	echo "Building charmap plugin: ...............................YES"
+else
+	echo "Building charmap plugin: ...............................NO"
+		echo "        Requires gucharmap >= $LIBGUCHARMAP_OPTIONAL=1.6.0"
+fi
+
+if [ test x"$have_libsoup" = "xyes" ]; then
+	echo "Building open-tran plugin: .............................YES"
+else
+	echo "Building open-tran plugin: .............................NO"
+		echo "        Requires libsoup >= $LIBSOUP_OPTIONAL"
+fi
+
+if [ test x"$have_gdict" = "xyes" ]; then
+	echo "Building dictionary plugin: ............................YES"
+else
+	echo "Building dictionary plugin: ............................NO"
+		echo "        Requires gdict-1.0 >= $GDICT_OPTIONAL"
+fi
+
+if [ test x"$have_gtkspell" = "xyes" ]; then
+	echo "Building spell support: ................................YES"
+else
+	echo "Building spell support: ................................NO"
+		echo "        Requires gtkspell >= $GTKSPELL_OPTIONAL"
+fi
 
+echo "
 ------------------------------------------------------------------
 -- For suggestions, problems & bug reports for gtranslator please
     use http://bugzilla.gnome.org/enter_bug.cgi?product=gtranslator
 
 
-Thanks for your attention and braveness in \"compiling\" gtranslator!
+Thanks for your attention and braveness in compiling gtranslator!
 -- The website for gtranslator is http://gtranslator.sourceforge.net
 
 ------------------------------------------------------------------

Modified: trunk/data/Makefile.am
==============================================================================
--- trunk/data/Makefile.am	(original)
+++ trunk/data/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -3,7 +3,8 @@
 SUBDIRS = \
 	desktop \
 	mime \
-	scripts
+	scripts \
+	pixmaps
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = gtranslator- GTR_API_VERSION@.pc
@@ -18,12 +19,8 @@
 		po.lang \
 		layout.xml
 
-icondir = $(datadir)/pixmaps/gtranslator
-icon_DATA = gtranslator-plugin.png
-
 EXTRA_DIST = \
 		$(ui_DATA) \
-		$(icon_DATA)\
 		gtranslator.pc.in
 
 CLEANFILES =	 			\

Modified: trunk/data/desktop/Makefile.am
==============================================================================
--- trunk/data/desktop/Makefile.am	(original)
+++ trunk/data/desktop/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -18,3 +18,5 @@
 EXTRA_DIST = $(Application_DATA) \
 	$(Applicationicon_DATA) \
 	$(Application_predata)
+
+CLEANFILES = $(Application_DATA)

Modified: trunk/data/desktop/gtranslator.desktop.in.in
==============================================================================
--- trunk/data/desktop/gtranslator.desktop.in.in	(original)
+++ trunk/data/desktop/gtranslator.desktop.in.in	Tue Sep 16 07:58:13 2008
@@ -1,5 +1,4 @@
 [Desktop Entry]
-Encoding=UTF-8
 _Name=Gtranslator PO Editor
 _Comment=Translate and localize applications and libraries
 Icon=gtranslator.png

Modified: trunk/data/gtr-toolbar.xml
==============================================================================
--- trunk/data/gtr-toolbar.xml	(original)
+++ trunk/data/gtr-toolbar.xml	Tue Sep 16 07:58:13 2008
@@ -20,6 +20,9 @@
     <toolitem name="GoPreviousFuzzy"/>
     <toolitem name="GoNextUntranslated"/>
     <toolitem name="GoPreviousUntranslated"/>
+    <toolitem name="GoNextFuzzyUntranslated"/>
+    <toolitem name="GoPreviousFuzzyUntranslated"/>
+    <toolitem name="GoJump"/>
     <toolitem name="SearchFind"/>
     <toolitem name="SearchReplace"/>
 

Modified: trunk/data/gtranslator-ui.xml
==============================================================================
--- trunk/data/gtranslator-ui.xml	(original)
+++ trunk/data/gtranslator-ui.xml	Tue Sep 16 07:58:13 2008
@@ -2,7 +2,6 @@
   <menubar name="MainMenu">
     <menu name="FileMenu" action="File">
       <menuitem name="FileOpenMenu" action="FileOpen"/>
-      <menuitem name="FileOpenCopyMenu" action="FileOpenUri"/>
       <menuitem name="FileRecentFilesMenu" action="FileRecentFiles"/>
       <separator/>
       <menuitem name="FileSaveMenu" action="FileSave"/>
@@ -29,6 +28,8 @@
       <separator/>
       <menuitem name="EditFuzzyMenu" action="EditFuzzy"/>
       <separator/>
+      <menuitem name="EditTranslationMemory" action="EditTranslationMemory"/>
+      <separator/>
       <placeholder name="EditOps_1" />
       <separator/>
       <menuitem name="EditToolbarMenu" action="EditToolbar"/>
@@ -39,7 +40,10 @@
       <separator/>
       <placeholder name="ViewOps_1" />
       <separator/>
-      <menuitem name="ViewSidePaneMenu" action="ViewSidePane"/>
+      <menuitem name="ViewContextMenu" action="ViewContext"/>
+      <menuitem name="ViewTranslationMemoryMenu" action="ViewTranslationMemory"/>
+      <placeholder name="ViewOps_2" />
+      <separator/>
     </menu>
 
     <?--<menu name="BookmarksMenu" action="Bookmarks">
@@ -63,23 +67,30 @@
       <menuitem name="GoForwardMenu" action="GoForward"/>
       <menuitem name="GoLastMenu" action="GoLast"/>
       <separator/>
-      <menuitem name="GoJumpToMenu" action="GoJumpTo"/>
-      <separator/>
       <menuitem name="GoNextFuzzyMenu" action="GoNextFuzzy"/>
       <menuitem name="GoPreviousFuzzyMenu" action="GoPreviousFuzzy"/>
       <separator/>
       <menuitem name="GoNextUntranslatedMenu" action="GoNextUntranslated"/>
       <menuitem name="GoPreviousUntranslatedMenu" action="GoPreviousUntranslated"/>
+      <separator/>
+      <menuitem name="GoNextFuzzyUntranslatedMenu" action="GoNextFuzzyUntranslated"/>
+      <menuitem name="GoPreviousFuzzyUntranslatedMenu" action="GoPreviousFuzzyUntranslated"/>
+      <separator/>
+      <menuitem name="GoJumpMenu" action="GoJump"/>
     </menu>
 
     <menu name="SearchMenu" action="Search">
       <menuitem name="SearchFindMenu" action="SearchFind"/>
-      <menuitem name="SearchFindNextMenu" action="SearchFindNext"/>
+    <?--  <menuitem name="SearchFindNextMenu" action="SearchFindNext"/>
       <menuitem name="SearchFindPreviousMenu" action="SearchFindPrevious"/>
-      <separator/>
+      <separator/>--?>
       <menuitem name="SearchReplaceMenu" action="SearchReplace"/>
     </menu>
 
+    <placeholder name="SubversionPlaceholder" />
+
+    <placeholder name="ExtraMenu_1" />
+
     <menu name="HelpMenu" action="Help">
       <menuitem name="HelpContentsMenu" action="HelpContents"/>
       <menuitem name="HelpAboutMenu" action="HelpAbout"/>

Modified: trunk/data/mime/Makefile.am
==============================================================================
--- trunk/data/mime/Makefile.am	(original)
+++ trunk/data/mime/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -26,3 +26,4 @@
 
 EXTRA_DIST = $(icon_DATA) $(mime_DATA) $(keys_predata)
 
+CLEANFILES = $(keys_DATA)

Added: trunk/data/pixmaps/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/data/pixmaps/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,10 @@
+icondir = $(datadir)/pixmaps/gtranslator
+icon_DATA =	\
+	gtranslator-plugin.png \
+	gtranslator-fuzzy-next.png \
+	gtranslator-fuzzy-prev.png \
+	gtranslator-untranslated-next.png \
+	gtranslator-untranslated-prev.png 
+
+EXTRA_DIST = \
+		$(icon_DATA)

Added: trunk/data/pixmaps/gtranslator-fuzzy-next.png
==============================================================================
Binary files (empty file) and trunk/data/pixmaps/gtranslator-fuzzy-next.png	Tue Sep 16 07:58:13 2008 differ

Added: trunk/data/pixmaps/gtranslator-fuzzy-prev.png
==============================================================================
Binary files (empty file) and trunk/data/pixmaps/gtranslator-fuzzy-prev.png	Tue Sep 16 07:58:13 2008 differ

Copied: trunk/data/pixmaps/gtranslator-plugin.png (from r3579, /trunk/data/gtranslator-plugin.png)
==============================================================================
Binary files. No diff available.

Added: trunk/data/pixmaps/gtranslator-untranslated-next.png
==============================================================================
Binary files (empty file) and trunk/data/pixmaps/gtranslator-untranslated-next.png	Tue Sep 16 07:58:13 2008 differ

Added: trunk/data/pixmaps/gtranslator-untranslated-prev.png
==============================================================================
Binary files (empty file) and trunk/data/pixmaps/gtranslator-untranslated-prev.png	Tue Sep 16 07:58:13 2008 differ

Modified: trunk/data/po.lang
==============================================================================
--- trunk/data/po.lang	(original)
+++ trunk/data/po.lang	Tue Sep 16 07:58:13 2008
@@ -41,10 +41,13 @@
           <match>[&amp;_][a-zA-Z]</match>
         </context>
         <context style-ref="tag">
-	  <match>&lt;[0-9a-zA-Z=\"/\- ]+&gt;</match>
+	  <match>&lt;[0-9a-zA-Z=.:?\"/\- ]+&gt;</match>
 	</context>
         <context ref="python:format" style-ref="special-variable"/>
         <context ref="c:printf"/>
+        <context id="csharp" style-ref="c:printf">
+          <match>{[0-9][0-9:\#\%,./cdefgnrxtsuDTFGMY]*}</match>
+        </context>
       </include>
     </context>
   </definitions>

Modified: trunk/doc/reference/Makefile.am
==============================================================================
--- trunk/doc/reference/Makefile.am	(original)
+++ trunk/doc/reference/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -37,11 +37,13 @@
 # Used for dependencies. The docs will be rebuilt if any of these change.
 HFILE_GLOB= 					\
 	$(top_srcdir)/src/*.h			\
-	$(top_srcdir)/src/plugin-system/*.h	
+	$(top_srcdir)/src/plugin-system/*.h	\
+	$(top_srcdir)/src/translation-memory/*.h
 	
 CFILE_GLOB=					\
 	$(top_srcdir)/src/*.c			\
-	$(top_srcdir)/src/plugin-system/*.c	
+	$(top_srcdir)/src/plugin-system/*.c	\
+	$(top_srcdir)/src/translation-memory/*.c
 
 # Header files to ignore when scanning (These are internal to gedit).
 IGNORE_HFILES=			\
@@ -61,7 +63,7 @@
 
 # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
 # e.g. content_files=running.sgml building.sgml changes-2.0.sgml
-content_files=
+content_files=version.xml
 
 # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
 # These files must be listed here *and* in content_files
@@ -75,13 +77,14 @@
 	-I$(top_srcdir)/src			\
 	-I$(top_srcdir)/src/plugin-system	\
 	-I$(top_srcdir)/src/toolbareditor	\
+	-I$(top_srcdir)/src/translation-memory	\
 	-I$(top_builddir)/src			\
 	-I$(top_srcdir)				\
 	-I$(top_builddir)			\
 	$(GTRANSLATOR_CFLAGS)
 
 GTKDOC_LIBS=	\
-	$(top_srcdir)/src/libgtranslator.la	\
+	$(top_builddir)/src/libgtranslator.la	\
 	$(GTRANSLATOR_LIBS)
 
 # This includes the standard gtk-doc make rules, copied by gtkdocize.
@@ -89,3 +92,4 @@
 
 # Other files to distribute
 # e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST += version.xml.in

Modified: trunk/doc/reference/gtranslator-docs.sgml
==============================================================================
--- trunk/doc/reference/gtranslator-docs.sgml	(original)
+++ trunk/doc/reference/gtranslator-docs.sgml	Tue Sep 16 07:58:13 2008
@@ -12,7 +12,8 @@
   <chapter>
     <title>API reference</title>
     <xi:include href="xml/application.xml"/>
-    <xi:include href="xml/comment.xml"/>
+    <xi:include href="xml/context.xml"/>
+    <xi:include href="xml/debug.xml"/>
     <xi:include href="xml/header.xml"/>
     <xi:include href="xml/history-entry.xml"/>
     <xi:include href="xml/io-error-message-area.xml"/>
@@ -24,6 +25,8 @@
     <xi:include href="xml/po.xml"/>
     <xi:include href="xml/statusbar.xml"/>
     <xi:include href="xml/tab.xml"/>
+    <xi:include href="xml/translation-memory.xml"/>
+    <xi:include href="xml/translation-memory-ui.xml"/>
     <xi:include href="xml/utils.xml"/>
     <xi:include href="xml/view.xml"/>
     <xi:include href="xml/window.xml"/>

Modified: trunk/doc/reference/gtranslator.types
==============================================================================
--- trunk/doc/reference/gtranslator.types	(original)
+++ trunk/doc/reference/gtranslator.types	Tue Sep 16 07:58:13 2008
@@ -1,6 +1,7 @@
 
 #include "application.h"
-#include "comment.h"
+#include "context.h"
+#include "debug.h"
 #include "header.h"
 #include "history-entry.h"
 #include "io-error-message-area.h"
@@ -12,6 +13,8 @@
 #include "po.h"
 #include "statusbar.h"
 #include "tab.h"
+#include "translation-memory.h"
+#include "translation-memory-ui.h"
 #include "utils.h"
 #include "view.h"
 #include "window.h"

Modified: trunk/help/C/gtranslator.xml
==============================================================================
--- trunk/help/C/gtranslator.xml	(original)
+++ trunk/help/C/gtranslator.xml	Tue Sep 16 07:58:13 2008
@@ -25,7 +25,7 @@
     </copyright>
     -->
 
-    <publisher>
+    <publisher role="maintainer">
 	    <publishername>GNOME Documentation Project</publishername>
     </publisher>
 
@@ -76,6 +76,10 @@
 	    </revision>
     </revhistory>
 
+    <abstract role="description">
+      <para>&app; is an enhanced gettext po file editor for the GNOME desktop environment.</para>
+    </abstract>
+
   </articleinfo>
   
 <!-- ================ Document Body ================= -->
@@ -1356,91 +1360,91 @@
   </sect1>
 
 
-  <sect1 id="gtranslator-glossary">
-    <title>Glossary</title>
-    <para>
-      <variablelist>
-        <varlistentry>
-          <term>
-            <command>gettext</command>
-          </term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>po file</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>internationalization</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>localization</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>l10n</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>i18n</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>translation memory</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>ISO 3166 coutry code</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>ISO 639-2 language code</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>default query domain</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>charset</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>encoding</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term>URI</term>
-          <listitem>
-            <para></para>
-          </listitem>
-        </varlistentry>
-      </variablelist>
-    </para>
-  </sect1>
+<!--   <sect1 id="gtranslator-glossary"> -->
+<!--     <title>Glossary</title> -->
+<!--     <para> -->
+<!--       <variablelist> -->
+<!--         <varlistentry> -->
+<!--           <term> -->
+<!--             <command>gettext</command> -->
+<!--           </term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>po file</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>internationalization</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>localization</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>l10n</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>i18n</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>translation memory</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>ISO 3166 coutry code</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>ISO 639-2 language code</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>default query domain</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>charset</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>encoding</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--         <varlistentry> -->
+<!--           <term>URI</term> -->
+<!--           <listitem> -->
+<!--             <para></para> -->
+<!--           </listitem> -->
+<!--         </varlistentry> -->
+<!--       </variablelist> -->
+<!--     </para> -->
+<!--   </sect1> -->
 </article>

Modified: trunk/help/Makefile.am
==============================================================================
--- trunk/help/Makefile.am	(original)
+++ trunk/help/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -1,7 +1,10 @@
-##
-## Add eventually existing other languages docs to here.
-##
+include $(top_srcdir)/gnome-doc-utils.make
+dist-hook: doc-dist-hook
 
-SUBDIRS = C
-# ja
-EXTRA_DIST = ChangeLog
+DOC_MODULE = gtranslator
+DOC_ENTITIES = legal.xml
+DOC_INCLUDES =
+DOC_FIGURES = figures/mainwindow.png \
+	      figures/prefs.png	\
+	      figures/toolbar.png
+DOC_LINGUAS =

Added: trunk/help/gtranslator.omf.in
==============================================================================
--- (empty file)
+++ trunk/help/gtranslator.omf.in	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,9 @@
+<?xml version="1.0" standalone="no"?>
+<omf>
+  <resource>
+    <subject category="GNOME|Applications|Programming"/>
+    <type>user's guide</type>	
+    <relation seriesid="eeee6e22-dab0-11d7-9ad8-af333333986d"/>
+    <rights type="GNU FDL" license.version="1.1" holder="Sun Microsystems"/>
+  </resource>
+</omf>

Added: trunk/m4/berkeley_db.m4
==============================================================================
--- (empty file)
+++ trunk/m4/berkeley_db.m4	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,94 @@
+dnl
+dnl @synopsis AX_BERKELEY_DB([MINIMUM-VERSION
+dnl                          [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl
+dnl This macro tries to find Berkeley DB. It honors MINIMUM-VERSION if given.
+dnl 
+dnl If libdb is found, DB_HEADER and DB_LIBS variables are set and 
+dnl ACTION-IF-FOUND shell code is executed if specified. DB_HEADER is set to 
+dnl location of db.h header in quotes (e.g. "db3/db.h") and AC_DEFINE_UNQUOTED
+dnl is called on it, so that you can type 
+dnl      #include DB_HEADER
+dnl in your C/C++ code. DB_LIBS is set to linker flags needed to link against
+dnl the library (e.g. -ldb3.1) and AC_SUBST is called on it.
+dnl
+dnl @version $Id: berkeley_db.m4 935 2005-07-04 20:53:00Z vaclavslavik $
+dnl @author Vaclav Slavik <vslavik fastmail fm>
+dnl
+AC_DEFUN([AX_BERKELEY_DB],
+[
+  old_LIBS="$LIBS"
+
+  minversion=ifelse([$1], ,,$1)
+                
+  DB_HEADER=""
+  DB_LIBS=""
+
+  if test -z $minversion ; then
+      minvermajor=0
+      minverminor=0
+      minverpatch=0
+      AC_MSG_CHECKING([for Berkeley DB])
+  else
+      minvermajor=`echo $minversion | cut -d. -f1`
+      minverminor=`echo $minversion | cut -d. -f2`
+      minverpatch=`echo $minversion | cut -d. -f3`
+      minvermajor=${minvermajor:-0}
+      minverminor=${minverminor:-0}
+      minverpatch=${minverpatch:-0}
+      AC_MSG_CHECKING([for Berkeley DB >= $minversion])
+  fi
+
+  for version in "" 5.0 4.9 4.8 4.7 4.6 4.5 4.4 4.3 4.2 4.1 4.0 3.6 3.5 3.4 3.3 3.2 3.1 ; do
+
+    if test -z $version ; then
+        db_lib="-ldb"
+        try_headers="db.h"
+    else
+        db_lib="-ldb-$version"
+        try_headers="db$version/db.h db`echo $version | sed -e 's,\..*,,g'`/db.h"
+    fi
+        
+    LIBS="$old_LIBS $db_lib"
+ 
+    for db_hdr in $try_headers ; do
+        if test -z $DB_HEADER ; then
+            AC_LINK_IFELSE(
+                [AC_LANG_PROGRAM(
+                    [
+                        #include <${db_hdr}>
+                    ],
+                    [
+                        #if !((DB_VERSION_MAJOR > (${minvermajor}) || \
+                              (DB_VERSION_MAJOR == (${minvermajor}) && \
+                                    DB_VERSION_MINOR > (${minverminor})) || \
+                              (DB_VERSION_MAJOR == (${minvermajor}) && \
+                                    DB_VERSION_MINOR == (${minverminor}) && \
+                                    DB_VERSION_PATCH >= (${minverpatch}))))
+                            #error "too old version"
+                        #endif
+                    
+                        DB *db;
+                        db_create(&db, NULL, 0);
+                    ])],
+                [
+                    AC_MSG_RESULT([header $db_hdr, library $db_lib])
+                                
+                    DB_HEADER="$db_hdr"
+                    DB_LIBS="$db_lib"
+                ])
+        fi
+    done
+  done
+
+  LIBS="$old_LIBS"
+
+  if test -z $DB_HEADER ; then
+    AC_MSG_RESULT([not found])
+    ifelse([$3], , :, [$3])
+  else
+    AC_DEFINE_UNQUOTED(DB_HEADER, ["$DB_HEADER"], [Berkeley DB header version])
+    AC_SUBST(DB_LIBS)
+    ifelse([$2], , :, [$2])
+  fi
+])

Added: trunk/m4/gtk-doc.m4
==============================================================================
--- (empty file)
+++ trunk/m4/gtk-doc.m4	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,39 @@
+dnl -*- mode: autoconf -*-
+
+# serial 1
+
+dnl Usage:
+dnl   GTK_DOC_CHECK([minimum-gtk-doc-version])
+AC_DEFUN([GTK_DOC_CHECK],
+[
+  AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
+  AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
+  dnl for overriding the documentation installation directory
+  AC_ARG_WITH([html-dir],
+    AS_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),,
+    [with_html_dir='${datadir}/gtk-doc/html'])
+  HTML_DIR="$with_html_dir"
+  AC_SUBST([HTML_DIR])
+
+  dnl enable/disable documentation building
+  AC_ARG_ENABLE([gtk-doc],
+    AS_HELP_STRING([--enable-gtk-doc],
+                   [use gtk-doc to build documentation [[default=no]]]),,
+    [enable_gtk_doc=no])
+
+  if test x$enable_gtk_doc = xyes; then
+    ifelse([$1],[],
+      [PKG_CHECK_EXISTS([gtk-doc],,
+                        AC_MSG_ERROR([gtk-doc not installed and --enable-gtk-doc requested]))],
+      [PKG_CHECK_EXISTS([gtk-doc >= $1],,
+                        AC_MSG_ERROR([You need to have gtk-doc >= $1 installed to build gtk-doc]))])
+  fi
+
+  AC_MSG_CHECKING([whether to build gtk-doc documentation])
+  AC_MSG_RESULT($enable_gtk_doc)
+
+  AC_PATH_PROGS(GTKDOC_CHECK,gtkdoc-check,)
+
+  AM_CONDITIONAL([ENABLE_GTK_DOC], [test x$enable_gtk_doc = xyes])
+  AM_CONDITIONAL([GTK_DOC_USE_LIBTOOL], [test -n "$LIBTOOL"])
+])

Modified: trunk/plugins/Makefile.am
==============================================================================
--- trunk/plugins/Makefile.am	(original)
+++ trunk/plugins/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -1,7 +1,8 @@
 SUBDIRS = 					\
 	alternate-language			\
 	fullscreen				\
-	insert-tags
+	insert-tags				\
+	source-code-view
 
 if USE_CHARMAP
 SUBDIRS += charmap
@@ -14,3 +15,7 @@
 if USE_DICTIONARY
 SUBDIRS += dictionary
 endif
+
+if BUILD_SVN
+SUBDIRS += subversion
+endif

Modified: trunk/plugins/alternate-language/alternate-language-panel.c
==============================================================================
--- trunk/plugins/alternate-language/alternate-language-panel.c	(original)
+++ trunk/plugins/alternate-language/alternate-language-panel.c	Tue Sep 16 07:58:13 2008
@@ -33,6 +33,9 @@
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
+#define FUZZY_ICON		"gtk-dialog-warning"
+#define UNTRANSLATED_ICON	"gtk-dialog-error"
+
 #define GTR_ALTERNATE_LANG_PANEL_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
 						 (object),		       \
 						 GTR_TYPE_ALTERNATE_LANG_PANEL,     \
@@ -47,12 +50,11 @@
 	GtkWidget *close_button;
 	GtkWidget *textview;
 	
-	GtkWidget *translated;
-	GtkWidget *untranslated;
-	GtkWidget *fuzzy;
+	GtkWidget *status;
 	
 	GtranslatorPo *po;
 	GtranslatorMsg *first;
+	GtranslatorTab *tab;
 };
 
 static void
@@ -73,15 +75,19 @@
 	GList *messages;
 	GList *l;
 	const gchar *msgid = gtranslator_msg_get_msgid (msg);
+	gchar *msgid_collate;
 	const gchar *string;
+	gchar *string_collate;
 	GtranslatorMsgStatus status;
 	
+	msgid_collate = g_utf8_collate_key (msgid, -1);
 	messages = gtranslator_po_get_messages (panel->priv->po);
 	l = messages;
 	do
 	{
 		string = gtranslator_msg_get_msgid (l->data);
-		if (g_utf8_collate(string, msgid) == 0)
+		string_collate = g_utf8_collate_key (string, -1);
+		if (strcmp (string_collate, msgid_collate) == 0)
 		{
 			gtranslator_alternate_lang_panel_set_text (panel,
 								   gtranslator_msg_get_msgstr (l->data));
@@ -89,28 +95,33 @@
 			switch (status)
 			{
 				case GTR_MSG_STATUS_TRANSLATED: 
-					gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->priv->translated),
-								      TRUE);
+					gtk_image_clear (GTK_IMAGE (panel->priv->status));
 					break;
 				case GTR_MSG_STATUS_FUZZY:
-					gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->priv->fuzzy),
-								      TRUE);
+					gtk_image_set_from_stock (GTK_IMAGE (panel->priv->status),
+								  FUZZY_ICON,
+								  GTK_ICON_SIZE_SMALL_TOOLBAR);
 					break;
 				default: break;
 			}
 			
+			g_free (string_collate);
+			g_free (msgid_collate);
 			return;
 		}
+		g_free (string_collate);
 	} while ((l = g_list_next (l)));
 	
+	g_free (msgid_collate);
 	gtranslator_alternate_lang_panel_set_text (panel,
 						   _("Message not found"));
 	
 	/*
 	 * If we are here the status is untranslated
 	 */
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->priv->untranslated),
-				      TRUE);
+	gtk_image_set_from_stock (GTK_IMAGE (panel->priv->status),
+				  UNTRANSLATED_ICON,
+				  GTK_ICON_SIZE_SMALL_TOOLBAR);
 }
 
 static void
@@ -131,11 +142,16 @@
 	   GtranslatorAlternateLangPanel *panel)
 {
 	GError *error = NULL;
-	gchar *po_file = g_strdup (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)));
-		  
+	GFile *file;
+	gchar *po_file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+	
+	file = g_file_new_for_path (po_file);
+	g_free (po_file);
 		  
 	panel->priv->po = gtranslator_po_new ();
-	gtranslator_po_parse (panel->priv->po, po_file, &error);
+	gtranslator_po_parse (panel->priv->po, file, &error);
+	
+	g_object_unref (file);
 	
 	if (error != NULL)
 	{
@@ -189,6 +205,9 @@
 			GtranslatorAlternateLangPanel *panel)
 {
 	GtkWidget *dialog = NULL;
+	gchar *dir;
+	GtranslatorPo *tab_po;
+	GFile *location, *parent;
 			       
 	if(dialog != NULL) {
 		gtk_window_present(GTK_WINDOW(dialog));
@@ -200,7 +219,19 @@
 	 */
 	dialog = gtranslator_file_chooser_new (NULL, 
 					       FILESEL_OPEN,
-					       _("Open file for alternate language"));
+					       _("Open file for alternate language"),
+					       NULL);
+	
+	tab_po = gtranslator_tab_get_po (panel->priv->tab);
+	location = gtranslator_po_get_location (tab_po);
+	parent = g_file_get_parent (location);
+	g_object_unref (location);
+	
+	dir = g_file_get_path (parent);
+	g_object_unref (parent);
+	
+	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dir);
+	g_free (dir);
 			       
 	gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
 	
@@ -270,20 +301,10 @@
 	/*
 	 * Radio buttons
 	 */
-	panel->priv->translated = gtk_radio_button_new_with_label (NULL,
-								   _("Translated"));
-	gtk_widget_show (panel->priv->translated);
-	gtk_box_pack_start (GTK_BOX (hbox), panel->priv->translated, FALSE, TRUE, 0);
-	
-	panel->priv->fuzzy = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (panel->priv->translated),
-									  _("Fuzzy"));
-	gtk_widget_show (panel->priv->fuzzy);
-	gtk_box_pack_start (GTK_BOX (hbox), panel->priv->fuzzy, FALSE, TRUE, 0);
-	
-	panel->priv->untranslated = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (panel->priv->translated),
-										 _("Untranslated"));
-	gtk_widget_show (panel->priv->untranslated);
-	gtk_box_pack_start (GTK_BOX (hbox), panel->priv->untranslated, FALSE, TRUE, 0);
+	panel->priv->status = gtk_image_new ();
+	gtk_widget_show (panel->priv->status);
+	
+	gtk_box_pack_start (GTK_BOX (hbox), panel->priv->status, FALSE, FALSE, 0);
 	
 	/*
 	 * Text view
@@ -300,8 +321,11 @@
 	gtk_widget_set_sensitive (panel->priv->textview, FALSE);
 	gtk_widget_show (panel->priv->textview);
 	
-	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll),
-					       panel->priv->textview);
+	gtk_container_add (GTK_CONTAINER (scroll),
+			   panel->priv->textview);
+	
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
+					     GTK_SHADOW_IN);
 	
 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
 					GTK_POLICY_AUTOMATIC,
@@ -345,6 +369,8 @@
 	GtranslatorAlternateLangPanel *panel;
 	panel = g_object_new (GTR_TYPE_ALTERNATE_LANG_PANEL, NULL);
 	
+	panel->priv->tab = GTR_TAB (tab);
+	
 	g_signal_connect (tab, "showed-message",
 			  G_CALLBACK (showed_message_cb),
 			  panel);

Modified: trunk/plugins/alternate-language/alternate-language-plugin.c
==============================================================================
--- trunk/plugins/alternate-language/alternate-language-plugin.c	(original)
+++ trunk/plugins/alternate-language/alternate-language-plugin.c	Tue Sep 16 07:58:13 2008
@@ -28,6 +28,8 @@
 #include <glib/gi18n-lib.h>
 
 #define WINDOW_DATA_KEY	"GtranslatorAlternateLangPluginWindowData"
+#define TAB_DATA_KEY    "GtranslatorAlternateLangPluginTabData"
+#define MENU_PATH "/MainMenu/ViewMenu/ViewOps_2"
 
 #define GTR_MESSAGE_TABLE_GET_PRIVATE(object) \
 				(G_TYPE_INSTANCE_GET_PRIVATE ((object),	\
@@ -35,9 +37,58 @@
 				GtranslatorAlternateLangPluginPrivate))
 
 GTR_PLUGIN_REGISTER_TYPE_WITH_CODE (GtranslatorAlternateLangPlugin, gtranslator_alternate_lang_plugin,
-		gtranslator_alternate_lang_panel_register_type (module);
+				    gtranslator_alternate_lang_panel_register_type (module);
 )
 
+static void
+on_alternate_lang_activated (GtkAction *action,
+			     GtranslatorWindow *window)
+{
+	GtranslatorTab *tab;
+	GtkWidget *alternatelang;
+	
+	tab = gtranslator_window_get_active_tab (window);
+	alternatelang = g_object_get_data (G_OBJECT (tab), TAB_DATA_KEY);
+	
+	gtranslator_tab_show_lateral_panel_widget (GTR_TAB (tab),
+						   alternatelang);
+}
+
+static const GtkActionEntry action_entries[] =
+{
+	{ "AlternateLang", NULL, N_("_Alternate Language"), "<control>L",
+	 N_("Show the Alternate Language panel"),
+	 G_CALLBACK (on_alternate_lang_activated)}, 
+};
+
+typedef struct
+{
+	GtkActionGroup *action_group;
+	guint           ui_id;
+} WindowData;
+
+static void
+free_window_data (WindowData *data)
+{
+	g_return_if_fail (data != NULL);
+
+	g_free (data);
+}
+
+static void
+update_ui_real (GtranslatorWindow *window,
+		WindowData   *data)
+{
+	GtranslatorTab *tab;
+	GtkAction *action;
+
+	tab = gtranslator_window_get_active_tab (window);
+
+	action = gtk_action_group_get_action (data->action_group,
+					      "AlternateLang");
+	gtk_action_set_sensitive (action,
+				  (tab != NULL));
+}
 
 static void
 gtranslator_alternate_lang_plugin_init (GtranslatorAlternateLangPlugin *message_table)
@@ -59,8 +110,6 @@
 {
 	GtkWidget *alternatelang;
 	GtranslatorPo *po;
-	GtkWidget *panel;
-	GtkWidget *label;
 	
 	po = gtranslator_tab_get_po (GTR_TAB (child));
 	
@@ -69,17 +118,13 @@
 	alternatelang = gtranslator_alternate_lang_panel_new (child);
 	gtk_widget_show (alternatelang);
 	
-	panel = gtranslator_tab_get_panel (GTR_TAB(child));
+	gtranslator_tab_add_widget_to_lateral_panel (GTR_TAB(child),
+						     alternatelang,
+						     _("Alternate Language"));
 	
-	label = gtk_label_new (_("Alternate Language"));
-	
-	gtk_notebook_append_page (GTK_NOTEBOOK (panel),
-				  alternatelang,
-				  label);
-
 	g_object_set_data (G_OBJECT (child),
-			   WINDOW_DATA_KEY,
-			   alternatelang);
+			   TAB_DATA_KEY,
+			   alternatelang);	
 }
 
 static void
@@ -88,6 +133,37 @@
 {
 	GtranslatorNotebook *notebook;
 	GList *tabs = NULL;
+	GtkUIManager *manager;
+	WindowData *data;
+	
+	data = g_new (WindowData, 1);
+
+	manager = gtranslator_window_get_ui_manager (window);
+
+	data->action_group = gtk_action_group_new ("GtranslatorAlternateLangPluginActions");
+	gtk_action_group_set_translation_domain (data->action_group, 
+						 GETTEXT_PACKAGE);
+	gtk_action_group_add_actions (data->action_group,
+				      action_entries,
+				      G_N_ELEMENTS (action_entries), 
+				      window);
+
+	gtk_ui_manager_insert_action_group (manager, data->action_group, -1);
+
+	data->ui_id = gtk_ui_manager_new_merge_id (manager);
+
+	g_object_set_data_full (G_OBJECT (window), 
+				WINDOW_DATA_KEY, 
+				data,
+				(GDestroyNotify) free_window_data);
+	
+	gtk_ui_manager_add_ui (manager,
+			       data->ui_id,
+			       MENU_PATH,
+			       "AlternateLang",
+			       "AlternateLang",
+			       GTK_UI_MANAGER_MENUITEM,
+			       FALSE);
 	
 	notebook = gtranslator_window_get_notebook(window);
 	
@@ -104,40 +180,58 @@
 						   tabs->data,
 						   0, window);
 	}while((tabs = g_list_next(tabs)));
-
 }
 
 static void
 impl_deactivate(GtranslatorPlugin *plugin,
 	        GtranslatorWindow *window)
 {
-	GtkWidget *panel;
 	GtranslatorNotebook *notebook;
 	GtkWidget *alternatelang;
 	GList *tabs;
-	gint page_num;
+	GtkUIManager *manager;
+	WindowData *data;
 	
-	tabs = gtranslator_window_get_all_tabs(window);
-	notebook = gtranslator_window_get_notebook(window);
+	tabs = gtranslator_window_get_all_tabs (window);
+	notebook = gtranslator_window_get_notebook (window);
 
-	if(tabs == NULL)
-		return;
-	do{
-		alternatelang = g_object_get_data(G_OBJECT(tabs->data), WINDOW_DATA_KEY);
-		panel = gtranslator_tab_get_panel (GTR_TAB(tabs->data));
-		
-		page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel),
-						  alternatelang);
-		gtk_notebook_remove_page (GTK_NOTEBOOK (panel),
-					  page_num);
+	if (tabs != NULL)
+	{
+		do{
+			alternatelang = g_object_get_data (G_OBJECT (tabs->data), TAB_DATA_KEY);
+			gtranslator_tab_remove_widget_from_lateral_panel (GTR_TAB (tabs->data),
+									  alternatelang);
 
-		g_object_set_data (G_OBJECT (tabs->data), WINDOW_DATA_KEY, NULL);
-		
-	}while((tabs = g_list_next(tabs)));
+			g_object_set_data (G_OBJECT (tabs->data), WINDOW_DATA_KEY, NULL);
+		}while ((tabs = g_list_next (tabs)));
+	}
+	
+	g_signal_handlers_disconnect_by_func (notebook,
+					      create_alternate_lang_plugin_panel,
+					      window);
+	
+	/* Remove menuitem */
+	manager = gtranslator_window_get_ui_manager (window);
 	
-	g_signal_handlers_disconnect_by_func(notebook,
-					     create_alternate_lang_plugin_panel,
-					     window);
+	data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
+	g_return_if_fail (data != NULL);
+
+	gtk_ui_manager_remove_ui (manager, data->ui_id);
+	gtk_ui_manager_remove_action_group (manager, data->action_group);
+
+	g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL);	
+}
+
+static void
+impl_update_ui (GtranslatorPlugin *plugin,
+		GtranslatorWindow *window)
+{
+	WindowData *data;
+
+	data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
+	g_return_if_fail (data != NULL);
+
+	update_ui_real (window, data);
 }
 
 static void
@@ -150,4 +244,5 @@
 
 	plugin_class->activate = impl_activate;
 	plugin_class->deactivate = impl_deactivate;
+	plugin_class->update_ui = impl_update_ui;
 }

Modified: trunk/plugins/charmap/Makefile.am
==============================================================================
--- trunk/plugins/charmap/Makefile.am	(original)
+++ trunk/plugins/charmap/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -37,7 +37,7 @@
 
 plugin_DATA = $(plugin_in_files:.gtranslator-plugin.desktop.in=.gtranslator.plugin)
 
-EXTRA_DIST = $(plugin_in_files)
+EXTRA_DIST = $(pixmaps__DATA) $(plugin_in_files)
 
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)

Modified: trunk/plugins/charmap/charmap-plugin.c
==============================================================================
--- trunk/plugins/charmap/charmap-plugin.c	(original)
+++ trunk/plugins/charmap/charmap-plugin.c	Tue Sep 16 07:58:13 2008
@@ -27,6 +27,7 @@
 
 #include <glib/gi18n-lib.h>
 #include "application.h"
+#include "statusbar.h"
 #include "window.h"
 #include <gucharmap/gucharmap-table.h>
 #include <gucharmap/gucharmap-unicode-info.h>
@@ -75,18 +76,18 @@
 			 const gchar    *message,
 			 GtranslatorWindow    *window)
 {
-	GtkStatusbar *statusbar;
+	GtranslatorStatusbar *statusbar;
 	WindowData *data;
 
-	statusbar = GTK_STATUSBAR (gtranslator_window_get_statusbar (window));
+	statusbar = GTR_STATUSBAR (gtranslator_window_get_statusbar (window));
 	data = (WindowData *) g_object_get_data (G_OBJECT (window),
 						 WINDOW_DATA_KEY);
 	g_return_if_fail (data != NULL);
 
-	gtk_statusbar_pop (statusbar, data->context_id);
+	gtranslator_statusbar_pop (statusbar, data->context_id);
 
 	if (message)
-		gtk_statusbar_push (statusbar, data->context_id, message);
+		gtranslator_statusbar_push (statusbar, data->context_id, message);
 }
 
 static void
@@ -217,24 +218,13 @@
 impl_activate (GtranslatorPlugin *plugin,
 	       GtranslatorWindow *window)
 {
-	/*GtkWidget *image;
-	GtkIconTheme *theme;*/
-	GtkStatusbar *statusbar;
+	GtranslatorStatusbar *statusbar;
 	WindowData *data;
 
 	//gtranslator_debug (DEBUG_PLUGINS);
 
 	data = g_new (WindowData, 1);
 
-	/*theme = gtk_icon_theme_get_default ();
-	
-	if (gtk_icon_theme_has_icon (theme, "accessories-character-map"))
-		image = gtk_image_new_from_icon_name ("accessories-character-map",
-						      GTK_ICON_SIZE_MENU);
-	else
-		image = gtk_image_new_from_icon_name ("gucharmap",
-						      GTK_ICON_SIZE_MENU);*/
-
 	gtranslator_application_register_icon (GTR_APP, "gucharmap.ico",
 					       "charmap-plugin-icon");
 	
@@ -247,11 +237,9 @@
 				       "charmap-plugin-icon",
 				       GTR_WINDOW_PLACEMENT_LEFT);
 
-	//gtk_object_sink (GTK_OBJECT (image));
-
-	statusbar = GTK_STATUSBAR (gtranslator_window_get_statusbar (window));
-	data->context_id = gtk_statusbar_get_context_id (statusbar,
-							 "Character Description");
+	statusbar = GTR_STATUSBAR (gtranslator_window_get_statusbar (window));
+	data->context_id = gtranslator_statusbar_get_context_id (statusbar,
+								 "Character Description");
 
 	g_object_set_data_full (G_OBJECT (window),
 				WINDOW_DATA_KEY,

Modified: trunk/plugins/dictionary/Makefile.am
==============================================================================
--- trunk/plugins/dictionary/Makefile.am	(original)
+++ trunk/plugins/dictionary/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -28,6 +28,11 @@
 	$(GTRANSLATOR_LIBS)					\
 	$(DICTIONARY_LIBS)
 
+pixmaps_dir = $(datadir)/pixmaps/gtranslator
+pixmaps__DATA = \
+        gnome-dictionary.png
+
+
 # Plugin Info
 
 plugin_in_files = dict.gtranslator-plugin.desktop.in
@@ -36,7 +41,7 @@
 
 plugin_DATA = $(plugin_in_files:.gtranslator-plugin.desktop.in=.gtranslator.plugin)
 
-EXTRA_DIST = $(plugin_in_files)
+EXTRA_DIST = $(pixmaps__DATA) $(plugin_in_files)
 
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)

Modified: trunk/plugins/dictionary/dict-panel.c
==============================================================================
--- trunk/plugins/dictionary/dict-panel.c	(original)
+++ trunk/plugins/dictionary/dict-panel.c	Tue Sep 16 07:58:13 2008
@@ -22,6 +22,9 @@
 #include "dict-panel.h"
 #include "gdict-sidebar.h"
 #include "plugin.h"
+#include "window.h"
+#include "statusbar.h"
+#include "utils.h"
 
 #include <glib.h>
 #include <glib-object.h>
@@ -36,24 +39,25 @@
 						 GTR_TYPE_DICT_PANEL,     \
 						 GtranslatorDictPanelPrivate))
 
-#define GDICT_GCONF_DIR                     "/apps/gnome-dictionary"
-#define GDICT_GCONF_DATABASE_KEY            GDICT_GCONF_DIR "/database"
-#define GDICT_GCONF_STRATEGY_KEY            GDICT_GCONF_DIR "/strategy"
-#define GDICT_DEFAULT_SOURCE_NAME           "Default"
-#define GDICT_GCONF_SOURCE_KEY              GDICT_GCONF_DIR "/source-name"
-
-#define PANEL_KEY "/apps/gtranslator/plugins/dictionary"
+#define DICTIONARY_GCONF_DIR                     "/apps/gtranslator/plugins/dictionary"
+#define DICTIONARY_GCONF_DATABASE_KEY            DICTIONARY_GCONF_DIR "/database"
+#define DICTIONARY_GCONF_STRATEGY_KEY            DICTIONARY_GCONF_DIR "/strategy"
+#define DICTIONARY_DEFAULT_SOURCE_NAME           "Default"
+#define DICTIONARY_GCONF_SOURCE_KEY              DICTIONARY_GCONF_DIR "/source-name"
+#define DICTIONARY_GCONF_POSITION_KEY            DICTIONARY_GCONF_DIR "/panel_position"
 
 /* sidebar pages logical ids */
 #define GDICT_SIDEBAR_SPELLER_PAGE      "speller"
 #define GDICT_SIDEBAR_DATABASES_PAGE    "db-chooser"
 #define GDICT_SIDEBAR_STRATEGIES_PAGE   "strat-chooser"
+#define GDICT_SIDEBAR_SOURCES_PAGE      "source-chooser"
 
 GTR_PLUGIN_DEFINE_TYPE(GtranslatorDictPanel, gtranslator_dict_panel, GTK_TYPE_VBOX)
 
 struct _GtranslatorDictPanelPrivate
 {
 	GtkPaned   *paned;
+	GtranslatorStatusbar *status;
   
 	GConfClient *gconf_client;
 	guint notify_id;
@@ -64,33 +68,39 @@
 
 	gchar *word;  
 	GdictContext *context;
-	guint lookup_start_id;
-	guint lookup_end_id;
-	guint error_id;
 
 	GdictSourceLoader *loader;
 
 	GtkWidget *speller;
 	GtkWidget *db_chooser;
 	GtkWidget *strat_chooser;
+	GtkWidget *source_chooser;
 	GtkWidget *entry;
 	GtkWidget *button;
 	GtkWidget *defbox;
 	GtkWidget *sidebar;
 };
 
-
-static gchar *
-gdict_get_data_dir (void)
+static void
+gtranslator_dict_panel_create_warning_dialog (const gchar *primary,
+					      const gchar *secondary)
 {
-	gchar *retval;
+	GtkWidget *dialog;
 	
-	retval = g_build_filename (g_get_home_dir (),
-				   ".gnome2",
-				   "gnome-dictionary",
-				   NULL);
-
-	return retval;
+	if (!primary)
+		return;
+	
+	dialog = gtk_message_dialog_new (NULL,
+					 GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_WARNING,
+					 GTK_BUTTONS_CLOSE,
+					 primary);
+	
+	if (secondary)
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+							  secondary);
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
 }
 
 static gchar *
@@ -134,7 +144,7 @@
 		priv->database = g_strdup (database);
 	else
 		priv->database = gdict_gconf_get_string_with_default (priv->gconf_client,
-								      GDICT_GCONF_DATABASE_KEY,
+								      DICTIONARY_GCONF_DATABASE_KEY,
 								      GDICT_DEFAULT_DATABASE);
 	if (priv->defbox)
 		gdict_defbox_set_database (GDICT_DEFBOX (priv->defbox),
@@ -153,7 +163,7 @@
 		priv->strategy = g_strdup (strategy);
 	else
 		priv->strategy = gdict_gconf_get_string_with_default (priv->gconf_client,
-								      GDICT_GCONF_STRATEGY_KEY,
+								      DICTIONARY_GCONF_STRATEGY_KEY,
 								      GDICT_DEFAULT_STRATEGY);
 }
 
@@ -165,7 +175,7 @@
 	GdictContext *retval;
 
 	if (!priv->source_name)
-		priv->source_name = g_strdup (GDICT_DEFAULT_SOURCE_NAME);
+		priv->source_name = g_strdup (DICTIONARY_DEFAULT_SOURCE_NAME);
 
 	source = gdict_source_loader_get_source (priv->loader,
 						 priv->source_name);
@@ -175,8 +185,9 @@
 		
 		detail = g_strdup_printf (_("No dictionary source available with name '%s'"),
 					  priv->source_name);
-
-		g_warning(_("Unable to find dictionary source"));
+		
+		gtranslator_dict_panel_create_warning_dialog (_("Unable to find dictionary source"),
+							      detail);
 		g_free (detail);
 
 		return NULL;
@@ -192,11 +203,9 @@
 
 		detail = g_strdup_printf (_("No context available for source '%s'"),
 					  gdict_source_get_description (source));
-      				
-      /*gdict_show_error_dialog (NULL,
-                               _("Unable to create a context"),
-                               detail);*/
-		g_warning(_("Unable to create a context"));
+		
+		gtranslator_dict_panel_create_warning_dialog (_("Unable to create a context"),
+							      detail);
 
 		g_free (detail);
 		g_object_unref (source);
@@ -216,15 +225,7 @@
 	GtranslatorDictPanelPrivate *priv = panel->priv;
 
 	if (priv->context)
-	{
-		g_signal_handler_disconnect (priv->context, priv->lookup_start_id);
-		g_signal_handler_disconnect (priv->context, priv->lookup_end_id);
-		g_signal_handler_disconnect (priv->context, priv->error_id);
-
-		priv->lookup_start_id = 0;
-		priv->lookup_end_id = 0;
-		priv->error_id = 0;
-		
+	{	
 		g_object_unref (priv->context);
 		priv->context = NULL;
 	}
@@ -232,20 +233,15 @@
 	if (priv->defbox)
 		gdict_defbox_set_context (GDICT_DEFBOX (priv->defbox), context);
 	
+	if (priv->db_chooser)
+		gdict_database_chooser_set_context (GDICT_DATABASE_CHOOSER (priv->db_chooser), context);
+	
+	if (priv->strat_chooser)
+		gdict_strategy_chooser_set_context (GDICT_STRATEGY_CHOOSER (priv->strat_chooser), context);
+	
 	if (!context)
 		return;
 	
-	/* attach our callbacks */
-	/* priv->lookup_start_id = g_signal_connect (context, "lookup-start",
-					    G_CALLBACK (gdict_applet_lookup_start_cb),
-					    panel);
-  priv->lookup_end_id   = g_signal_connect (context, "lookup-end",
-					    G_CALLBACK (gdict_applet_lookup_end_cb),
-					    panel);*/
-  /*priv->error_id        = g_signal_connect (context, "error",
-		  			    G_CALLBACK (gdict_applet_error_cb),
-					    panel);*/
-
 	priv->context = context;
 }
 
@@ -256,17 +252,46 @@
 	GtranslatorDictPanelPrivate *priv = panel->priv;
 	GdictContext *context;
 	
+	if (priv->source_name && source_name &&
+	    strcmp (priv->source_name, source_name) == 0)
+		return;
+	
 	g_free (priv->source_name);
 	
 	if (source_name)
 		priv->source_name = g_strdup (source_name);
 	else
 		priv->source_name = gdict_gconf_get_string_with_default (priv->gconf_client,
-									 GDICT_GCONF_SOURCE_KEY,
-									 GDICT_DEFAULT_SOURCE_NAME);
+									 DICTIONARY_GCONF_SOURCE_KEY,
+									 DICTIONARY_DEFAULT_SOURCE_NAME);
 
 	context = get_context_from_loader (panel);
 	gtranslator_dict_panel_set_context (panel, context);
+	
+	if (priv->source_chooser)
+		gdict_source_chooser_set_current_source (GDICT_SOURCE_CHOOSER (priv->source_chooser),
+							 priv->source_name);
+}
+
+static void
+source_activated_cb (GdictSourceChooser *chooser,
+                     const gchar        *source_name,
+                     GdictSource        *source,
+                     GtranslatorDictPanel *panel)
+{
+	g_signal_handlers_block_by_func (chooser, source_activated_cb, panel);
+	gtranslator_dict_panel_set_source_name (panel, source_name);
+	g_signal_handlers_unblock_by_func (chooser, source_activated_cb, panel);
+	
+	if (panel->priv->status)
+	{
+		gchar *message;
+		
+		message = g_strdup_printf (_("Dictionary source '%s' selected"),
+					   gdict_source_get_description (source));
+		gtranslator_statusbar_flash_message (panel->priv->status, 0, message);
+		g_free (message);
+	}
 }
 
 static void
@@ -275,17 +300,17 @@
                        const gchar          *strat_desc,
                        GtranslatorDictPanel *panel)
 {
-/*	GtranslatorDictPanelPrivate *priv = panel->priv;
+	GtranslatorDictPanelPrivate *priv = panel->priv;
 	gtranslator_dict_panel_set_strategy (panel, strat_name);
 
-  if (window->status)
-    {
-      gchar *message;
-
-      message = g_strdup_printf (_("Strategy `%s' selected"), strat_desc);
-      gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
-      g_free (message);
-    }*/
+	if (priv->status)
+	{
+		gchar *message;
+		
+		message = g_strdup_printf (_("Strategy '%s' selected"), strat_desc);
+		gtranslator_statusbar_flash_message (priv->status, 0, message);
+		g_free (message);
+	}
 }
 
 static void
@@ -294,17 +319,17 @@
 		       const gchar          *db_desc,
 		       GtranslatorDictPanel *panel)
 {
-/*	GtranslatorDictPanelPrivate *priv = panel->priv;
+	GtranslatorDictPanelPrivate *priv = panel->priv;
 	gtranslator_dict_panel_set_database (panel, db_name);
-
-  if (window->status)
-    {
-      gchar *message;
-
-      message = g_strdup_printf (_("Database `%s' selected"), db_desc);
-      gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
-      g_free (message);
-    }*/
+	
+	if (priv->status)
+	{
+		gchar *message;
+		
+		message = g_strdup_printf (_("Database '%s' selected"), db_desc);
+		gtranslator_statusbar_flash_message (priv->status, 0, message);
+		g_free (message);
+	}
 }
 
 static void
@@ -342,19 +367,17 @@
 	gtk_entry_set_text (GTK_ENTRY (priv->entry), word);
 	
 	gtranslator_dict_panel_set_word (panel, word, db_name);
-	/*
-  if (window->status)
-    {
-      gchar *message;
-
-      message = g_strdup_printf (_("Word `%s' selected"), word);
-      gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
-      g_free (message);
-    }*/
+	
+	if (priv->status)
+	{
+		gchar *message;
+		
+		message = g_strdup_printf (_("Word '%s' selected"), word);
+		gtranslator_statusbar_flash_message (priv->status, 0, message);
+		g_free (message);
+	}
 }
 
-
-
 static void
 sidebar_page_changed_cb (GdictSidebar *sidebar,
 			 GtranslatorDictPanel *panel)
@@ -364,7 +387,7 @@
 	const gchar *message;
 	
 	page_id = gdict_sidebar_current_page (sidebar);
-	
+
 	switch (page_id[0])
 	{
 		case 's':
@@ -382,6 +405,10 @@
 				
 					gdict_strategy_chooser_refresh (GDICT_STRATEGY_CHOOSER (priv->strat_chooser));
 				break;
+				case 'o': /* source-chooser */
+					message = _("Double-click on the source to use");
+					gdict_source_chooser_refresh (GDICT_SOURCE_CHOOSER (priv->source_chooser));
+				break;
 				default:
 					message = NULL;
 			}
@@ -397,24 +424,24 @@
 		break;
 	}
 	
-	/*if (message && window->status)
-	gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);*/
+	if (message && priv->status)
+		gtranslator_statusbar_flash_message (priv->status, 0, message);
 }
 
 static void
-store_position(GObject    *gobject,
-               GParamSpec *arg1,
-               gpointer    user_data)
+store_position (GObject    *gobject,
+		GParamSpec *arg1,
+		gpointer    user_data)
 {
-	GtkPaned *paned = GTK_PANED(gobject);
+	GtkPaned *paned = GTK_PANED (gobject);
 	GConfClient *client;
 	gint position;
 	
-	client = gconf_client_get_default();
-	position = gtk_paned_get_position(paned);
-	gconf_client_set_int(client, PANEL_KEY "/panel_position", position, NULL);
+	client = gconf_client_get_default ();
+	position = gtk_paned_get_position (paned);
+	gconf_client_set_int (client, DICTIONARY_GCONF_POSITION_KEY, position, NULL);
 	
-	g_object_unref(client);
+	g_object_unref (client);
 }
 
 static void
@@ -438,6 +465,7 @@
 {
 	GtkWidget  *vbox;
 	GtkWidget  *hbox;
+	gint position;
 	
 	vbox = gtk_vbox_new (FALSE, 6);
 	gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
@@ -485,6 +513,9 @@
 	gtk_container_add (GTK_CONTAINER (vbox), panel->priv->defbox);
 	gtk_widget_show (panel->priv->defbox);
 	
+	/*
+	 * Sidebar
+	 */
 	panel->priv->sidebar = gdict_sidebar_new ();
 	g_signal_connect (panel->priv->sidebar, "page-changed",
 			  G_CALLBACK (sidebar_page_changed_cb),
@@ -499,8 +530,12 @@
 	gtk_paned_pack2 (panel->priv->paned, panel->priv->sidebar, TRUE, TRUE);
 	gtk_widget_show (GTK_WIDGET(panel->priv->paned));
 	
-	g_signal_connect(panel->priv->paned, "notify::position",
-			 G_CALLBACK(store_position), NULL);
+	position = gconf_client_get_int (panel->priv->gconf_client,
+					 DICTIONARY_GCONF_POSITION_KEY, NULL);
+	gtk_paned_set_position (GTK_PANED (panel->priv->paned), position);
+	
+	g_signal_connect (panel->priv->paned, "notify::position",
+			  G_CALLBACK(store_position), NULL);
 	
 	
 	/*
@@ -551,10 +586,19 @@
 				_("Available strategies"),
 				panel->priv->strat_chooser);
 	gtk_widget_show (panel->priv->strat_chooser);
-
-	gtk_widget_show (panel->priv->sidebar);
 	
+	/* Source chooser */
+	panel->priv->source_chooser = gdict_source_chooser_new_with_loader (panel->priv->loader);
+	g_signal_connect (panel->priv->source_chooser, "source-activated",
+			  G_CALLBACK (source_activated_cb),
+			  panel);
+	gdict_sidebar_add_page (GDICT_SIDEBAR (panel->priv->sidebar),
+				GDICT_SIDEBAR_SOURCES_PAGE,
+				_("Dictionary sources"),
+				panel->priv->source_chooser);
+	gtk_widget_show (panel->priv->source_chooser);
 	
+	gtk_widget_show (panel->priv->sidebar);
 }
 
 static void
@@ -565,21 +609,21 @@
 {
 	GtranslatorDictPanel *panel = GTR_DICT_PANEL (user_data);
 
-	if (strcmp (entry->key, GDICT_GCONF_SOURCE_KEY) == 0)
+	if (strcmp (entry->key, DICTIONARY_GCONF_SOURCE_KEY) == 0)
 	{
 		if (entry->value && (entry->value->type == GCONF_VALUE_STRING))
 			gtranslator_dict_panel_set_source_name (panel, gconf_value_get_string (entry->value));
 		else
-			gtranslator_dict_panel_set_source_name (panel, GDICT_DEFAULT_SOURCE_NAME);
+			gtranslator_dict_panel_set_source_name (panel, DICTIONARY_DEFAULT_SOURCE_NAME);
 	}
-	else if (strcmp (entry->key, GDICT_GCONF_DATABASE_KEY) == 0)
+	else if (strcmp (entry->key, DICTIONARY_GCONF_DATABASE_KEY) == 0)
 	{
 		if (entry->value && (entry->value->type == GCONF_VALUE_STRING))
 			gtranslator_dict_panel_set_database (panel, gconf_value_get_string (entry->value));
 		else
 			gtranslator_dict_panel_set_database (panel, GDICT_DEFAULT_DATABASE);
 	}
-	else if (strcmp (entry->key, GDICT_GCONF_STRATEGY_KEY) == 0)
+	else if (strcmp (entry->key, DICTIONARY_GCONF_STRATEGY_KEY) == 0)
 	{
 		if (entry->value && (entry->value->type == GCONF_VALUE_STRING))
 			gtranslator_dict_panel_set_strategy (panel, gconf_value_get_string (entry->value));
@@ -598,23 +642,23 @@
 	panel->priv = GTR_DICT_PANEL_GET_PRIVATE (panel);
 	priv = panel->priv;
 	
+	priv->status = NULL;
+	
 	if (!priv->loader)
 		panel->priv->loader = gdict_source_loader_new ();
 	
 	/* add our data dir inside $HOME to the loader's search paths */
-	data_dir = gdict_get_data_dir ();
+	data_dir = gtranslator_utils_get_user_config_dir ();
 	gdict_source_loader_add_search_path (priv->loader, data_dir);
 	g_free (data_dir);
 	
-	
-	
 	/* get the default gconf client */
 	if (!priv->gconf_client)
 		priv->gconf_client = gconf_client_get_default ();
 
 	gconf_error = NULL;
 	gconf_client_add_dir (priv->gconf_client,
-			      GDICT_GCONF_DIR,
+			      DICTIONARY_GCONF_DIR,
 			      GCONF_CLIENT_PRELOAD_ONELEVEL,
 			      &gconf_error);
 	if (gconf_error)
@@ -626,7 +670,7 @@
 	}
 	
 	priv->notify_id = gconf_client_notify_add (priv->gconf_client,
-						   GDICT_GCONF_DIR,
+						   DICTIONARY_GCONF_DIR,
 						   gtranslator_dict_panel_gconf_notify_cb,
 						   panel, NULL,
 						   &gconf_error);
@@ -671,15 +715,12 @@
 }
 
 GtkWidget *
-gtranslator_dict_panel_new (void)
-{
-	return GTK_WIDGET (g_object_new (GTR_TYPE_DICT_PANEL, NULL));
-}
-
-void
-gtranslator_dict_panel_set_position(GtranslatorDictPanel *panel,
-			      gint pos)
+gtranslator_dict_panel_new (GtranslatorWindow *window)
 {
-	gtk_paned_set_position(panel->priv->paned, pos);
-}
-
+	GtranslatorDictPanel *panel;
+	
+	panel = g_object_new (GTR_TYPE_DICT_PANEL, NULL);
+	panel->priv->status = GTR_STATUSBAR (gtranslator_window_get_statusbar (window));
+	
+	return GTK_WIDGET (panel);
+}
\ No newline at end of file

Modified: trunk/plugins/dictionary/dict-panel.h
==============================================================================
--- trunk/plugins/dictionary/dict-panel.h	(original)
+++ trunk/plugins/dictionary/dict-panel.h	Tue Sep 16 07:58:13 2008
@@ -22,6 +22,8 @@
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
+#include "window.h"
+
 G_BEGIN_DECLS
 
 /*
@@ -67,7 +69,7 @@
 
 GType		 gtranslator_dict_panel_register_type    (GTypeModule * module);
 
-GtkWidget *	 gtranslator_dict_panel_new 		   (void);
+GtkWidget *	 gtranslator_dict_panel_new 		   (GtranslatorWindow *window);
 
 void             gtranslator_dict_panel_set_position     (GtranslatorDictPanel *panel,
 						    gint pos);

Modified: trunk/plugins/dictionary/dict.gtranslator-plugin.desktop.in
==============================================================================
--- trunk/plugins/dictionary/dict.gtranslator-plugin.desktop.in	(original)
+++ trunk/plugins/dictionary/dict.gtranslator-plugin.desktop.in	Tue Sep 16 07:58:13 2008
@@ -3,7 +3,7 @@
 IAge=2
 _Name=Dictionary
 _Description=Look up words in a dictionary.
-Icon=gdict
+Icon=gnome-dictionary
 Authors=Ignacio Casal <nacho resa gmail com>
 Copyright=Copyright @ 2007 Ignacio Casal
 Website=http://gtranslator.sf.net

Modified: trunk/plugins/dictionary/dictionary-plugin.c
==============================================================================
--- trunk/plugins/dictionary/dictionary-plugin.c	(original)
+++ trunk/plugins/dictionary/dictionary-plugin.c	Tue Sep 16 07:58:13 2008
@@ -19,16 +19,14 @@
 #include <config.h>
 #endif
 
+#include "application.h"
 #include "dictionary-plugin.h"
 #include "dict-panel.h"
 #include "window.h"
 
 #include <glib/gi18n-lib.h>
-#include <gconf/gconf-client.h>
-//#include <gtranslator/gtranslator-debug.h>
 
 #define WINDOW_DATA_KEY	"GtranslatorDictPluginWindowData"
-#define PANEL_KEY "/apps/gtranslator/plugins/dictionary"
 
 #define GTR_DICT_PLUGIN_GET_PRIVATE(object) \
 				(G_TYPE_INSTANCE_GET_PRIVATE ((object),	\
@@ -42,20 +40,17 @@
 } WindowData;
 
 GTR_PLUGIN_REGISTER_TYPE_WITH_CODE (GtranslatorDictPlugin, gtranslator_dict_plugin,
-		gtranslator_dict_panel_register_type (module);
+				    gtranslator_dict_panel_register_type (module);
 )
 
 static void
 gtranslator_dict_plugin_init (GtranslatorDictPlugin *plugin)
 {
-	//gtranslator_debug_message (DEBUG_PLUGINS, "GtranslatorDictPlugin initializing");
 }
 
 static void
 gtranslator_dict_plugin_finalize (GObject *object)
 {
-	//gtranslator_debug_message (DEBUG_PLUGINS, "GtranslatorDictPlugin finalizing");
-
 	G_OBJECT_CLASS (gtranslator_dict_plugin_parent_class)->finalize (object);
 }
 
@@ -73,60 +68,33 @@
 {
 	GtkWidget      *panel;
 
-	panel = gtranslator_dict_panel_new ();
+	panel = gtranslator_dict_panel_new (window);
 
-	gtk_widget_show_all (panel);
+	gtk_widget_show (panel);
 
 	return panel;
 }
 
 static void
-restore_position(GtranslatorDictPanel *panel)
-{
-	GConfClient *client;
-	gint position;
-	
-	client = gconf_client_get_default();
-	position = gconf_client_get_int(client, PANEL_KEY "/panel_position", NULL);
-	gtranslator_dict_panel_set_position(panel, position);
-	
-	g_object_unref(client);
-}
-
-static void
 impl_activate (GtranslatorPlugin *plugin,
 	       GtranslatorWindow *window)
 {
-	/*GtkWidget *image;
-	GtkIconTheme *theme;*/
 	WindowData *data;
 
-	//gtranslator_debug (DEBUG_PLUGINS);
-
 	data = g_new (WindowData, 1);
-
-	/*theme = gtk_icon_theme_get_default ();
 	
-	if (gtk_icon_theme_has_icon (theme, "accessories-dictionary"))
-		image = gtk_image_new_from_icon_name ("accessories-dictionary",
-						      GTK_ICON_SIZE_MENU);
-	else
-		image = gtk_image_new_from_icon_name ("gdict",
-						      GTK_ICON_SIZE_MENU);*/
-
 	data->panel = create_dict_panel (window);
 	
-	restore_position(GTR_DICT_PANEL(data->panel));
+	gtranslator_application_register_icon (GTR_APP, "gnome-dictionary.png",
+					       "dictionary-icon");
 	
 	gtranslator_window_add_widget (window,
 				       data->panel,
 				       "GtranslatorDictionaryPlugin",
 				       _("Dictionary"),
-				       NULL,
+				       "dictionary-icon",
 				       GTR_WINDOW_PLACEMENT_LEFT);
 
-	//gtk_object_sink (GTK_OBJECT (image));
-
 	g_object_set_data_full (G_OBJECT (window),
 				WINDOW_DATA_KEY,
 				data,

Modified: trunk/plugins/dictionary/gdict-sidebar.c
==============================================================================
--- trunk/plugins/dictionary/gdict-sidebar.c	(original)
+++ trunk/plugins/dictionary/gdict-sidebar.c	Tue Sep 16 07:58:13 2008
@@ -58,7 +58,6 @@
   GtkWidget *hbox;
   GtkWidget *notebook;
   GtkWidget *menu;
-  GtkWidget *close_button;
   GtkWidget *label;
   GtkWidget *select_button;
 };
@@ -215,15 +214,6 @@
 }
 
 static void
-gdict_sidebar_close_clicked_cb (GtkWidget *widget,
-				gpointer   user_data)
-{
-  GdictSidebar *sidebar = GDICT_SIDEBAR (user_data);
-
-  g_signal_emit (sidebar, sidebar_signals[CLOSED], 0);
-}
-
-static void
 gdict_sidebar_menu_deactivate_cb (GtkWidget *widget,
 				  gpointer   user_data)
 {
@@ -309,7 +299,6 @@
   GtkWidget *hbox;
   GtkWidget *select_hbox;
   GtkWidget *select_button;
-  GtkWidget *close_button;
   GtkWidget *arrow;
 
   sidebar->priv = priv = GDICT_SIDEBAR_GET_PRIVATE (sidebar);
@@ -356,18 +345,6 @@
   gtk_box_pack_start (GTK_BOX (hbox), select_button, TRUE, TRUE, 0);
   gtk_widget_show (select_button);
 
-  close_button = gtk_button_new ();
-  gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
-  gtk_button_set_image (GTK_BUTTON (close_button),
-		        gtk_image_new_from_stock (GTK_STOCK_CLOSE,
-						  GTK_ICON_SIZE_SMALL_TOOLBAR));
-  g_signal_connect (close_button, "clicked",
-		    G_CALLBACK (gdict_sidebar_close_clicked_cb),
-		    sidebar);
-  gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
-  gtk_widget_show (close_button);
-  priv->close_button = close_button;
-
   sidebar->priv->menu = gtk_menu_new ();
   g_signal_connect (sidebar->priv->menu, "deactivate",
 		    G_CALLBACK (gdict_sidebar_menu_deactivate_cb),

Added: trunk/plugins/dictionary/gnome-dictionary.png
==============================================================================
Binary files (empty file) and trunk/plugins/dictionary/gnome-dictionary.png	Tue Sep 16 07:58:13 2008 differ

Modified: trunk/plugins/fullscreen/fullscreen-plugin.c
==============================================================================
--- trunk/plugins/fullscreen/fullscreen-plugin.c	(original)
+++ trunk/plugins/fullscreen/fullscreen-plugin.c	Tue Sep 16 07:58:13 2008
@@ -102,6 +102,8 @@
 	if (data->ui_id == 0)
 	{
 		g_warning (error->message);
+		g_error_free (error);
+		g_free (data);
 		return;
 	}
 

Modified: trunk/plugins/insert-tags/insert-tags-plugin.c
==============================================================================
--- trunk/plugins/insert-tags/insert-tags-plugin.c	(original)
+++ trunk/plugins/insert-tags/insert-tags-plugin.c	Tue Sep 16 07:58:13 2008
@@ -70,7 +70,7 @@
 	{ "InsertTags", NULL, N_("_Insert Tags") }
 };
 
-const gchar submenu[] =
+static const gchar submenu[] =
 "<ui>"
 "  <menubar name='MainMenu'>"
 "    <menu name='EditMenu' action='Edit'>"
@@ -126,6 +126,12 @@
 static void
 gtranslator_insert_tags_plugin_finalize (GObject *object)
 {
+	if (tags != NULL)
+	{
+		g_slist_free (tags);
+		tags = NULL;
+	}
+	
 	G_OBJECT_CLASS (gtranslator_insert_tags_plugin_parent_class)->finalize (object);
 }
 
@@ -193,7 +199,7 @@
 					      (const gchar *)l->data);
 		
 		gtk_menu_item_set_accel_path (GTK_MENU_ITEM (menuitem), accel_path);
-		gtk_accel_map_add_entry (accel_path, i+48, GDK_CONTROL_MASK);
+		gtk_accel_map_add_entry (accel_path, i+48, GDK_CONTROL_MASK | GDK_MOD1_MASK);
 
 		g_free (accel_path);
 		
@@ -235,7 +241,7 @@
 	/*
 	 * Regular expression
 	 */
-	regex = g_regex_new ("<[-0-9a-zA-Z=\"/ ]+>", 0, 0, NULL);
+	regex = g_regex_new ("<[-0-9a-zA-Z=.:?\"/ ]+>", 0, 0, NULL);
 	g_regex_match (regex, msgid, 0, &match_info);
 	while (g_match_info_matches (match_info))
 	{
@@ -290,9 +296,11 @@
 							 submenu,
 							 -1,
 							 &error);
-	if (data->ui_id == 0)
+	if (error)
 	{
 		g_warning (error->message);
+		g_error_free (error);
+		g_free (data);
 		return;
 	}
 
@@ -344,6 +352,12 @@
 	g_signal_handlers_disconnect_by_func(notebook,
 					     page_added_cb,
 					     window);
+	
+	if (tags != NULL)
+	{
+		g_slist_free (tags);
+		tags = NULL;
+	}
 }
 
 static void

Modified: trunk/plugins/open-tran/Makefile.am
==============================================================================
--- trunk/plugins/open-tran/Makefile.am	(original)
+++ trunk/plugins/open-tran/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -38,7 +38,10 @@
         kde.ico \
         mozilla.png \
         debian.png \
-	open-tran.png
+	open-tran.png \
+	suse.png \
+	xfce.png \
+	inkscape.png
 
 # Plugin Info
 

Added: trunk/plugins/open-tran/inkscape.png
==============================================================================
Binary files (empty file) and trunk/plugins/open-tran/inkscape.png	Tue Sep 16 07:58:13 2008 differ

Modified: trunk/plugins/open-tran/open-tran-dialog.glade
==============================================================================
--- trunk/plugins/open-tran/open-tran-dialog.glade	(original)
+++ trunk/plugins/open-tran/open-tran-dialog.glade	Tue Sep 16 07:58:13 2008
@@ -123,7 +123,7 @@
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label" translatable="no">gtk-cancel</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-6</property>
               </widget>
@@ -134,7 +134,7 @@
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="label" translatable="no">gtk-ok</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-5</property>
               </widget>

Modified: trunk/plugins/open-tran/open-tran-panel.c
==============================================================================
--- trunk/plugins/open-tran/open-tran-panel.c	(original)
+++ trunk/plugins/open-tran/open-tran-panel.c	Tue Sep 16 07:58:13 2008
@@ -43,6 +43,9 @@
 #define KDE_ICON     PIXMAPSDIR"/kde.ico"
 #define MOZILLA_ICON PIXMAPSDIR"/mozilla.png"
 #define DEBIAN_ICON  PIXMAPSDIR"/debian.png"
+#define SUSE_ICON    PIXMAPSDIR"/suse.png"
+#define XFCE_ICON    PIXMAPSDIR"/xfce.png"
+#define INKSCAPE_ICON PIXMAPSDIR"/inkscape.png"
 
 GTR_PLUGIN_DEFINE_TYPE(GtranslatorOpenTranPanel, gtranslator_open_tran_panel, GTK_TYPE_VBOX)
 
@@ -128,27 +131,21 @@
 	{
 		str = g_value_get_string (value);
 
-		/*
-		 * We have to parse the first character of str:
-		 * G - Gnome
-		 * K - KDE
-		 * M - Mozilla
-		 * D - Debian Installer
-		 * F - Frysian dictionary
-		 */
-		switch(*str)
-		{
-			case 'G': icon = create_pixbuf(GNOME_ICON);
-				break;
-			case 'K': icon = create_pixbuf(KDE_ICON);
-				break;
-			case 'M': icon = create_pixbuf(MOZILLA_ICON);
-				break;
-			case 'D': icon = create_pixbuf(DEBIAN_ICON);
-				break;
-			default: icon = NULL;
-				break;
-		}
+		if (strcmp ("GNOME", str) == 0)
+			icon = create_pixbuf (GNOME_ICON);
+		else if (strcmp ("KDE", str) == 0)
+			icon = create_pixbuf (KDE_ICON);
+		else if (strcmp ("MOZILLA", str) == 0)
+			icon = create_pixbuf (MOZILLA_ICON);
+		else if (strcmp ("DEBIAN", str) == 0)
+			icon = create_pixbuf (DEBIAN_ICON);
+		else if (strcmp ("SUSE", str) == 0)
+			icon = create_pixbuf (SUSE_ICON);
+		else if (strcmp ("XFCE", str) == 0)
+			icon = create_pixbuf (XFCE_ICON);
+		else if (strcmp ("Inkscape", str) == 0)
+			icon = create_pixbuf (INKSCAPE_ICON);
+		else icon = NULL;
 		
 		gtk_list_store_append(panel->priv->store, &iter);
 		gtk_list_store_set(panel->priv->store, &iter,
@@ -157,6 +154,9 @@
 				   -1);
 				   
 		g_free (panel->priv->text);
+		
+		if (icon)
+			g_object_unref (icon);
 	}
 }
 

Modified: trunk/plugins/open-tran/open-tran-plugin.c
==============================================================================
--- trunk/plugins/open-tran/open-tran-plugin.c	(original)
+++ trunk/plugins/open-tran/open-tran-plugin.c	Tue Sep 16 07:58:13 2008
@@ -94,33 +94,13 @@
 impl_activate (GtranslatorPlugin *plugin,
 	       GtranslatorWindow *window)
 {
-	//GtkWidget *image = NULL;
 	GtkWidget *opentran;
-	/*GdkPixbuf *pixbuf;
-	GtkIconSet *iconset;
-	GError *error = NULL;*/
-	
-	/*pixbuf = gdk_pixbuf_new_from_file(OPEN_TRAN_PLUGIN_ICON, &error);
-	
-	if (error)
-	{
-		g_warning ("Could not load icon: %s\n", error->message);
-		g_error_free(error);
-		pixbuf = NULL;
-	}
-	
-	if(pixbuf)
-	{
-		iconset = gtk_icon_set_new_from_pixbuf(pixbuf);
-	
-		image = gtk_image_new_from_icon_set(iconset,
-						    GTK_ICON_SIZE_MENU);
-	}*/
 	
 	gtranslator_application_register_icon (GTR_APP, "open-tran.png",
 					       "open-tran-plugin-icon");
 
 	opentran = gtranslator_open_tran_panel_new(window);
+	gtk_widget_show (opentran);
 
 	gtranslator_window_add_widget (window,
 				       opentran,
@@ -132,8 +112,6 @@
 	g_object_set_data(G_OBJECT(window),
 			  WINDOW_DATA_KEY,
 			  opentran);
-	
-	gtk_widget_show_all(opentran);
 }
 
 static void

Added: trunk/plugins/open-tran/suse.png
==============================================================================
Binary files (empty file) and trunk/plugins/open-tran/suse.png	Tue Sep 16 07:58:13 2008 differ

Added: trunk/plugins/open-tran/xfce.png
==============================================================================
Binary files (empty file) and trunk/plugins/open-tran/xfce.png	Tue Sep 16 07:58:13 2008 differ

Added: trunk/plugins/source-code-view/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/source-code-view/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,47 @@
+# source-code-view plugin
+plugindir = $(libdir)/gtranslator/plugins
+
+INCLUDES = \
+	-I$(top_srcdir) 				\
+	-I$(top_srcdir)/src				\
+	-I$(top_srcdir)/src/plugin-system		\
+	$(GTRANSLATOR_CFLAGS) 				\
+	$(WARN_CFLAGS)					\
+	$(DISABLE_DEPRECATED_CFLAGS)			\
+	-DDATADIR=\""$(pkgdatadir)"\"                   \
+	-DGTR_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"
+
+plugin_LTLIBRARIES = \
+	libsourcecodeview.la
+
+libsourcecodeview_la_SOURCES = \
+	source-code-view-plugin.c \
+	source-code-view-plugin.h \
+	viewer.c \
+	viewer.h
+
+libsourcecodeview_la_LDFLAGS = \
+	$(PLUGIN_LIBTOOL_FLAGS)				\
+	$(GTRANSLATOR_LIBS)
+
+gladedir = $(pkgdatadir)
+
+glade_DATA =  \
+        viewer.glade \
+	source-code-view-dialog.glade
+
+# Plugin Info
+
+plugin_in_files = source-code-view.gtranslator-plugin.desktop.in
+
+%.gtranslator.plugin: %.gtranslator-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.gtranslator-plugin.desktop.in=.gtranslator.plugin)
+
+EXTRA_DIST =	\
+	$(plugin_in_files)	\
+	$(glade_DATA)
+
+CLEANFILES = $(plugin_DATA)
+DISTCLEANFILES = $(plugin_DATA)
+

Added: trunk/plugins/source-code-view/source-code-view-dialog.glade
==============================================================================
--- (empty file)
+++ trunk/plugins/source-code-view/source-code-view-dialog.glade	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Mon Jun 30 12:37:34 2008 -->
+<glade-interface>
+  <widget class="GtkDialog" id="dialog">
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Source View Settings</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="main_box">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="border_width">12</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkCheckButton" id="use_editor">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="label" translatable="yes">Use external editor</property>
+                <property name="response_id">0</property>
+                <property name="draw_indicator">True</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="program_box">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Program command:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <widget class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">    </property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkEntry" id="program_cmd">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="tooltip_text">E.g.: gedit</property>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Line command:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox2">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">     </property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkEntry" id="line_cmd">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="tooltip_text">E.g.: +</property>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="cancel_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="no">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="ok_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="no">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-5</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

Added: trunk/plugins/source-code-view/source-code-view-plugin.c
==============================================================================
--- (empty file)
+++ trunk/plugins/source-code-view/source-code-view-plugin.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,748 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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
+ *     MERCHANPOILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "source-code-view-plugin.h"
+#include "context.h"
+#include "utils.h"
+#include "viewer.h"
+#include "window.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <gio/gio.h>
+#include <gconf/gconf-client.h>
+
+/* Gconf keys */
+#define SOURCE_CODE_VIEW_BASE_KEY "/apps/gtranslator/plugins/source-view"
+#define USE_EDITOR_KEY SOURCE_CODE_VIEW_BASE_KEY "/use_editor"
+#define PROGRAM_CMD_KEY SOURCE_CODE_VIEW_BASE_KEY "/program_cmd"
+#define LINE_CMD_KEY SOURCE_CODE_VIEW_BASE_KEY "/line_cmd"
+
+/* Glade */
+#define GLADE_FILE DATADIR"/source-view-dialog.glade"
+
+#define GTR_SOURCE_CODE_VIEW_PLUGIN_GET_PRIVATE(object) \
+				(G_TYPE_INSTANCE_GET_PRIVATE ((object),	\
+				GTR_TYPE_SOURCE_CODE_VIEW_PLUGIN,		\
+				GtranslatorSourceCodeViewPluginPrivate))
+
+struct _GtranslatorSourceCodeViewPluginPrivate
+{
+	GConfClient *gconf_client;
+	
+	/* Dialog stuff */
+	GtkWidget *dialog;
+	
+	GtkWidget *main_box;
+	GtkWidget *use_editor_checkbutton;
+	GtkWidget *program_box;
+	GtkWidget *program_cmd_entry;
+	GtkWidget *line_cmd_entry;
+	
+	GtranslatorWindow *window;
+
+	GSList *tags;	
+};
+
+GTR_PLUGIN_REGISTER_TYPE(GtranslatorSourceCodeViewPlugin, gtranslator_source_code_view_plugin)
+
+static void 
+insert_link (GtkTextBuffer *buffer, 
+	     GtkTextIter *iter,
+	     const gchar *path,
+	     gint *line,
+	     GtranslatorSourceCodeViewPlugin *plugin)
+{
+	GtkTextTag *tag;
+	gchar *text;
+
+	tag = gtk_text_buffer_create_tag (buffer, NULL, 
+					  "foreground", "blue", 
+					  "underline", PANGO_UNDERLINE_SINGLE, 
+					  NULL);
+	g_object_set_data (G_OBJECT (tag), "path", g_strdup (path));
+	g_object_set_data (G_OBJECT (tag), "line", line);
+
+	text = g_strdup_printf ("%s:%d\n", path, GPOINTER_TO_INT (line));
+	gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
+	g_free (text);
+	
+	plugin->priv->tags = g_slist_prepend (plugin->priv->tags, tag);
+}
+
+static void
+show_in_editor (const gchar *program_name,
+		const gchar *line_cmd,
+		const gchar *path,
+		gint line)
+{
+	gchar *open[4];
+
+	if (g_find_program_in_path (program_name))
+	{
+		open[0] = g_strdup (program_name);
+	}
+	else
+	{
+		GtkWidget *dialog;
+		
+		dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+						 GTK_DIALOG_MODAL,
+						 GTK_BUTTONS_CLOSE,
+						 _("Please, install %s to be able to show the file"),
+						 program_name);
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+	}
+	
+	open[1] = g_strdup (path);
+	open[2] = g_strdup_printf ("%s%d",line_cmd, line);
+	open[3] = NULL;
+					
+	gdk_spawn_on_screen (gdk_screen_get_default (),
+			     NULL,
+			     open,
+			     NULL,
+			     G_SPAWN_SEARCH_PATH,
+			     NULL,
+			     NULL, NULL, NULL);
+	g_free (open[0]);
+	g_free (open[1]);
+	g_free (open[2]);
+}
+
+static void
+show_source (GtranslatorSourceCodeViewPlugin *plugin,
+	     const gchar *path,
+	     gint line)
+{
+	gboolean use_editor;
+	
+	use_editor = gconf_client_get_bool (plugin->priv->gconf_client,
+					    USE_EDITOR_KEY,
+					    NULL);
+
+	if (use_editor)
+	{
+		gchar *program_cmd;
+		gchar *line_cmd;
+		
+		//Program cmd
+		program_cmd = gconf_client_get_string (plugin->priv->gconf_client,
+						       PROGRAM_CMD_KEY,
+						       NULL);
+	
+		//Line cmd
+		line_cmd = gconf_client_get_string (plugin->priv->gconf_client,
+						    LINE_CMD_KEY,
+						    NULL);
+		
+		show_in_editor (program_cmd,
+				line_cmd,
+				path, line);
+		
+		g_free (program_cmd);
+		g_free (line_cmd);
+	}
+	else gtranslator_show_viewer (plugin->priv->window,
+				      path, line);
+}
+
+static void
+follow_if_link (GtranslatorSourceCodeViewPlugin *plugin,
+		GtkWidget   *text_view, 
+		GtkTextIter *iter)
+{
+	GSList *tags = NULL, *tagp = NULL;
+	GtranslatorTab *tab;
+	GtranslatorPo *po;
+	gchar *fullpath;
+	gchar *dirname;
+	GFile *location, *parent;
+	
+	tab = gtranslator_window_get_active_tab (plugin->priv->window);
+
+	if (!tab)
+		return;
+	po = gtranslator_tab_get_po (tab);
+
+	location = gtranslator_po_get_location (po);
+	parent = g_file_get_parent (location);
+	g_object_unref (location);
+	
+	dirname = g_file_get_path (parent);
+	g_object_unref (parent);
+	
+	tags = gtk_text_iter_get_tags (iter);
+	for (tagp = tags;  tagp != NULL;  tagp = tagp->next)
+	{
+		GtkTextTag *tag = tagp->data;
+		gchar *path = g_object_get_data (G_OBJECT (tag), "path");
+		gint line = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "line"));
+
+		fullpath = g_build_filename (dirname, path, NULL);
+		show_source (plugin, fullpath, line);
+		
+		g_free (fullpath);
+	}
+
+	if (tags)
+		g_slist_free (tags);
+	
+	g_free (dirname);
+}
+
+static gboolean
+event_after (GtkWidget *text_view,
+	     GdkEvent  *ev,
+	     GtranslatorSourceCodeViewPlugin *plugin)
+{
+	GtkTextIter start, end, iter;
+	GtkTextBuffer *buffer;
+	GdkEventButton *event;
+	gint x, y;
+
+	if (ev->type != GDK_BUTTON_RELEASE)
+		return FALSE;
+
+	event = (GdkEventButton *)ev;
+
+	if (event->button != 1)
+		return FALSE;
+
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
+
+	/* we shouldn't follow a link if the user has selected something */
+	gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+	if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
+		return FALSE;
+
+	gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), 
+					       GTK_TEXT_WINDOW_WIDGET,
+					       event->x, event->y, &x, &y);
+	
+	gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
+
+	follow_if_link (plugin, text_view, &iter);
+
+	return FALSE;
+}
+
+static gboolean hovering_over_link = FALSE;
+static GdkCursor *hand_cursor = NULL;
+static GdkCursor *regular_cursor = NULL;
+
+/* Looks at all tags covering the position (x, y) in the text view, 
+ * and if one of them is a link, change the cursor to the "hands" cursor
+ * typically used by web browsers.
+ */
+static void
+set_cursor_if_appropriate (GtkTextView    *text_view,
+                           gint            x,
+                           gint            y)
+{
+	GSList *tags = NULL, *tagp = NULL;
+	GtkTextIter iter;
+	gboolean hovering = FALSE;
+
+	gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
+  
+	tags = gtk_text_iter_get_tags (&iter);
+	for (tagp = tags;  tagp != NULL;  tagp = tagp->next)
+	{
+		GtkTextTag *tag = tagp->data;
+		gchar *path = g_object_get_data (G_OBJECT (tag), "path");
+
+		if (path) 
+		{
+			hovering = TRUE;
+			break;
+		}
+	}
+
+	if (hovering != hovering_over_link)
+	{
+		hovering_over_link = hovering;
+
+		if (hovering_over_link)
+			gdk_window_set_cursor (gtk_text_view_get_window (text_view,
+									 GTK_TEXT_WINDOW_TEXT),
+					       hand_cursor);
+		else
+			gdk_window_set_cursor (gtk_text_view_get_window (text_view,
+									 GTK_TEXT_WINDOW_TEXT),
+					       regular_cursor);
+	}
+	
+	if (tags) 
+		g_slist_free (tags);
+}
+
+/*
+ * Update the cursor image if the pointer moved. 
+ */
+static gboolean
+motion_notify_event (GtkWidget      *text_view,
+		     GdkEventMotion *event)
+{
+	gint x, y;
+
+	gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), 
+					       GTK_TEXT_WINDOW_WIDGET,
+					       event->x, event->y, &x, &y);
+
+	set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
+
+	gdk_window_get_pointer (text_view->window, NULL, NULL, NULL);
+	return FALSE;
+}
+
+/* Also update the cursor image if the window becomes visible
+ * (e.g. when a window covering it got iconified).
+ */
+static gboolean
+visibility_notify_event (GtkWidget          *text_view,
+			 GdkEventVisibility *event)
+{
+	gint wx, wy, bx, by;
+  
+	gdk_window_get_pointer (text_view->window, &wx, &wy, NULL);
+  
+	gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), 
+					       GTK_TEXT_WINDOW_WIDGET,
+					       wx, wy, &bx, &by);
+
+	set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), bx, by);
+
+	return FALSE;
+}
+
+static void
+gtranslator_source_code_view_plugin_init (GtranslatorSourceCodeViewPlugin *plugin)
+{
+	plugin->priv = GTR_SOURCE_CODE_VIEW_PLUGIN_GET_PRIVATE (plugin);
+
+	plugin->priv->gconf_client = gconf_client_get_default ();
+
+	gconf_client_add_dir (plugin->priv->gconf_client,
+			      SOURCE_CODE_VIEW_BASE_KEY,
+			      GCONF_CLIENT_PRELOAD_ONELEVEL,
+			      NULL);
+	
+	plugin->priv->tags = NULL;
+}
+
+static void
+gtranslator_source_code_view_plugin_finalize (GObject *object)
+{
+	GtranslatorSourceCodeViewPlugin *plugin = GTR_SOURCE_CODE_VIEW_PLUGIN (object);
+	
+	gconf_client_suggest_sync (plugin->priv->gconf_client, NULL);
+
+	g_object_unref (G_OBJECT (plugin->priv->gconf_client));
+	
+	G_OBJECT_CLASS (gtranslator_source_code_view_plugin_parent_class)->finalize (object);
+}
+
+static void
+showed_message_cb (GtranslatorTab *tab,
+		   GtranslatorMsg *msg,
+		   GtranslatorSourceCodeViewPlugin *plugin)
+{
+	const gchar *filename = NULL;
+	gint i = 0;
+	gint *line = NULL;
+	GtkTextIter iter;
+	GtkTextBuffer *buffer;
+	GtkTextView *view;
+	GtranslatorContextPanel *panel;
+	GtkTextMark *path_start, *path_end;
+
+	panel = gtranslator_tab_get_context_panel (tab);
+	view = gtranslator_context_panel_get_context_text_view (panel);
+	
+	buffer = gtk_text_view_get_buffer (view);
+	
+	gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+	
+	path_start = gtk_text_buffer_create_mark (buffer,
+						  "path_start",
+						  &iter,
+						  TRUE);
+	gtk_text_buffer_insert (buffer, &iter, _("Paths:\n"), -1);
+	
+	filename = gtranslator_msg_get_filename (msg, i);
+	while (filename)
+	{
+		line = gtranslator_msg_get_file_line (msg, i);
+		insert_link (buffer, &iter, filename, line, plugin);
+		i++;
+		filename = gtranslator_msg_get_filename (msg, i);
+	}
+	
+	/*
+	 * The tags are managed by buffer, so lets add a reference in the buffer
+	 */
+	g_object_set_data (G_OBJECT (buffer), "link_tags", plugin->priv->tags);
+	plugin->priv->tags = NULL;
+
+	path_end = gtk_text_buffer_create_mark (buffer,
+						"path_end",
+						&iter,
+						TRUE);
+}
+
+static void
+delete_text_and_tags (GtranslatorTab *tab,
+		      GtranslatorSourceCodeViewPlugin *plugin)
+{
+	GSList *tagp = NULL, *tags;
+	GtkTextBuffer *buffer;
+	GtranslatorContextPanel *panel;
+	GtkTextView *view;
+	GtkTextIter start, end;
+	GtkTextMark *path_start, *path_end;
+	
+	panel = gtranslator_tab_get_context_panel (tab);
+	view = gtranslator_context_panel_get_context_text_view (panel);
+	
+	buffer = gtk_text_view_get_buffer (view);
+	path_start = gtk_text_buffer_get_mark (buffer, "path_start");
+	
+	if (path_start == NULL)
+		return;
+	
+	path_end = gtk_text_buffer_get_mark (buffer, "path_end");
+	tags = g_object_get_data (G_OBJECT (buffer), "link_tags");
+
+	for (tagp = tags;  tagp != NULL;  tagp = tagp->next)
+	{
+		GtkTextTag *tag = tagp->data;
+		gchar *path = g_object_get_data (G_OBJECT (tag), "path");
+		
+		if (path) 
+		{
+			g_free (path);
+		}
+	}
+	g_slist_free (tags);
+
+	/*
+	 * Deleting the text
+	 */
+	gtk_text_buffer_get_iter_at_mark (buffer, &start, path_start);
+	gtk_text_buffer_get_iter_at_mark (buffer, &end, path_end);
+	gtk_text_buffer_delete (buffer, &start, &end);
+	
+	/*
+	 * Deleting the marks
+	 */
+	gtk_text_buffer_delete_mark (buffer, path_start);
+	gtk_text_buffer_delete_mark (buffer, path_end);
+}
+
+static void
+message_edition_finished_cb (GtranslatorTab *tab,
+			     GtranslatorMsg *msg,
+			     GtranslatorSourceCodeViewPlugin *plugin)
+{
+	delete_text_and_tags (tab, plugin);
+}
+
+static void
+page_added_cb (GtkNotebook *notebook,
+	       GtkWidget *child,
+	       guint page_num,
+	       GtranslatorSourceCodeViewPlugin *plugin)
+{	
+	GtranslatorContextPanel *panel;
+	GtkTextView *view;
+
+	panel = gtranslator_tab_get_context_panel (GTR_TAB (child));
+	view = gtranslator_context_panel_get_context_text_view (panel);
+	
+	g_return_if_fail (GTK_IS_TEXT_VIEW (view));
+
+	g_signal_connect_after (child, "showed-message",
+				G_CALLBACK (showed_message_cb), plugin);
+	g_signal_connect (child, "message-edition-finished",
+			  G_CALLBACK (message_edition_finished_cb), plugin);
+	
+	g_signal_connect (view, "event-after", 
+			  G_CALLBACK (event_after), plugin);
+	g_signal_connect (view, "motion-notify-event", 
+			  G_CALLBACK (motion_notify_event), NULL);
+	g_signal_connect (view, "visibility-notify-event", 
+			  G_CALLBACK (visibility_notify_event), NULL);
+}
+
+static void
+use_editor_toggled (GtkToggleButton *button,
+		    GtranslatorSourceCodeViewPlugin *plugin)
+{
+	gtk_widget_set_sensitive (plugin->priv->program_box,
+				  gtk_toggle_button_get_active (button));
+}
+
+static GtkWidget *
+get_configuration_dialog (GtranslatorSourceCodeViewPlugin *plugin)
+{
+
+	gboolean ret;
+	GtkWidget *error_widget;
+	gchar *value;
+	gboolean use_editor;
+	
+	ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+						  "dialog",
+						  &error_widget,
+						  "dialog", &plugin->priv->dialog,
+						  "main_box", &plugin->priv->main_box,
+						  "use_editor", &plugin->priv->use_editor_checkbutton,
+						  "program_box", &plugin->priv->program_box,
+						  "program_cmd", &plugin->priv->program_cmd_entry,
+						  "line_cmd", &plugin->priv->line_cmd_entry,
+						  NULL);
+
+	if(!ret)
+	{
+		//FIXME: We have to show a dialog
+	}
+
+	/* Set default values */
+	
+	//Use editor
+	use_editor = gconf_client_get_bool (plugin->priv->gconf_client,
+					    USE_EDITOR_KEY,
+					    NULL);
+	
+	g_signal_connect (plugin->priv->use_editor_checkbutton, "toggled",
+			  G_CALLBACK (use_editor_toggled), plugin);
+	
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->priv->use_editor_checkbutton),
+				      use_editor);
+	
+	use_editor_toggled (GTK_TOGGLE_BUTTON (plugin->priv->use_editor_checkbutton),
+			    plugin);
+	
+	//Program cmd
+	value = gconf_client_get_string (plugin->priv->gconf_client,
+					 PROGRAM_CMD_KEY,
+					 NULL);
+
+	gtk_entry_set_text (GTK_ENTRY (plugin->priv->program_cmd_entry),
+			    value);
+	
+	g_free (value);
+	
+	//Line cmd
+	value = gconf_client_get_string (plugin->priv->gconf_client,
+					 LINE_CMD_KEY,
+					 NULL);
+	
+	gtk_entry_set_text (GTK_ENTRY (plugin->priv->line_cmd_entry),
+			    value);
+
+	g_free (value);
+	
+	return plugin->priv->dialog;
+}
+
+static void
+impl_activate (GtranslatorPlugin *plugin,
+	       GtranslatorWindow *window)
+{	
+	GtkWidget *notebook;
+	GtranslatorSourceCodeViewPlugin *source_code_view = GTR_SOURCE_CODE_VIEW_PLUGIN (plugin);
+	GList *tabs, *l;
+
+	/*
+	 * Cursors
+	 */
+	hand_cursor = gdk_cursor_new (GDK_HAND2);
+	regular_cursor = gdk_cursor_new (GDK_XTERM);
+	
+	notebook = GTK_WIDGET (gtranslator_window_get_notebook (window));
+	
+	source_code_view->priv->window = window;
+	
+	g_signal_connect (notebook, "page-added",
+			  G_CALLBACK (page_added_cb), plugin);
+
+	/*
+	 * If we already have tabs opened we have to add them
+	 */
+	tabs = gtranslator_window_get_all_tabs (window);
+	for (l = tabs; l != NULL; l = g_list_next (l))
+	{
+		GtranslatorPo *po;
+		GList *msg;
+		
+		page_added_cb (GTK_NOTEBOOK (notebook),
+			       l->data, 0, GTR_SOURCE_CODE_VIEW_PLUGIN (plugin));
+		
+		po = gtranslator_tab_get_po (GTR_TAB (l->data));
+		msg = gtranslator_po_get_current_message (po);
+		
+		showed_message_cb (GTR_TAB (l->data),
+				   msg->data, GTR_SOURCE_CODE_VIEW_PLUGIN (plugin));
+	}
+}
+
+static void
+impl_deactivate(GtranslatorPlugin *plugin,
+	        GtranslatorWindow *window)
+{
+	GList *tabs, *l;
+	GtkTextView *view;
+	GtranslatorContextPanel *panel;
+	GtkWidget *notebook;
+	
+	tabs = gtranslator_window_get_all_tabs (window);
+	notebook = GTK_WIDGET (gtranslator_window_get_notebook (window));
+	
+	for (l = tabs; l != NULL; l = g_list_next (l))
+	{
+		panel = gtranslator_tab_get_context_panel (GTR_TAB (l->data));
+		view = gtranslator_context_panel_get_context_text_view (panel);
+		
+		delete_text_and_tags (GTR_TAB (l->data), GTR_SOURCE_CODE_VIEW_PLUGIN (plugin));
+		
+		g_signal_handlers_disconnect_by_func (l->data,
+						      showed_message_cb,
+						      plugin);
+
+		g_signal_handlers_disconnect_by_func (view,
+						      event_after,
+						      window);
+		g_signal_handlers_disconnect_by_func (view,
+						      motion_notify_event,
+						      NULL);
+		g_signal_handlers_disconnect_by_func (view,
+						      visibility_notify_event,
+						      NULL);
+	}
+	
+	g_signal_handlers_disconnect_by_func (notebook, 
+					      page_added_cb,
+					      plugin);
+}
+
+static void
+ok_button_pressed (GtranslatorSourceCodeViewPlugin *plugin)
+{
+	const gchar *program_cmd;
+	const gchar *line_cmd;
+	gboolean use_editor;
+	
+	/* We have to get the text from the entries */
+	use_editor = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (plugin->priv->use_editor_checkbutton));
+	program_cmd = gtk_entry_get_text (GTK_ENTRY (plugin->priv->program_cmd_entry));
+	line_cmd = gtk_entry_get_text (GTK_ENTRY (plugin->priv->line_cmd_entry));
+	
+	/* Now we store the data in gconf */
+	if (!gconf_client_key_is_writable (plugin->priv->gconf_client,
+					   USE_EDITOR_KEY,
+					   NULL))
+		return;
+
+	gconf_client_set_bool (plugin->priv->gconf_client,
+			       USE_EDITOR_KEY,
+			       use_editor,
+			       NULL);
+	
+	if (!gconf_client_key_is_writable (plugin->priv->gconf_client,
+					   PROGRAM_CMD_KEY,
+					   NULL))
+		return;
+
+	gconf_client_set_string (plugin->priv->gconf_client,
+				 PROGRAM_CMD_KEY,
+		       		 program_cmd,
+		       		 NULL);
+	
+	if (!gconf_client_key_is_writable (plugin->priv->gconf_client,
+					   LINE_CMD_KEY,
+					   NULL))
+		return;
+
+	gconf_client_set_string (plugin->priv->gconf_client,
+				 LINE_CMD_KEY,
+		       		 line_cmd,
+		       		 NULL);
+}
+
+static void
+configure_dialog_response_cb (GtkWidget           *widget,
+			      gint                 response,
+			      GtranslatorSourceCodeViewPlugin *plugin)
+{
+	switch (response)
+	{
+		case GTK_RESPONSE_OK:
+		{
+			ok_button_pressed (plugin);
+
+			gtk_widget_destroy (plugin->priv->dialog);
+			break;
+		}
+		case GTK_RESPONSE_CANCEL:
+		{
+			gtk_widget_destroy (plugin->priv->dialog);
+		}
+	}
+}
+
+static GtkWidget *
+impl_create_configure_dialog (GtranslatorPlugin *plugin)
+{
+	GtkWidget *dialog;
+	
+	dialog = get_configuration_dialog (GTR_SOURCE_CODE_VIEW_PLUGIN (plugin));
+	
+	g_signal_connect (dialog,
+			  "response",
+			  G_CALLBACK (configure_dialog_response_cb),
+			  GTR_SOURCE_CODE_VIEW_PLUGIN (plugin));
+	g_signal_connect (dialog,
+			  "destroy",
+			  G_CALLBACK (gtk_widget_destroy),
+			  &dialog);
+	
+	return dialog;
+}
+
+static void
+gtranslator_source_code_view_plugin_class_init (GtranslatorSourceCodeViewPluginClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtranslatorPluginClass *plugin_class = GTR_PLUGIN_CLASS (klass);
+
+	object_class->finalize = gtranslator_source_code_view_plugin_finalize;
+
+	plugin_class->activate = impl_activate;
+	plugin_class->deactivate = impl_deactivate;
+	plugin_class->create_configure_dialog = impl_create_configure_dialog;
+	
+	g_type_class_add_private (object_class, sizeof (GtranslatorSourceCodeViewPluginPrivate));
+}

Added: trunk/plugins/source-code-view/source-code-view-plugin.h
==============================================================================
--- (empty file)
+++ trunk/plugins/source-code-view/source-code-view-plugin.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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
+ *     MERCHANPOILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __GTR_SOURCE_CODE_VIEW_PLUGIN_H__
+#define __GTR_SOURCE_CODE_VIEW_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "plugin.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_SOURCE_CODE_VIEW_PLUGIN		(gtranslator_source_code_view_plugin_get_type ())
+#define GTR_SOURCE_CODE_VIEW_PLUGIN(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_SOURCE_CODE_VIEW_PLUGIN, GtranslatorSourceCodeViewPlugin))
+#define GTR_SOURCE_CODE_VIEW_PLUGIN_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_SOURCE_CODE_VIEW_PLUGIN, GtranslatorSourceCodeViewPluginClass))
+#define GTR_IS_SOURCE_CODE_VIEW_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_SOURCE_CODE_VIEW_PLUGIN))
+#define GTR_IS_SOURCE_CODE_VIEW_PLUGIN_CLASS(k)		(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_SOURCE_CODE_VIEW_PLUGIN))
+#define GTR_SOURCE_CODE_VIEW_PLUGIN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_SOURCE_CODE_VIEW_PLUGIN_PLUGIN, GtranslatorSourceCodeViewPluginClass))
+
+/* Private structure type */
+typedef struct _GtranslatorSourceCodeViewPluginPrivate	GtranslatorSourceCodeViewPluginPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorSourceCodeViewPlugin		GtranslatorSourceCodeViewPlugin;
+
+struct _GtranslatorSourceCodeViewPlugin
+{
+	GtranslatorPlugin parent_instance;
+	
+	/* private */
+	GtranslatorSourceCodeViewPluginPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorSourceCodeViewPluginClass	GtranslatorSourceCodeViewPluginClass;
+
+struct _GtranslatorSourceCodeViewPluginClass
+{
+	GtranslatorPluginClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType	gtranslator_source_code_view_plugin_get_type	(void) G_GNUC_CONST;
+
+/* All the plugins must implement this function */
+G_MODULE_EXPORT GType register_gtranslator_plugin (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* __GTR_SOURCE_CODE_VIEW_PLUGIN_H__ */

Added: trunk/plugins/source-code-view/source-code-view.gtranslator-plugin.desktop.in
==============================================================================
--- (empty file)
+++ trunk/plugins/source-code-view/source-code-view.gtranslator-plugin.desktop.in	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,8 @@
+[Gtranslator Plugin]
+Module=sourcecodeview
+IAge=2
+_Name=Source Code View
+_Description=Show the message in the source code.
+Authors=Ignacio Casal Quinteiro  <nacho resa gmail com>
+Copyright=Copyright @ 2008 Ignacio Casal Quinteiro
+Website=http://gtranslator.sf.net

Added: trunk/plugins/source-code-view/viewer.c
==============================================================================
--- (empty file)
+++ trunk/plugins/source-code-view/viewer.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "utils.h"
+#include "viewer.h"
+#include "window.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <string.h>
+#include <gtksourceview/gtksourcelanguagemanager.h>
+
+#define GTR_VIEWER_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 	(object),	\
+						 	GTR_TYPE_VIEWER,     \
+						 	GtranslatorViewerPrivate))
+
+
+G_DEFINE_TYPE(GtranslatorViewer, gtranslator_viewer, GTK_TYPE_DIALOG)
+
+struct _GtranslatorViewerPrivate
+{
+	GtkWidget *main_box;
+	GtkWidget *view;
+};		    
+
+static void
+dialog_response_handler (GtkDialog *dlg, 
+			 gint       res_id)
+{
+	switch (res_id)
+	{
+		default:
+			gtk_widget_destroy (GTK_WIDGET(dlg));
+	}
+}
+
+static void
+gtranslator_viewer_init (GtranslatorViewer *dlg)
+{
+	gboolean ret;
+	GtkWidget *error_widget;
+	GtkWidget *sw;
+	
+	dlg->priv = GTR_VIEWER_GET_PRIVATE (dlg);
+	
+	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
+				GTK_STOCK_CLOSE,
+				GTK_RESPONSE_CLOSE,
+				NULL);
+	
+	gtk_window_set_title (GTK_WINDOW (dlg), _("Source Viewer"));
+	gtk_window_set_default_size(GTK_WINDOW(dlg), 800, 600);
+	gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
+	
+	/* HIG defaults */
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 2); /* 2 * 5 + 2 = 12 */
+	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 4);
+	
+	g_signal_connect (dlg,
+			  "response",
+			  G_CALLBACK (dialog_response_handler),
+			  NULL);
+	
+	/*Glade*/
+	ret = gtranslator_utils_get_glade_widgets(DATADIR "/viewer.glade",
+		"main_box",
+		&error_widget,
+		
+		"main_box", &dlg->priv->main_box,
+		"scrolledwindow", &sw,
+		NULL);
+	
+	if(!ret)
+	{
+		gtk_widget_show(error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+					     error_widget);
+		
+		return;
+	}
+	
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+			    dlg->priv->main_box, TRUE, TRUE, 0);
+	
+	gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->main_box), 5);
+	
+	/* Source view */
+	dlg->priv->view = gtk_source_view_new ();
+	gtk_text_view_set_editable (GTK_TEXT_VIEW (dlg->priv->view), FALSE);
+	gtk_widget_show (dlg->priv->view);
+	gtk_container_add (GTK_CONTAINER (sw), dlg->priv->view);
+	
+	gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW (dlg->priv->view),
+						    TRUE);
+	
+	gtk_source_view_set_show_line_numbers (GTK_SOURCE_VIEW (dlg->priv->view),
+					       TRUE);
+	
+	gtk_source_view_set_show_right_margin (GTK_SOURCE_VIEW (dlg->priv->view),
+					       TRUE);
+}
+
+static void
+gtranslator_viewer_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_viewer_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_viewer_class_init (GtranslatorViewerClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorViewerPrivate));
+
+	object_class->finalize = gtranslator_viewer_finalize;
+}
+
+/***************** File loading *****************/
+
+static void
+error_dialog (GtkWindow *parent, const gchar *msg, ...)
+{
+	va_list ap;
+	gchar *tmp;
+	GtkWidget *dialog;
+
+	va_start (ap, msg);
+	tmp = g_strdup_vprintf (msg, ap);
+	va_end (ap);
+
+	dialog = gtk_message_dialog_new (parent,
+					 GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_ERROR,
+					 GTK_BUTTONS_OK,
+					 tmp);
+	g_free (tmp);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+}
+
+static gboolean
+gtk_source_buffer_load_file (GtkSourceBuffer *source_buffer,
+			     const gchar     *filename,
+			     GError         **error)
+{
+	GtkTextIter iter;
+	gchar *buffer;
+	GError *error_here = NULL;
+
+	g_return_val_if_fail (GTK_IS_SOURCE_BUFFER (source_buffer), FALSE);
+	g_return_val_if_fail (filename != NULL, FALSE);
+
+	if (!g_file_get_contents (filename, &buffer, NULL, &error_here))
+	{
+		error_dialog (NULL, "%s\nFile %s", error_here->message, filename);
+		g_propagate_error (error, error_here);
+		return FALSE;
+	}
+
+	gtk_source_buffer_begin_not_undoable_action (source_buffer);
+	gtk_text_buffer_set_text (GTK_TEXT_BUFFER (source_buffer), buffer, -1);
+	gtk_source_buffer_end_not_undoable_action (source_buffer);
+	gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (source_buffer), FALSE);
+
+	/* move cursor to the beginning */
+	gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (source_buffer), &iter);
+	gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (source_buffer), &iter);
+
+	{
+		GtkTextIter start, end;
+		char *text;
+		gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (source_buffer), &start, &end);
+		text = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (source_buffer), &start, &end, TRUE);
+		g_assert (!strcmp (text, buffer));
+		g_free (text);
+	}
+
+	g_free (buffer);
+	return TRUE;
+}
+
+static void
+remove_all_marks (GtkSourceBuffer *buffer)
+{
+	GtkTextIter s, e;
+
+	gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &s, &e);
+
+	gtk_source_buffer_remove_source_marks (buffer, &s, &e, NULL);
+}
+
+/* Note this is wrong for several reasons, e.g. g_pattern_match is broken
+ * for glob matching. */
+static GtkSourceLanguage *
+get_language_for_filename (const gchar *filename)
+{
+	const gchar * const *languages;
+	gchar *filename_utf8;
+	GtkSourceLanguageManager *manager;
+
+	filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
+	g_return_val_if_fail (filename_utf8 != NULL, NULL);
+
+	manager = gtk_source_language_manager_get_default ();
+	languages = gtk_source_language_manager_get_language_ids (manager);
+
+	while (*languages != NULL)
+	{
+		GtkSourceLanguage *lang;
+		gchar **globs, **p;
+
+		lang = gtk_source_language_manager_get_language (manager,
+								 *languages);
+		g_return_val_if_fail (GTK_IS_SOURCE_LANGUAGE (lang), NULL);
+		++languages;
+
+		globs = gtk_source_language_get_globs (lang);
+		if (globs == NULL)
+			continue;
+
+		for (p = globs; *p != NULL; p++)
+		{
+			if (g_pattern_match_simple (*p, filename_utf8))
+			{
+				g_strfreev (globs);
+				g_free (filename_utf8);
+
+				return lang;
+			}
+		}
+
+		g_strfreev (globs);
+	}
+
+	g_free (filename_utf8);
+	return NULL;
+}
+
+static GtkSourceLanguage *
+get_language_for_file (const gchar *filename)
+{
+	GtkSourceLanguage *language = NULL;
+
+	if (!language)
+		language = get_language_for_filename (filename);
+
+	return language;
+}
+
+static GtkSourceLanguage *
+get_language_by_id (const gchar *id)
+{
+	GtkSourceLanguageManager *manager;
+	manager = gtk_source_language_manager_get_default ();
+	return gtk_source_language_manager_get_language (manager, id);
+}
+
+static GtkSourceLanguage *
+get_language (GtkTextBuffer *buffer, const gchar *filename)
+{
+	GtkSourceLanguage *language = NULL;
+	GtkTextIter start, end;
+	gchar *text;
+	gchar *lang_string;
+
+	gtk_text_buffer_get_start_iter (buffer, &start);
+	end = start;
+	gtk_text_iter_forward_line (&end);
+
+#define LANG_STRING "gtk-source-lang:"
+	text = gtk_text_iter_get_slice (&start, &end);
+	lang_string = strstr (text, LANG_STRING);
+	if (lang_string != NULL)
+	{
+		gchar **tokens;
+
+		lang_string += strlen (LANG_STRING);
+		g_strchug (lang_string);
+
+		tokens = g_strsplit_set (lang_string, " \t\n", 2);
+
+		if (tokens != NULL && tokens[0] != NULL)
+			language = get_language_by_id (tokens[0]);
+
+		g_strfreev (tokens);
+	}
+
+	if (!language)
+		language = get_language_for_file (filename);
+
+	g_free (text);
+	return language;
+}
+
+static gboolean
+open_file (GtkSourceBuffer *buffer, const gchar *filename)
+{
+	GtkSourceLanguage *language = NULL;
+	gchar *freeme = NULL;
+	gboolean success = FALSE;
+	GFile *file;
+	gchar *path;
+	
+	file = g_file_new_for_path (filename);
+	path = g_file_get_path (file);
+	g_object_unref (file);
+	
+	remove_all_marks (buffer);
+
+	success = gtk_source_buffer_load_file (buffer, path, NULL);
+
+	if (!success)
+		goto out;
+
+	language = get_language (GTK_TEXT_BUFFER (buffer), filename);
+
+	if (language == NULL)
+		g_print ("No language found for file `%s'\n", filename);
+
+	gtk_source_buffer_set_language (buffer, language);
+	g_object_set_data_full (G_OBJECT (buffer),
+				"filename", g_strdup (filename),
+				(GDestroyNotify) g_free);
+
+	if (language != NULL)
+	{
+		gchar **styles;
+
+		styles = gtk_source_language_get_style_ids (language);
+
+		if (styles == NULL)
+			g_print ("No styles in language '%s'\n", gtk_source_language_get_name (language));
+		else
+		{
+			gchar **ids;
+			g_print ("Styles in in language '%s':\n", gtk_source_language_get_name (language));
+
+			ids = styles;
+
+			while (*ids != NULL)
+			{
+				const gchar *name;
+
+				name = gtk_source_language_get_style_name (language, *ids);
+
+				g_print ("- %s (name: '%s')\n", *ids, name);
+
+				++ids;
+			}
+
+			g_strfreev (styles);
+		}
+
+		g_print("\n");
+	}
+out:
+	g_free (freeme);
+	return success;
+}
+
+static void
+jump_to_line (GtkTextView *view,
+	      gint line)
+{
+	GtkTextBuffer *buffer;
+	GtkTextIter iter;
+	gint line_count;
+	
+	buffer = gtk_text_view_get_buffer (view);
+	
+	line_count = gtk_text_buffer_get_line_count (buffer);
+
+	if (line >= line_count)
+		gtk_text_buffer_get_end_iter (buffer,
+					      &iter);
+	else
+		gtk_text_buffer_get_iter_at_line (buffer,
+						  &iter,
+						  line-1);
+
+	gtk_text_buffer_place_cursor (buffer, &iter);
+	
+	gtk_text_view_scroll_to_mark (view,
+				      gtk_text_buffer_get_insert (buffer),
+				      0.25,
+				      FALSE,
+				      0.0,
+				      0.0);
+}
+
+void
+gtranslator_show_viewer (GtranslatorWindow *window,
+			 const gchar *path,
+			 gint line)
+{
+	static GtranslatorViewer *dlg = NULL;
+	
+	g_return_if_fail (GTR_IS_WINDOW (window));
+	
+	if (dlg == NULL)
+	{
+		GtkSourceBuffer *buffer;
+		
+		dlg = g_object_new (GTR_TYPE_VIEWER, NULL);
+
+		buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (dlg->priv->view)));
+		
+		open_file (buffer, path);
+		jump_to_line (GTK_TEXT_VIEW (dlg->priv->view), line);
+		
+		g_signal_connect (dlg,
+				  "destroy",
+				  G_CALLBACK (gtk_widget_destroyed),
+				  &dlg);
+		gtk_widget_show (GTK_WIDGET (dlg));
+	}
+	
+	if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (dlg)))
+	{
+		gtk_window_set_transient_for (GTK_WINDOW (dlg),
+					      GTK_WINDOW (window));
+	}
+
+	gtk_window_present (GTK_WINDOW (dlg));
+}

Added: trunk/plugins/source-code-view/viewer.glade
==============================================================================
--- (empty file)
+++ trunk/plugins/source-code-view/viewer.glade	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Fri Jun 27 10:41:35 2008 -->
+<glade-interface>
+  <widget class="GtkDialog" id="dialog1">
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="main_box">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Source code&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkScrolledWindow" id="scrolledwindow">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                <property name="shadow_type">GTK_SHADOW_IN</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-close</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

Added: trunk/plugins/source-code-view/viewer.h
==============================================================================
--- (empty file)
+++ trunk/plugins/source-code-view/viewer.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __VIEWER_H__
+#define __VIEWER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "window.h"
+#include "msg.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_VIEWER		(gtranslator_viewer_get_type ())
+#define GTR_VIEWER(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_VIEWER, GtranslatorViewer))
+#define GTR_VIEWER_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_VIEWER, GtranslatorViewerClass))
+#define GTR_IS_VIEWER(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_VIEWER))
+#define GTR_IS_VIEWER_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_VIEWER))
+#define GTR_VIEWER_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_VIEWER, GtranslatorViewerClass))
+
+/* Private structure type */
+typedef struct _GtranslatorViewerPrivate	GtranslatorViewerPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorViewer		GtranslatorViewer;
+
+struct _GtranslatorViewer
+{
+	GtkDialog parent_instance;
+	
+	/*< private > */
+	GtranslatorViewerPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorViewerClass	GtranslatorViewerClass;
+
+struct _GtranslatorViewerClass
+{
+	GtkDialogClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_viewer_get_type               (void) G_GNUC_CONST;
+
+GType		 gtranslator_viewer_register_type          (GTypeModule * module);
+
+void	         gtranslator_show_viewer                   (GtranslatorWindow *window,
+							    const gchar *path,
+							    gint line);
+
+G_END_DECLS
+
+#endif /* __VIEWER_H__ */

Added: trunk/plugins/subversion/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,105 @@
+# FullScreen plugin
+plugindir = $(libdir)/gtranslator/plugins
+
+INCLUDES = \
+	-I$(top_srcdir) 				\
+	-I$(top_srcdir)/src				\
+	-I$(top_srcdir)/src/plugin-system		\
+	-I$(top_srcdir)/src/dialogs			\
+	-DDATADIR=\""$(pkgdatadir)"\"                   \
+	$(GTRANSLATOR_CFLAGS) 				\
+	$(SVN_CFLAGS)					\
+        $(SVN_INCLUDE)					\
+	$(WARN_CFLAGS)					\
+	$(DISABLE_DEPRECATED_CFLAGS)			\
+	-DGTR_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"
+
+plugin_LTLIBRARIES = \
+	libsubversion.la
+
+BUILT_SOURCES = \
+	subversion-enum-types.h \
+	subversion-enum-types.c
+
+NOINST_H_FILES = \
+	subversion-plugin.h \
+	command.h \
+	async-command.h \
+	svn-command.h \
+	svn-commit-command.h \
+	svn-update-command.h \
+	svn-add-command.h \
+	svn-status-command.h \
+	svn-status.h \
+	commit-dialog.h \
+	vcs-status-tree-view.h \
+	subversion-utils.h \
+	svn-diff-command.h \
+	svn-resolve-command.h \
+	svn-cat-command.h \
+	svn-checkout-command.h \
+	update-dialog.h \
+	diff-dialog.h \
+	checkout-dialog.h
+
+libsubversion_la_SOURCES = \
+	$(BUILT_SOURCES) \
+	subversion-plugin.c \
+	command.c \
+	async-command.c \
+	svn-command.c \
+	svn-commit-command.c \
+	svn-update-command.c \
+	svn-add-command.c \
+	svn-status-command.c \
+	svn-status.c \
+	commit-dialog.c \
+	vcs-status-tree-view.c \
+	subversion-utils.c \
+	svn-diff-command.c \
+	svn-resolve-command.c \
+	update-dialog.c \
+	svn-cat-command.c \
+	svn-checkout-command.c \
+	diff-dialog.c \
+	checkout-dialog.c \
+	$(NOINST_H_FILES)
+
+libsubversion_la_LDFLAGS = \
+	$(PLUGIN_LIBTOOL_FLAGS)				\
+	$(GTRANSLATOR_LIBS)				\
+	$(SVN_LIB)
+
+gladedir = $(pkgdatadir)
+
+glade_DATA =  \
+	subversion.glade
+
+pixmaps_dir = $(datadir)/pixmaps/gtranslator
+pixmaps__DATA = \
+	subversion-icon.png
+
+subversion-enum-types.h: subversion-enum-types.h.template $(NOINST_H_FILES) $(GLIB_MKENUMS)
+	(cd $(srcdir) && $(GLIB_MKENUMS) --template subversion-enum-types.h.template $(NOINST_H_FILES)) > $@
+
+subversion-enum-types.c: subversion-enum-types.c.template $(NOINST_H_FILES) $(GLIB_MKENUMS)
+	(cd $(srcdir) && $(GLIB_MKENUMS) --template subversion-enum-types.c.template $(NOINST_H_FILES)) > $@
+
+# Plugin Info
+
+plugin_in_files = subversion.gtranslator-plugin.desktop.in
+
+%.gtranslator.plugin: %.gtranslator-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.gtranslator-plugin.desktop.in=.gtranslator.plugin)
+
+EXTRA_DIST =	\
+	$(glade_DATA)	\
+	$(pixmaps__DATA)	\
+	$(plugin_in_files)	\
+	subversion-enum-types.h.template \
+	subversion-enum-types.c.template	
+
+CLEANFILES = $(plugin_DATA) $(BUILT_SOURCES)
+DISTCLEANFILES = $(plugin_DATA)
+

Added: trunk/plugins/subversion/async-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/async-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,205 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "async-command.h"
+
+/**
+ * SECTION: gtranslator-async-command
+ * @short_description: #GtranslatorCommand subclass that serves as the base for 
+ *					   commands that need to run in another thread.
+ * @include: libgtranslator/gtranslator-async-command.h
+ *
+ * #GtranslatorAsyncCommand provides a simple way for plugins to run tasks that 
+ * are synchronous and usually take several seconds or longer to execute in 
+ * another thread so that such tasks do no block Gtranslator's user interface.
+ *
+ * #GtranslatorAsyncCommand automatically runs and manages the thread when the 
+ * command starts, and destroys it when the command finishes. Aside from 
+ * locking protected data with gtranslator_async_command_lock/unlock, clients, and
+ * even commands themselves need not even be concerned that their tasks are 
+ * rnning on another thread.
+ *
+ * For an example of how #GtranslatorAsyncCommand is used, see the Subversion plugin.
+ */
+
+struct _GtranslatorAsyncCommandPriv
+{
+	GMutex *mutex;
+	guint return_code;
+	gboolean complete;
+	gboolean new_data_arrived;
+};
+
+G_DEFINE_TYPE (GtranslatorAsyncCommand, gtranslator_async_command, GTR_TYPE_COMMAND);
+
+static void
+gtranslator_async_command_init (GtranslatorAsyncCommand *self)
+{
+	self->priv = g_new0 (GtranslatorAsyncCommandPriv, 1);
+	
+	self->priv->mutex = g_mutex_new ();
+}
+
+static void
+gtranslator_async_command_finalize (GObject *object)
+{
+	GtranslatorAsyncCommand *self;
+	
+	self = GTR_ASYNC_COMMAND (object);
+	
+	g_mutex_free (self->priv->mutex);
+	g_idle_remove_by_data (self);
+	
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (gtranslator_async_command_parent_class)->finalize (object);
+}
+
+static gboolean
+gtranslator_async_command_notification_poll (GtranslatorCommand *command)
+{
+	GtranslatorAsyncCommand *self;
+	
+	self = GTR_ASYNC_COMMAND (command);
+	
+	if (self->priv->new_data_arrived &&
+		g_mutex_trylock (self->priv->mutex))
+	{
+		g_signal_emit_by_name (command, "data-arrived");
+		g_mutex_unlock (self->priv->mutex);
+		self->priv->new_data_arrived = FALSE;
+	}
+	
+	if (self->priv->complete)
+	{
+		g_signal_emit_by_name (command, "command-finished", 
+							   self->priv->return_code);
+		return FALSE;
+	}
+	else
+		return TRUE;
+	
+}
+
+static gpointer
+gtranslator_async_command_thread (GtranslatorCommand *command)
+{
+	guint return_code;
+	
+	return_code = GTR_COMMAND_GET_CLASS (command)->run (command);
+	gtranslator_command_notify_complete (command, return_code);
+	return NULL;
+}
+
+static void
+start_command (GtranslatorCommand *command)
+{
+	g_idle_add ((GSourceFunc) gtranslator_async_command_notification_poll, 
+				command);
+	g_thread_create ((GThreadFunc) gtranslator_async_command_thread, 
+					 command, FALSE, NULL);
+}
+
+static void
+notify_data_arrived (GtranslatorCommand *command)
+{
+	GtranslatorAsyncCommand *self;
+	
+	self = GTR_ASYNC_COMMAND (command);
+	
+	self->priv->new_data_arrived = TRUE;
+}
+
+static void
+notify_complete (GtranslatorCommand *command, guint return_code)
+{
+	GtranslatorAsyncCommand *self;
+	
+	self = GTR_ASYNC_COMMAND (command);
+	
+	self->priv->complete = TRUE;
+	self->priv->return_code = return_code;
+}
+
+static void
+gtranslator_async_command_class_init (GtranslatorAsyncCommandClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass* parent_class = GTR_COMMAND_CLASS (klass);
+
+	object_class->finalize = gtranslator_async_command_finalize;
+	
+	parent_class->start = start_command;
+	parent_class->notify_data_arrived = notify_data_arrived;
+	parent_class->notify_complete = notify_complete;
+}
+
+void
+gtranslator_async_command_set_error_message (GtranslatorCommand *command, 
+										gchar *error_message)
+{
+	gtranslator_async_command_lock (GTR_ASYNC_COMMAND (command));
+	GTR_COMMAND_GET_CLASS (command)->set_error_message (command, 
+														   error_message);
+	gtranslator_async_command_unlock (GTR_ASYNC_COMMAND (command));
+}
+
+gchar *
+gtranslator_async_command_get_error_message (GtranslatorCommand *command)
+{
+	gchar *error_message;
+	
+	gtranslator_async_command_lock (GTR_ASYNC_COMMAND (command));
+	error_message = GTR_COMMAND_GET_CLASS (command)->get_error_message (command);
+	gtranslator_async_command_unlock (GTR_ASYNC_COMMAND (command));
+	
+	return error_message;
+}
+
+/**
+ * gtranslator_async_command_lock:
+ * @self: GtranslatorAsyncCommand object.
+ *
+ * Locks the command's built-in mutex.
+ */
+void
+gtranslator_async_command_lock (GtranslatorAsyncCommand *self)
+{
+	g_mutex_lock (self->priv->mutex);
+}
+
+/**
+ * gtranslator_async_command_unlock:
+ * @self: GtranslatorAsyncCommand object.
+ *
+ * Unlocks the command's built-in mutex.
+ */
+void
+gtranslator_async_command_unlock (GtranslatorAsyncCommand *self)
+{
+	g_mutex_unlock (self->priv->mutex);
+}

Added: trunk/plugins/subversion/async-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/async-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,70 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _GTR_ASYNC_COMMAND_H_
+#define _GTR_ASYNC_COMMAND_H_
+
+#include <glib-object.h>
+#include "command.h"
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_ASYNC_COMMAND             (gtranslator_async_command_get_type ())
+#define GTR_ASYNC_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTR_TYPE_ASYNC_COMMAND, GtranslatorAsyncCommand))
+#define GTR_ASYNC_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTR_TYPE_ASYNC_COMMAND, GtranslatorAsyncCommandClass))
+#define IS_GTR_ASYNC_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTR_TYPE_ASYNC_COMMAND))
+#define IS_GTR_ASYNC_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_ASYNC_COMMAND))
+#define GTR_ASYNC_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTR_TYPE_ASYNC_COMMAND, GtranslatorAsyncCommandClass))
+
+typedef struct _GtranslatorAsyncCommandClass GtranslatorAsyncCommandClass;
+typedef struct _GtranslatorAsyncCommand GtranslatorAsyncCommand;
+typedef struct _GtranslatorAsyncCommandPriv GtranslatorAsyncCommandPriv;
+
+struct _GtranslatorAsyncCommandClass
+{
+	GtranslatorCommandClass parent_class;
+};
+
+struct _GtranslatorAsyncCommand
+{
+	GtranslatorCommand parent_instance;
+	
+	GtranslatorAsyncCommandPriv *priv;
+};
+
+GType gtranslator_async_command_get_type (void) G_GNUC_CONST;
+
+void gtranslator_async_command_set_error_message (GtranslatorCommand *command, 
+											 gchar *error_message);
+gchar *gtranslator_async_command_get_error_message (GtranslatorCommand *command);
+
+void gtranslator_async_command_lock (GtranslatorAsyncCommand *self);
+void gtranslator_async_command_unlock (GtranslatorAsyncCommand *self);
+
+G_END_DECLS
+
+#endif /* _GTR_ASYNC_COMMAND_H_ */

Added: trunk/plugins/subversion/checkout-dialog.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/checkout-dialog.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "checkout-dialog.h"
+#include "subversion-plugin.h"
+#include "svn-checkout-command.h"
+#include "utils.h"
+#include "svn-command.h"
+#include "statusbar.h"
+#include "subversion-utils.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+
+#define GTR_CHECKOUT_DIALOG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 	(object),	\
+						 	GTR_TYPE_CHECKOUT_DIALOG,     \
+						 	GtranslatorCheckoutDialogPrivate))
+
+
+G_DEFINE_TYPE(GtranslatorCheckoutDialog, gtranslator_checkout_dialog, GTK_TYPE_DIALOG)
+
+struct _GtranslatorCheckoutDialogPrivate
+{
+	GtkWidget *main_box;
+	GtkWidget *path_entry;
+	GtkWidget *dir_find_button;
+	GtkWidget *url_entry;
+	
+	GtkListStore *store;
+	GtkWidget *checkout_treeview;
+	
+	GtranslatorWindow *window;
+};
+
+enum 
+{
+	ICON_COLUMN,
+	TEXT_COLUMN,
+	N_COLUMNS
+};
+
+static void
+on_checkout_command_finished (GtranslatorCommand *command,
+			    guint return_code,
+			    GtranslatorCheckoutDialog *dlg)
+{
+	GtranslatorStatusbar *status;
+	
+	status = GTR_STATUSBAR (gtranslator_window_get_statusbar (dlg->priv->window));
+	
+	gtranslator_statusbar_flash_message (status, 0,
+					     _("Subversion: Checkout complete."));
+	
+	subversion_utils_report_errors (dlg->priv->window, 
+					command, return_code);
+	
+	svn_checkout_command_destroy (SVN_CHECKOUT_COMMAND (command));	
+}
+
+static void
+on_checkout_command_info_arrived (GtranslatorCommand *command,
+				GtranslatorCheckoutDialog *dlg)
+{
+	GQueue *info;
+	gchar *message;
+	GtkTreeIter iter;
+	
+	info = svn_command_get_info_queue (SVN_COMMAND (command));
+	
+	while (g_queue_peek_head (info))
+	{
+		message = g_queue_pop_head (info);
+		
+		gtk_list_store_append (dlg->priv->store, &iter);
+		gtk_list_store_set (dlg->priv->store, &iter,
+				    TEXT_COLUMN, message,
+				    -1);
+		
+		g_free (message);
+	}
+}
+
+static void
+dialog_response_handler (GtranslatorCheckoutDialog *dlg, 
+			 gint       res_id)
+{
+	switch (res_id)
+	{
+		case GTK_RESPONSE_APPLY:
+		{
+			const gchar *path, *url;
+			SvnCheckoutCommand *checkout_command;
+			
+			path = gtk_entry_get_text (GTK_ENTRY (dlg->priv->path_entry));
+			if (strcmp ("", path) == 0)
+			{
+				GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (dlg->priv->window),
+									    GTK_DIALOG_DESTROY_WITH_PARENT,
+									    GTK_MESSAGE_WARNING,
+									    GTK_BUTTONS_CLOSE,
+									    _("Please, add a directory path to make the checkout"));
+				gtk_dialog_run (GTK_DIALOG (dialog));
+				gtk_widget_destroy (dialog);
+				break;
+			}
+			
+			url = gtk_entry_get_text (GTK_ENTRY (dlg->priv->url_entry));
+			if (strcmp ("", url) == 0)
+			{
+				GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (dlg->priv->window),
+									    GTK_DIALOG_DESTROY_WITH_PARENT,
+									    GTK_MESSAGE_WARNING,
+									    GTK_BUTTONS_CLOSE,
+									    _("Please, add a Subversion URL"));
+				gtk_dialog_run (GTK_DIALOG (dialog));
+				gtk_widget_destroy (dialog);
+				break;
+			}
+
+			checkout_command = svn_checkout_command_new (url, path);
+			
+			gtk_list_store_clear (dlg->priv->store);
+			
+			g_signal_connect (G_OBJECT (checkout_command), "command-finished",
+					  G_CALLBACK (on_checkout_command_finished),
+					  dlg);
+			
+			g_signal_connect (G_OBJECT (checkout_command), "data-arrived",
+					  G_CALLBACK (on_checkout_command_info_arrived),
+					  dlg);
+
+			gtranslator_command_start (GTR_COMMAND (checkout_command));
+
+			break;
+		}
+		default:
+			gtk_widget_hide (GTK_WIDGET (dlg));
+	}
+}
+
+static void
+on_dir_find_button_clicked (GtkButton *button,
+			    GtranslatorCheckoutDialog *dlg)
+{
+	GtkWidget *dialog;
+	gint res;
+	
+	dialog = gtk_file_chooser_dialog_new (_("Checkout directory"),
+					      GTK_WINDOW (dlg->priv->window),
+					      GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
+					      GTK_STOCK_CANCEL,
+					      GTK_RESPONSE_CANCEL,
+					      GTK_STOCK_OK,
+					      GTK_RESPONSE_OK,
+					      NULL);
+	res = gtk_dialog_run (GTK_DIALOG (dialog));
+	switch (res)
+	{
+		case GTK_RESPONSE_OK: 
+		{
+			gchar *filename;
+			
+			filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+			gtk_entry_set_text (GTK_ENTRY (dlg->priv->path_entry),
+					    filename);
+			g_free (filename);
+			break;
+		}
+		default:
+			break;
+	}
+	gtk_widget_destroy (dialog);
+}
+
+static void
+setup_treeview (GtranslatorCheckoutDialog *dlg)
+{
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+	
+	dlg->priv->store = gtk_list_store_new (N_COLUMNS,
+					       GDK_TYPE_PIXBUF,
+					       G_TYPE_STRING);
+	
+	gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->checkout_treeview),
+				 GTK_TREE_MODEL (dlg->priv->store));
+	
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (dlg->priv->checkout_treeview),
+					   FALSE);
+	
+	column = gtk_tree_view_column_new ();
+	/*
+	 * Icon column
+	 */
+	renderer = gtk_cell_renderer_pixbuf_new ();
+	g_object_set (renderer,
+		      "stock-id", GTK_STOCK_INFO,
+		      "stock-size", GTK_ICON_SIZE_MENU,
+		      "xalign", 1.0,
+		      "xpad", 6,
+		      NULL);
+
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	
+	/*
+	 * Text column
+	 */
+	
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_set_attributes (column,
+					     renderer,
+					     "text", TEXT_COLUMN,
+					     NULL);
+
+	gtk_tree_view_column_set_resizable (column, FALSE);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->checkout_treeview),
+				     column);
+}
+
+static void
+gtranslator_checkout_dialog_init (GtranslatorCheckoutDialog *dlg)
+{
+	gboolean ret;
+	GtkWidget *error_widget;
+	
+	dlg->priv = GTR_CHECKOUT_DIALOG_GET_PRIVATE (dlg);
+	
+	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
+				GTK_STOCK_REFRESH,
+				GTK_RESPONSE_APPLY,
+				GTK_STOCK_CLOSE,
+				GTK_RESPONSE_CLOSE,
+				NULL);
+	
+	gtk_window_set_title (GTK_WINDOW (dlg), _("Checkout repository"));
+	gtk_window_set_default_size (GTK_WINDOW (dlg), 600, 600);
+	gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
+	
+	/* HIG defaults */
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 2); /* 2 * 5 + 2 = 12 */
+	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 4);
+	
+	g_signal_connect (dlg,
+			  "response",
+			  G_CALLBACK (dialog_response_handler),
+			  NULL);
+	
+	/*Glade*/
+	ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+		"checkout_main_box",
+		&error_widget,
+		
+		"checkout_main_box", &dlg->priv->main_box,
+		"path_entry", &dlg->priv->path_entry,
+		"dir_find_button", &dlg->priv->dir_find_button,
+		"url_entry", &dlg->priv->url_entry,
+		"checkout_treeview", &dlg->priv->checkout_treeview,
+		
+		NULL);
+	
+	if(!ret)
+	{
+		gtk_widget_show (error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+					     error_widget);
+		
+		return;
+	}
+	
+	setup_treeview (dlg);
+	
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+			    dlg->priv->main_box, TRUE, TRUE, 0);
+	
+	gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->main_box), 5);
+	
+	g_signal_connect (dlg->priv->dir_find_button, "clicked",
+			  G_CALLBACK (on_dir_find_button_clicked), dlg);
+}
+
+static void
+gtranslator_checkout_dialog_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_checkout_dialog_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_checkout_dialog_class_init (GtranslatorCheckoutDialogClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorCheckoutDialogPrivate));
+
+	object_class->finalize = gtranslator_checkout_dialog_finalize;
+}
+
+void
+gtranslator_show_checkout_dialog (GtranslatorWindow *window)
+{
+	static GtranslatorCheckoutDialog *dlg = NULL;
+	
+	g_return_if_fail (GTR_IS_WINDOW (window));
+	
+	if(dlg == NULL)
+	{
+		dlg = g_object_new (GTR_TYPE_CHECKOUT_DIALOG, NULL);
+		
+		gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg),
+						    TRUE);
+		
+		dlg->priv->window = window;
+		
+		g_signal_connect (dlg,
+				  "destroy",
+				  G_CALLBACK (gtk_widget_destroyed),
+				  &dlg);
+
+		gtk_widget_show (GTK_WIDGET (dlg));
+	}
+	
+	if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (dlg)))
+	{
+		gtk_window_set_transient_for (GTK_WINDOW (dlg),
+					      GTK_WINDOW (window));
+	}
+
+	gtk_window_present (GTK_WINDOW (dlg));
+}

Added: trunk/plugins/subversion/checkout-dialog.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/checkout-dialog.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __CHECKOUT_DIALOG_H__
+#define __CHECKOUT_DIALOG_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "window.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_CHECKOUT_DIALOG		(gtranslator_checkout_dialog_get_type ())
+#define GTR_CHECKOUT_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_CHECKOUT_DIALOG, GtranslatorCheckoutDialog))
+#define GTR_CHECKOUT_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_CHECKOUT_DIALOG, GtranslatorCheckoutDialogClass))
+#define GTR_IS_CHECKOUT_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_CHECKOUT_DIALOG))
+#define GTR_IS_CHECKOUT_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_CHECKOUT_DIALOG))
+#define GTR_CHECKOUT_DIALOG_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_CHECKOUT_DIALOG, GtranslatorCheckoutDialogClass))
+
+/* Private structure type */
+typedef struct _GtranslatorCheckoutDialogPrivate	GtranslatorCheckoutDialogPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorCheckoutDialog		GtranslatorCheckoutDialog;
+
+struct _GtranslatorCheckoutDialog
+{
+	GtkDialog parent_instance;
+	
+	/*< private > */
+	GtranslatorCheckoutDialogPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorCheckoutDialogClass	GtranslatorCheckoutDialogClass;
+
+struct _GtranslatorCheckoutDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_checkout_dialog_get_type               (void) G_GNUC_CONST;
+
+GType		 gtranslator_checkout_dialog_register_type          (GTypeModule * module);
+
+void	     gtranslator_show_checkout_dialog                   (GtranslatorWindow *window);
+
+G_END_DECLS
+
+#endif /* __CHECKOUT_DIALOG_H__ */

Added: trunk/plugins/subversion/command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,217 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "command.h"
+
+/**
+ * SECTION: gtranslator-command
+ * @short_description: System for creating objects that provide a standard 
+ *					   interface to external components (libraries, processes,
+ *					   etc.) 
+ * @see_also: #GtranslatorAsyncCommand
+ * @include libgtranslator/gtranslator-command.h
+ *
+ * #GtranslatorCommand is the base class for objects that are designed to provide 
+ * a layer of abstraction between UI code and some other component, like a 
+ * library or child process. GtranslatorCommand provides a simple and consistent
+ * interface for plugins to interact with these components without needing 
+ * to concern themselves with the exact details of how these components work.
+ * 
+ * To create command objects, plugins derive them from an #GtranslatorCommand 
+ * subclass like #GtranslatorAsyncCommand, which runs commands in another thread.
+ * These classes determine how ::run is called and how signals are emitted.
+ * ::run is responsible for actually doing the work of the command. It is the 
+ * responsiblity of the command object that does a certain task to implement 
+ * ::run to do its job. Everything else is normally implemented by its parent
+ * classes at this point
+ *
+ * For an example of how to use #GtranslatorCommand, see the Subversion plugin.
+ */
+
+struct _GtranslatorCommandPriv
+{
+	gchar *error_message;
+};
+
+enum
+{
+	DATA_ARRIVED,
+	COMMAND_FINISHED,
+
+	LAST_SIGNAL
+};
+
+
+static guint gtranslator_command_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GtranslatorCommand, gtranslator_command, G_TYPE_OBJECT);
+
+static void
+gtranslator_command_init (GtranslatorCommand *self)
+{
+	self->priv = g_new0 (GtranslatorCommandPriv, 1);
+}
+
+static void
+gtranslator_command_finalize (GObject *object)
+{
+	GtranslatorCommand *self;
+	
+	self = GTR_COMMAND (object);
+	
+	g_free (self->priv->error_message);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (gtranslator_command_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_command_class_init (GtranslatorCommandClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gtranslator_command_finalize;
+	
+	klass->run = NULL;
+	klass->start = NULL;
+	klass->notify_data_arrived = NULL;
+	klass->notify_complete = NULL;
+	klass->set_error_message = gtranslator_command_set_error_message;
+	klass->get_error_message = gtranslator_command_get_error_message;
+
+	/**
+	 * GtranslatorCommand::data-arrived:
+	 * @command: Command
+	 * 
+	 * Notifies clients that the command has processed data that is ready to 
+	 * be used.
+	 */
+	gtranslator_command_signals[DATA_ARRIVED] =
+		g_signal_new ("data-arrived",
+		              G_OBJECT_CLASS_TYPE (klass),
+		              G_SIGNAL_RUN_FIRST,
+		              0,
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__VOID,
+		              G_TYPE_NONE, 
+					  0);
+
+	/**
+	 * GtranslatorCommand::command-finished:
+	 * @command: Command
+	 * @return_code: The return code of the finished commmand
+	 *
+	 * Indicates that the command has completed. Clients should at least handle
+	 * this signal to unref the command object. 
+	 */
+	gtranslator_command_signals[COMMAND_FINISHED] =
+		g_signal_new ("command-finished",
+		              G_OBJECT_CLASS_TYPE (klass),
+		              G_SIGNAL_RUN_FIRST,
+		              0,
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__UINT ,
+		              G_TYPE_NONE, 1,
+		              G_TYPE_UINT);
+}
+
+/**
+ * gtranslator_command_start:
+ * @self: Command object to start
+ *
+ * Starts a command. Client code can handle data from the command by connecting
+ * to the ::data-arrived signal. 
+ *
+ * #GtranslatorCommand subclasses should override this method to determine how they
+ * call ::run, which actually does the command's legwork. 
+ */
+void
+gtranslator_command_start (GtranslatorCommand *self)
+{
+	GTR_COMMAND_GET_CLASS (self)->start (self);
+}
+
+
+/**
+ * gtranslator_command_notify_data_arrived:
+ * @self: Command object.
+ * 
+ * Used by base classes derived from #GtranslatorCommand to emit the ::data-arrived
+ * signal. This method should not be used by client code or #GtranslatorCommand 
+ * objects that are not base classes. 
+ */
+void
+gtranslator_command_notify_data_arrived (GtranslatorCommand *self)
+{
+	GTR_COMMAND_GET_CLASS (self)->notify_data_arrived (self);
+}
+
+/**
+ * gtranslator_command_notify_complete:
+ * @self: Command object.
+ * 
+ * Used by base classes derived from #GtranslatorCommand to emit the 
+ * ::command-finished signal. This method should not be used by client code or  
+ * #GtranslatorCommand objects that are not base classes. 
+ */
+void
+gtranslator_command_notify_complete (GtranslatorCommand *self, guint return_code)
+{
+	GTR_COMMAND_GET_CLASS (self)->notify_complete (self, return_code);
+}
+
+/**
+ * gtranslator_command_set_error_message:
+ * @self: Command object.
+ * @error_message: Error message.
+ * 
+ * Command objects use this to set error messages when they encounter some kind
+ * of failure. 
+ */
+void
+gtranslator_command_set_error_message (GtranslatorCommand *self, gchar *error_message)
+{
+	if (self->priv->error_message)
+		g_free (error_message);
+	
+	self->priv->error_message = g_strdup (error_message);
+}
+
+/**
+ * gtranslator_command_get_error_message:
+ * @self: Command object.
+ * @error_message: Error message.
+ * 
+ * Get the error message from the command, if there is one. This method is 
+ * normally used from a ::command-finished handler to report errors to the user
+ * when a command finishes. 
+ *
+ * Return value: Error message string that must be freed when no longer needed.
+ * If no error is set, return %NULL.
+ */
+gchar *
+gtranslator_command_get_error_message (GtranslatorCommand *self)
+{
+	return g_strdup (self->priv->error_message);
+}

Added: trunk/plugins/subversion/command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,75 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _GTR_COMMAND_H_
+#define _GTR_COMMAND_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_COMMAND             (gtranslator_command_get_type ())
+#define GTR_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTR_TYPE_COMMAND, GtranslatorCommand))
+#define GTR_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTR_TYPE_COMMAND, GtranslatorCommandClass))
+#define GTR_IS_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTR_TYPE_COMMAND))
+#define GTR_IS_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_COMMAND))
+#define GTR_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTR_TYPE_COMMAND, GtranslatorCommandClass))
+
+typedef struct _GtranslatorCommandClass GtranslatorCommandClass;
+typedef struct _GtranslatorCommand GtranslatorCommand;
+typedef struct _GtranslatorCommandPriv GtranslatorCommandPriv;
+
+struct _GtranslatorCommandClass
+{
+	GObjectClass parent_class;
+	
+	/* Virtual Methods */
+	guint (*run) (GtranslatorCommand *self);
+	void (*start) (GtranslatorCommand *self);
+	void (*notify_data_arrived) (GtranslatorCommand *self);
+	void (*notify_complete) (GtranslatorCommand *self, guint return_code);
+	void (*set_error_message) (GtranslatorCommand *self, gchar *error_message);
+	gchar * (*get_error_message) (GtranslatorCommand *self);
+
+};
+
+struct _GtranslatorCommand
+{
+	GObject parent_instance;
+	
+	GtranslatorCommandPriv *priv;
+};
+
+GType gtranslator_command_get_type (void) G_GNUC_CONST;
+
+void gtranslator_command_start (GtranslatorCommand *self);
+void gtranslator_command_notify_data_arrived (GtranslatorCommand *self);
+void gtranslator_command_notify_complete (GtranslatorCommand *self, guint return_code);
+
+void gtranslator_command_set_error_message (GtranslatorCommand *self, gchar *error_message);
+gchar *gtranslator_command_get_error_message (GtranslatorCommand *self);
+
+G_END_DECLS
+
+#endif /* _GTR_COMMAND_H_ */

Added: trunk/plugins/subversion/commit-dialog.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/commit-dialog.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,708 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based on anjuta subversion plugin.
+ *     Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "commit-dialog.h"
+#include "utils.h"
+#include "subversion-plugin.h"
+#include "svn-status-command.h"
+#include "vcs-status-tree-view.h"
+#include "svn-status.h"
+#include "subversion-utils.h"
+#include "statusbar.h"
+#include "svn-commit-command.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <gconf/gconf-client.h>
+#include <unistd.h>
+
+
+#define GTR_COMMIT_DIALOG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 	(object),	\
+						 	GTR_TYPE_COMMIT_DIALOG,     \
+						 	GtranslatorCommitDialogPrivate))
+
+#define ADD_CHANGE_LOG_KEY SUBVERSION_BASE_KEY "/add_change_log"
+
+G_DEFINE_TYPE(GtranslatorCommitDialog, gtranslator_commit_dialog, GTK_TYPE_DIALOG)
+
+struct _GtranslatorCommitDialogPrivate
+{
+	GConfClient *gconf_client;
+	
+	GtkWidget *main_box;
+	GtkWidget *changelog_view;
+	GtkWidget *status_view;
+	GtkWidget *select_all_button;
+	GtkWidget *clear_button;
+	GtkWidget *status_progress_bar;
+	GtkWidget *add_log_checkbutton;
+	
+	GtranslatorWindow *window;
+	gchar *dirname;
+};
+
+static void        send_status_command           (GtranslatorCommitDialog *dlg,
+						  GtranslatorWindow *window);
+
+static void
+select_all_status_items (GtkButton *select_all_button,
+			 GtranslatorVcsStatusTreeView *tree_view)
+{
+	gtranslator_vcs_status_tree_view_select_all (tree_view);
+}
+
+static void
+clear_all_status_selections (GtkButton *clear_button,
+			     GtranslatorVcsStatusTreeView *tree_view)
+{
+	gtranslator_vcs_status_tree_view_unselect_all (tree_view);
+}
+
+static gboolean
+pulse_timer (GtkProgressBar *progress_bar)
+{
+	gtk_progress_bar_pulse (progress_bar);
+	return TRUE;
+}
+
+static void
+stop_pulse_timer (gpointer timer_id, GtkProgressBar *progress_bar)
+{
+	g_source_remove (GPOINTER_TO_UINT (timer_id));
+}
+
+static void
+pulse_progress_bar (GtkProgressBar *progress_bar)
+{
+	guint timer_id;
+	
+	timer_id = g_timeout_add (100, (GSourceFunc) pulse_timer, 
+							  progress_bar);
+	g_object_set_data (G_OBJECT (progress_bar), "pulse-timer-id",
+					   GUINT_TO_POINTER (timer_id));
+	
+	g_object_weak_ref (G_OBJECT (progress_bar),
+					   (GWeakNotify) stop_pulse_timer,
+					   GUINT_TO_POINTER (timer_id));
+}
+
+static void
+hide_pulse_progress_bar (GtranslatorCommand *command,
+			 guint return_code,
+			 GtkProgressBar *progress_bar)
+{
+	guint timer_id;
+	
+	/* If the progress bar has already been destroyed, the timer should be 
+	 * stopped by stop_pulse_timer */
+	if (GTK_IS_PROGRESS_BAR (progress_bar))
+	{
+		timer_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (progress_bar),
+								"pulse-timer-id")); 
+		
+		g_source_remove (GPOINTER_TO_UINT (timer_id));
+		gtk_widget_hide (GTK_WIDGET (progress_bar));
+	}
+}
+
+static void
+select_all_files (GtranslatorCommand *command,
+		  guint return_code, 
+		  GtranslatorVcsStatusTreeView *status_view)
+{
+	gtranslator_vcs_status_tree_view_select_all (status_view);
+}
+
+/* This function is normally intended to disconnect stock data-arrived signal
+ * handlers in this file. It is assumed that object is the user data for the 
+ * callback. If you use any of the stock callbacks defined here, make sure 
+ * to weak ref its target with this callback. Make sure to cancel this ref
+ * by connecting cancel_data_arrived_signal_disconnect to the command-finished 
+ * signal so we don't try to disconnect signals on a destroyed command. */
+static void
+disconnect_data_arrived_signals (GtranslatorCommand *command,
+				 GObject *object)
+{
+	guint data_arrived_signal;
+	
+	if (GTR_IS_COMMAND (command))
+	{
+		data_arrived_signal = g_signal_lookup ("data-arrived",
+						       GTR_TYPE_COMMAND);
+		
+		g_signal_handlers_disconnect_matched (command,
+						      G_SIGNAL_MATCH_DATA,
+						      data_arrived_signal,
+						      0,
+						      NULL,
+						      NULL,
+						      object);
+	}
+										  
+}
+
+static void 
+cancel_data_arrived_signal_disconnect (GtranslatorCommand *command, 
+				       guint return_code,
+				       GObject *signal_target)
+{
+	g_object_weak_unref (signal_target, 
+			     (GWeakNotify) disconnect_data_arrived_signals,
+			     command);
+}
+
+static void
+on_status_command_finished (GtranslatorCommand *command,
+			    guint return_code, 
+			    GtranslatorWindow *window)
+{
+	subversion_utils_report_errors (window, command, return_code);
+	
+	svn_status_command_destroy (SVN_STATUS_COMMAND (command));
+}
+
+static void
+on_status_command_data_arrived (GtranslatorCommand *command, 
+				GtranslatorVcsStatusTreeView *tree_view)
+{
+	GQueue *status_queue;
+	SvnStatus *status;
+	gchar *path;
+
+	status_queue = svn_status_command_get_status_queue (SVN_STATUS_COMMAND (command));
+
+	while (g_queue_peek_head (status_queue))
+	{
+		status = g_queue_pop_head (status_queue);
+		path = svn_status_get_path (status);
+		
+		gtranslator_vcs_status_tree_view_add (tree_view, path, 
+						      svn_status_get_vcs_status (status),
+						      FALSE);
+		
+		svn_status_destroy (status);
+		g_free (path);
+	}
+}
+
+static void
+on_commit_command_finished (GtranslatorCommand *command,
+			    guint return_code,
+			    GtranslatorCommitDialog *dlg)
+{
+	GtranslatorStatusbar *status;
+	
+	g_return_if_fail (GTR_IS_WINDOW (dlg->priv->window));
+
+	status = GTR_STATUSBAR (gtranslator_window_get_statusbar (dlg->priv->window));
+	
+	gtranslator_statusbar_flash_message (status, 0,
+					     _("Subversion: Commit complete."));
+	
+	subversion_utils_report_errors (dlg->priv->window,
+					command, return_code);
+	
+	svn_commit_command_destroy (SVN_COMMIT_COMMAND (command));
+}
+
+static void
+on_command_info_arrived (GtranslatorCommand *command,
+			 GtranslatorWindow *window)
+{
+	GQueue *info;
+	gchar *message;
+	GtranslatorStatusbar *status;
+	
+	status = GTR_STATUSBAR (gtranslator_window_get_statusbar (window));
+	info = svn_command_get_info_queue (SVN_COMMAND (command));
+	
+	while (g_queue_peek_head (info))
+	{
+		message = g_queue_pop_head (info);
+		gtranslator_statusbar_flash_message (status, 0,
+						     message);
+		g_free (message);
+	}
+}
+
+static void
+add_changelog_to_text_view (GtkWidget *textview)
+{
+	gchar *log;
+	GtkTextBuffer *buf;
+	
+	buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
+	
+	log = g_strdup_printf ("Updated %s translation",
+	/*
+	 * Translators: Please change LANGUAGE for your language name in ENGLISH.
+	 * This string is used to fill the ChangeLog entry
+	 */
+			       C_("ChangeLog entry", "LANGUAGE"));
+	
+	gtk_text_buffer_set_text (buf, log, -1);
+	g_free (log);
+}
+
+static void
+add_changelog_entry (GtranslatorCommitDialog *dlg)
+{
+	guint tmpfd;
+	GError *error = NULL;
+	gchar *tmp_fname;
+	GFile *tmp_file;
+	gchar *changelog;
+	GFile *changelog_file;
+	GFileInputStream *istream;
+	GFileOutputStream *ostream;
+	gchar *changelog_entry;
+	
+	changelog = g_build_filename (dlg->priv->dirname,
+				      "ChangeLog",
+				      NULL);
+	
+	changelog_file = g_file_new_for_path (changelog);
+	if (!g_file_query_exists (changelog_file, NULL))
+	{
+		g_warning (_("The ChangeLog file '%s' does not exists"),
+			   changelog);
+		g_free (changelog);
+		g_object_unref (changelog_file);
+		return;
+	}
+	g_free (changelog);
+	
+	tmpfd = g_file_open_tmp (".gtranslator-changelog-XXXXXX",
+				 &tmp_fname,
+				 &error);
+	
+	if (tmpfd == -1)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+		g_object_unref (changelog_file);
+		
+		/* In this case we don't have to close the file */
+		return;
+	}
+	
+	tmp_file = g_file_new_for_path (tmp_fname);
+	
+	istream = g_file_read (changelog_file, NULL, &error);
+	if (error)
+		goto free;
+	
+	ostream = g_file_append_to (tmp_file, G_FILE_CREATE_NONE,
+				    NULL, &error);
+	if (error)
+		goto free;
+	
+	/*
+	 * We move the current ChangeLog file to the temp file
+	 */
+	subversion_utils_from_file_to_file (G_INPUT_STREAM (istream),
+					    G_OUTPUT_STREAM (ostream));
+	
+	/*
+	 * Then we remove the old changelog_file
+	 */
+	g_file_delete (changelog_file, NULL, &error);
+	if (error)
+		goto free;
+	
+	/*
+	 * We create the new one
+	 */
+	ostream = g_file_create (changelog_file, G_FILE_CREATE_NONE,
+				 NULL, &error);
+	if (error)
+		goto free;
+
+	/*
+	 * Now, adding the new changelog entry
+	 */
+	changelog_entry = subversion_utils_get_changelog_entry_from_view (dlg->priv->changelog_view);
+	
+	g_output_stream_write (G_OUTPUT_STREAM (ostream), changelog_entry,
+			       g_utf8_strlen (changelog_entry, -1),
+			       NULL, &error);
+	if (error)
+		goto free;
+	
+	istream = g_file_read (tmp_file, NULL, &error);
+	if (error)
+		goto free;
+	
+	/* Now, appending from tempfile to ChangeLog file */
+	subversion_utils_from_file_to_file (G_INPUT_STREAM (istream),
+					    G_OUTPUT_STREAM (ostream));
+
+	/*
+	 * Updating the dialog
+	 */
+	gtranslator_vsc_status_tree_view_clear (GTR_VCS_STATUS_TREE_VIEW (dlg->priv->status_view));
+	send_status_command (dlg, dlg->priv->window);
+	
+free:   if (error)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+	}
+	g_object_unref (tmp_file);
+	close (tmpfd);
+	g_free (tmp_fname);
+	g_object_unref (changelog_file);
+}
+
+static void
+dialog_response_handler (GtkDialog *dlg, 
+			 gint       res_id)
+{
+	GtranslatorCommitDialog *commit = GTR_COMMIT_DIALOG (dlg);
+	
+	switch (res_id)
+	{
+		case GTK_RESPONSE_OK:
+		{
+			gchar* log = NULL;
+			GList *selected_paths;
+			SvnCommitCommand *commit_command;
+			//guint pulse_timer_id;
+			
+			log = subversion_utils_get_log_from_textview (commit->priv->changelog_view);
+			if (!g_utf8_strlen (log, -1))
+			{
+				gint result;
+				GtkWidget* dialog = gtk_message_dialog_new (GTK_WINDOW (commit->priv->window), 
+									    GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO,
+									    GTK_BUTTONS_YES_NO, 
+									    _("Are you sure that you want to pass an empty log message?"));
+				result = gtk_dialog_run (GTK_DIALOG (dialog));
+				gtk_widget_destroy (dialog);
+				if (result == GTK_RESPONSE_NO)
+				{
+					g_free (log);
+					break;
+				}
+			}
+			
+			selected_paths = gtranslator_vcs_status_tree_view_get_selected (GTR_VCS_STATUS_TREE_VIEW (commit->priv->status_view));
+
+			if (selected_paths == NULL)
+			{
+				GtkWidget* dialog = gtk_message_dialog_new (GTK_WINDOW (commit->priv->window), 
+									    GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO,
+									    GTK_BUTTONS_CLOSE, 
+									    _("You have to select at least one file to send"));
+				gtk_dialog_run (GTK_DIALOG (dialog));
+				gtk_widget_destroy (dialog);
+				g_free (log);
+				break;
+			}
+			
+			if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (commit->priv->add_log_checkbutton)))
+			{
+				gchar *changelog_path;
+				
+				add_changelog_entry (commit);
+				
+				changelog_path = g_build_filename (commit->priv->dirname,
+								   "ChangeLog",
+								   NULL);
+				selected_paths = g_list_append (selected_paths,
+								changelog_path);
+			}
+				    
+			commit_command = svn_commit_command_new (selected_paths, 
+								 log,
+								 FALSE);
+			g_free (log);
+			
+			svn_command_free_path_list (selected_paths);
+		
+			/*pulse_timer_id = status_bar_progress_pulse (data->plugin,
+								    _("Subversion: " 
+								      "Committing changes "
+								      "to the "
+								      "repository..."));
+			
+			g_signal_connect (G_OBJECT (commit_command), "command-finished",
+					  G_CALLBACK (stop_status_bar_progress_pulse),
+					  GUINT_TO_POINTER (pulse_timer_id));*/
+			
+			g_signal_connect (G_OBJECT (commit_command), "command-finished",
+					  G_CALLBACK (on_commit_command_finished),
+					  commit);
+			
+			g_signal_connect (G_OBJECT (commit_command), "data-arrived",
+					  G_CALLBACK (on_command_info_arrived),
+					  commit->priv->window);
+			
+			gtranslator_command_start (GTR_COMMAND (commit_command));
+		
+			gtk_widget_hide (GTK_WIDGET (dlg));
+			break;
+		}
+		default:
+			gtk_widget_destroy (GTK_WIDGET (dlg));
+	}
+}
+
+static void
+send_status_command (GtranslatorCommitDialog *dlg,
+		     GtranslatorWindow *window)
+{
+	SvnStatusCommand *status_command;
+	GtranslatorTab *tab;
+	GtranslatorPo *po;
+	GFile *location, *parent;
+	
+	/* Setting up */
+	dlg->priv->window = window;
+	tab = gtranslator_window_get_active_tab (window);
+	po = gtranslator_tab_get_po (tab);
+	g_free (dlg->priv->dirname);
+	
+	location = gtranslator_po_get_location (po);
+	parent = g_file_get_parent (location);
+	g_object_unref (location);
+	
+	dlg->priv->dirname = g_file_get_path (parent);
+	g_object_unref (parent);
+	
+	status_command = svn_status_command_new (dlg->priv->dirname,
+						 TRUE, TRUE);
+	
+	g_signal_connect (G_OBJECT (status_command), "command-finished",
+			  G_CALLBACK (select_all_files),
+			  dlg->priv->status_view);
+	
+	pulse_progress_bar (GTK_PROGRESS_BAR (dlg->priv->status_progress_bar));
+	
+	g_signal_connect (G_OBJECT (status_command), "command-finished",
+			  G_CALLBACK (cancel_data_arrived_signal_disconnect),
+			  dlg->priv->status_view);
+	
+	g_signal_connect (G_OBJECT (status_command), "command-finished",
+			  G_CALLBACK (hide_pulse_progress_bar),
+			  dlg->priv->status_progress_bar);
+	
+	g_signal_connect (G_OBJECT (status_command), "command-finished",
+			  G_CALLBACK (on_status_command_finished),
+			  dlg->priv->window);
+	
+	g_signal_connect (G_OBJECT (status_command), "data-arrived",
+			  G_CALLBACK (on_status_command_data_arrived),
+			  dlg->priv->status_view);
+	
+	g_object_weak_ref (G_OBJECT (dlg->priv->status_view),
+			   (GWeakNotify) disconnect_data_arrived_signals,
+			   status_command);
+	
+	gtranslator_command_start (GTR_COMMAND (status_command));
+}
+
+static void
+on_add_log_checkbutton_toggled (GtkToggleButton *button,
+				GtranslatorCommitDialog *dlg)
+{
+	g_return_if_fail (GTR_IS_COMMIT_DIALOG (dlg));
+	
+	if (!gconf_client_key_is_writable (dlg->priv->gconf_client,
+					   ADD_CHANGE_LOG_KEY,
+					   NULL))
+		return;
+
+	gconf_client_set_bool (dlg->priv->gconf_client,
+			       ADD_CHANGE_LOG_KEY,
+			       gtk_toggle_button_get_active (button),
+			       NULL);
+}
+
+static void
+gtranslator_commit_dialog_init (GtranslatorCommitDialog *dlg)
+{
+	gboolean ret;
+	GtkWidget *error_widget;
+	GtkWidget *sw_view;
+	gboolean data;
+	
+	dlg->priv = GTR_COMMIT_DIALOG_GET_PRIVATE (dlg);
+	
+	dlg->priv->gconf_client = gconf_client_get_default ();
+	dlg->priv->dirname = NULL;
+	
+	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
+				GTK_STOCK_CANCEL,
+				GTK_RESPONSE_CANCEL,
+				GTK_STOCK_OK,
+				GTK_RESPONSE_OK,
+				NULL);
+	
+	gtk_window_set_title (GTK_WINDOW (dlg), _("Commit Changes"));
+	gtk_window_set_default_size (GTK_WINDOW (dlg), 600, 600);
+	gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
+	
+	/* HIG defaults */
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 2); /* 2 * 5 + 2 = 12 */
+	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 4);
+	
+	g_signal_connect (dlg,
+			  "response",
+			  G_CALLBACK (dialog_response_handler),
+			  NULL);
+	
+	/*Glade*/
+	ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+		"commit_main_box",
+		&error_widget,
+		
+		"commit_main_box", &dlg->priv->main_box,
+		"changelog_view", &dlg->priv->changelog_view,
+		"add_log_checkbutton", &dlg->priv->add_log_checkbutton,
+		"select_all_button", &dlg->priv->select_all_button,
+		"clear_button", &dlg->priv->clear_button,
+		"status_progress_bar", &dlg->priv->status_progress_bar,
+		"sw_view", &sw_view,
+		
+		NULL);
+	
+	if(!ret)
+	{
+		gtk_widget_show (error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+					     error_widget);
+		
+		return;
+	}
+	
+	/* status view */
+	dlg->priv->status_view = gtranslator_vcs_status_tree_view_new ();
+	gtk_widget_show (dlg->priv->status_view);
+	gtk_container_add (GTK_CONTAINER (sw_view),
+			   dlg->priv->status_view);
+	
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+			    dlg->priv->main_box, TRUE, TRUE, 0);
+	
+	gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->main_box), 5);
+	
+	/*
+	 * We add the ChangeLog
+	 */
+	add_changelog_to_text_view (dlg->priv->changelog_view);
+	
+	g_signal_connect (dlg->priv->add_log_checkbutton, "toggled",
+			  G_CALLBACK (on_add_log_checkbutton_toggled), dlg);
+	
+	g_signal_connect (G_OBJECT (dlg->priv->select_all_button), "clicked",
+			  G_CALLBACK (select_all_status_items),
+			  dlg->priv->status_view);
+	
+	g_signal_connect (G_OBJECT (dlg->priv->clear_button), "clicked",
+			  G_CALLBACK (clear_all_status_selections),
+			  dlg->priv->status_view);
+	
+	/*
+	 * Set add_log_checkbutton value
+	 */
+	data = gconf_client_get_bool (dlg->priv->gconf_client,
+				      ADD_CHANGE_LOG_KEY,
+				      NULL);
+	
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->add_log_checkbutton),
+				      data);
+}
+
+static void
+gtranslator_commit_dialog_finalize (GObject *object)
+{
+	GtranslatorCommitDialog *dlg = GTR_COMMIT_DIALOG (object);
+	
+	gconf_client_suggest_sync (dlg->priv->gconf_client, NULL);
+
+	g_object_unref (G_OBJECT (dlg->priv->gconf_client));
+	
+	g_free (dlg->priv->dirname);
+	
+	G_OBJECT_CLASS (gtranslator_commit_dialog_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_commit_dialog_class_init (GtranslatorCommitDialogClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorCommitDialogPrivate));
+
+	object_class->finalize = gtranslator_commit_dialog_finalize;
+}
+
+void
+gtranslator_show_commit_dialog (GtranslatorWindow *window)
+{
+	static GtranslatorCommitDialog *dlg = NULL;
+	
+	g_return_if_fail (GTR_IS_WINDOW (window));
+	
+	if(dlg == NULL)
+	{
+		dlg = g_object_new (GTR_TYPE_COMMIT_DIALOG, NULL);
+		
+		gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg),
+						    TRUE);
+
+		send_status_command (dlg, window);
+		
+		g_signal_connect (dlg,
+				  "destroy",
+				  G_CALLBACK (gtk_widget_destroyed),
+				  &dlg);
+		gtk_widget_show (GTK_WIDGET (dlg));
+	}
+	else
+	{
+		/* We clean the current status treeview and send another
+		 status command */
+		gtranslator_vsc_status_tree_view_clear (GTR_VCS_STATUS_TREE_VIEW (dlg->priv->status_view));
+		send_status_command (dlg, dlg->priv->window);
+	}
+	
+	if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (dlg)))
+	{
+		gtk_window_set_transient_for (GTK_WINDOW (dlg),
+					      GTK_WINDOW (window));
+	}
+
+	gtk_window_present (GTK_WINDOW (dlg));
+}

Added: trunk/plugins/subversion/commit-dialog.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/commit-dialog.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __COMMIT_DIALOG_H__
+#define __COMMIT_DIALOG_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "window.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_COMMIT_DIALOG		(gtranslator_commit_dialog_get_type ())
+#define GTR_COMMIT_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_COMMIT_DIALOG, GtranslatorCommitDialog))
+#define GTR_COMMIT_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_COMMIT_DIALOG, GtranslatorCommitDialogClass))
+#define GTR_IS_COMMIT_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_COMMIT_DIALOG))
+#define GTR_IS_COMMIT_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_COMMIT_DIALOG))
+#define GTR_COMMIT_DIALOG_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_COMMIT_DIALOG, GtranslatorCommitDialogClass))
+
+/* Private structure type */
+typedef struct _GtranslatorCommitDialogPrivate	GtranslatorCommitDialogPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorCommitDialog		GtranslatorCommitDialog;
+
+struct _GtranslatorCommitDialog
+{
+	GtkDialog parent_instance;
+	
+	/*< private > */
+	GtranslatorCommitDialogPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorCommitDialogClass	GtranslatorCommitDialogClass;
+
+struct _GtranslatorCommitDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_commit_dialog_get_type               (void) G_GNUC_CONST;
+
+GType		 gtranslator_commit_dialog_register_type          (GTypeModule * module);
+
+void         gtranslator_show_commit_dialog                   (GtranslatorWindow *window);
+
+G_END_DECLS
+
+#endif /* __COMMIT_DIALOG_H__ */

Added: trunk/plugins/subversion/diff-dialog.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/diff-dialog.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "diff-dialog.h"
+#include "subversion-plugin.h"
+#include "svn-diff-command.h"
+#include "svn-cat-command.h"
+#include "utils.h"
+#include "svn-command.h"
+#include "statusbar.h"
+#include "subversion-utils.h"
+#include "subversion-plugin.h"
+#include "tab.h"
+#include "po.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <gconf/gconf-client.h>
+#include <unistd.h>
+
+#define USE_CONFIGURED_PROGRAM_KEY SUBVERSION_BASE_KEY "/use_configured_program"
+#define SAVE_DIFF_KEY SUBVERSION_BASE_KEY "/save_diff"
+
+#define GTR_DIFF_DIALOG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 	(object),	\
+						 	GTR_TYPE_DIFF_DIALOG,     \
+						 	GtranslatorDiffDialogPrivate))
+
+
+G_DEFINE_TYPE(GtranslatorDiffDialog, gtranslator_diff_dialog, GTK_TYPE_DIALOG)
+
+struct _GtranslatorDiffDialogPrivate
+{
+	GConfClient *gconf_client;
+	
+	GtkWidget *main_box;
+	GtkWidget *use_configured_program;
+	GtkWidget *save_diff;
+	GtkWidget *diff_filename_entry;
+	GtkWidget *diff_find;
+	
+	gchar *filename;
+
+	GtranslatorWindow *window;
+};
+
+static void
+on_diff_command_finished (GtranslatorCommand *command,
+			  guint return_code,
+			  GtranslatorDiffDialog *dlg)
+{
+	GtranslatorStatusbar *status;
+	
+	status = GTR_STATUSBAR (gtranslator_window_get_statusbar (dlg->priv->window));
+	
+	gtranslator_statusbar_flash_message (status, 0,
+					     _("Subversion: Diff complete."));
+	
+	subversion_utils_report_errors (dlg->priv->window, 
+					command, return_code);
+	
+	if (SVN_IS_DIFF_COMMAND (command))
+		svn_diff_command_destroy (SVN_DIFF_COMMAND (command));	
+	else svn_cat_command_destroy (SVN_CAT_COMMAND (command));
+}
+
+static void
+show_in_program (const gchar *program_name,
+		 const gchar *line_arg,
+		 const gchar *path1,
+		 const gchar *path2)
+{
+	gchar *open[5];
+
+	if (g_find_program_in_path (program_name))
+	{
+		open[0] = g_strdup (program_name);
+	}
+	else
+	{
+		GtkWidget *dialog;
+		
+		dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+						 GTK_DIALOG_MODAL,
+						 GTK_BUTTONS_CLOSE,
+						 _("Please, install %s to be able to diff the file"),
+						 program_name);
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+	}
+	
+	open[1] = g_strdup (path1);
+	open[2] = g_strdup (path2);
+	
+	if (strcmp (line_arg, ""))
+	{
+		open[3] = g_strdup_printf ("%s",line_arg);
+		open[4] = NULL;
+	}
+	else open[3] = NULL;
+					
+	gdk_spawn_on_screen (gdk_screen_get_default (),
+			     NULL,
+			     open,
+			     NULL,
+			     G_SPAWN_SEARCH_PATH,
+			     NULL,
+			     NULL, NULL, NULL);
+	g_free (open[0]);
+	g_free (open[1]);
+	g_free (open[2]);
+	g_free (open[3]);
+}
+
+static void
+on_cat_command_info_arrived (GtranslatorCommand *command,
+			     GtranslatorDiffDialog *dlg)
+{
+	GQueue *output;
+	gchar *line;
+	guint tmpfd;
+	GError *error = NULL;
+	gchar *tmp_fname;
+	GFile *tmp_file;
+	GFileOutputStream *ostream;
+	gboolean check;
+	gchar *program_name;
+	gchar *program_arg;
+	
+	output = svn_cat_command_get_output (SVN_CAT_COMMAND (command));
+	
+	tmpfd = g_file_open_tmp (".gtranslator-changelog-XXXXXX",
+				 &tmp_fname,
+				 &error);
+	
+	if (tmpfd == -1)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+		
+		/* In this case we don't have to close the file */
+		return;
+	}
+	
+	tmp_file = g_file_new_for_path (tmp_fname);
+		    
+	ostream = g_file_append_to (tmp_file, G_FILE_CREATE_NONE,
+				    NULL, &error);
+	
+	while (g_queue_peek_head (output))
+	{
+		line = g_queue_pop_head (output);
+		
+		g_output_stream_write (G_OUTPUT_STREAM (ostream), line,
+				       strlen (line),
+				       NULL, &error);
+		
+		g_free (line);
+		
+		if (error)
+			break;
+	}
+	
+	if (error)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+		error = NULL;
+	}
+	
+	if (!g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, &error))
+	{
+		g_warning (error->message);
+		g_error_free (error);
+	}
+	
+	/*
+	 * Check if we have to show it in an external diff program
+	 */
+	check = gconf_client_get_bool (dlg->priv->gconf_client,
+				       USE_CONFIGURED_PROGRAM_KEY,
+				       NULL);
+	
+	if (check)
+	{
+		program_name = gconf_client_get_string (dlg->priv->gconf_client,
+							PROGRAM_NAME_KEY,
+							NULL);
+		program_arg = gconf_client_get_string (dlg->priv->gconf_client,
+						       LINE_ARGUMENT_KEY,
+						       NULL);
+		
+		show_in_program (program_name, program_arg,
+				 tmp_fname, dlg->priv->filename);
+		
+		g_free (program_name);
+		g_free (program_arg);
+	}
+	
+	close (tmpfd);
+	g_free (tmp_fname);
+	g_object_unref (tmp_file);
+}
+
+static void
+on_diff_command_info_arrived (GtranslatorCommand *command,
+			      GtranslatorDiffDialog *dlg)
+{
+	GQueue *output;
+	gchar *line;
+	GError *error = NULL;
+	GFile *tmp_file;
+	const gchar *tmp_fname;
+	GFileOutputStream *ostream;
+	
+	output = svn_diff_command_get_output (SVN_DIFF_COMMAND (command));
+	
+	tmp_fname = gtk_entry_get_text (GTK_ENTRY (dlg->priv->diff_filename_entry));
+	
+	tmp_file = g_file_new_for_path (tmp_fname);
+	
+	if (g_file_query_exists (tmp_file, NULL))
+	{
+		if (!g_file_delete (tmp_file, NULL, &error))
+		{
+			g_warning (error->message);
+			g_error_free (error);
+			
+			g_object_unref (tmp_file);
+			return;
+		}
+	}
+	
+	ostream = g_file_create (tmp_file, G_FILE_CREATE_NONE,
+				 NULL, &error);
+	
+	while (g_queue_peek_head (output))
+	{
+		line = g_queue_pop_head (output);
+		
+		g_output_stream_write (G_OUTPUT_STREAM (ostream), line,
+				       strlen (line),
+				       NULL, &error);
+		
+		g_free (line);
+		
+		if (error)
+			break;
+	}
+	
+	if (error)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+		error = NULL;
+	}
+	
+	if (!g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, &error))
+	{
+		g_warning (error->message);
+		g_error_free (error);
+	}
+	
+	g_object_unref (tmp_file);
+}
+
+static void
+send_diff_command (GtranslatorDiffDialog *dlg)
+{
+	SvnDiffCommand *diff_command;
+	
+	diff_command = svn_diff_command_new (dlg->priv->filename,
+					     SVN_DIFF_REVISION_NONE,
+					     SVN_DIFF_REVISION_NONE,
+					     TRUE);
+	
+	g_signal_connect (G_OBJECT (diff_command), "command-finished",
+			  G_CALLBACK (on_diff_command_finished),
+			  dlg);
+	
+	g_signal_connect (G_OBJECT (diff_command), "data-arrived",
+			  G_CALLBACK (on_diff_command_info_arrived),
+			  dlg);
+	
+	gtranslator_command_start (GTR_COMMAND (diff_command));
+}
+
+static void
+send_cat_command (GtranslatorDiffDialog *dlg)
+{
+	SvnCatCommand *cat_command;
+	
+	cat_command = svn_cat_command_new (dlg->priv->filename,
+					   SVN_DIFF_REVISION_NONE);
+	
+	g_signal_connect (G_OBJECT (cat_command), "command-finished",
+			  G_CALLBACK (on_diff_command_finished),
+			  dlg);
+	
+	g_signal_connect (G_OBJECT (cat_command), "data-arrived",
+			  G_CALLBACK (on_cat_command_info_arrived),
+			  dlg);
+	
+	gtranslator_command_start (GTR_COMMAND (cat_command));
+}
+
+static void
+dialog_response_handler (GtranslatorDiffDialog *dlg, 
+			 gint       res_id)
+{
+	switch (res_id)
+	{
+		case GTK_RESPONSE_OK:
+		{	
+			if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->save_diff)))
+				send_diff_command (dlg);
+			if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->use_configured_program)))
+				send_cat_command (dlg);
+			gtk_widget_hide (GTK_WIDGET (dlg));
+			break;
+		}
+		default:
+			gtk_widget_hide (GTK_WIDGET (dlg));
+	}
+}
+
+static void
+setup_diff_filename_entry (GtranslatorDiffDialog *dlg)
+{
+	gchar *file;
+	
+	file = g_strdup_printf ("%s.diff", dlg->priv->filename);
+	
+	gtk_entry_set_text (GTK_ENTRY (dlg->priv->diff_filename_entry),
+			    file);
+	g_free (file);
+}
+
+static void
+use_configured_program_toggled (GtkToggleButton *button,
+				GtranslatorDiffDialog *dlg)
+{
+	g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
+	
+	if (!gconf_client_key_is_writable (dlg->priv->gconf_client,
+					   USE_CONFIGURED_PROGRAM_KEY,
+					   NULL))
+		return;
+
+	gconf_client_set_bool (dlg->priv->gconf_client,
+			       USE_CONFIGURED_PROGRAM_KEY,
+			       gtk_toggle_button_get_active (button),
+			       NULL);
+}
+
+static void
+save_diff_toggled (GtkToggleButton *button,
+		   GtranslatorDiffDialog *dlg)
+{
+	gboolean active;
+	
+	g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
+	
+	active = gtk_toggle_button_get_active (button);
+	
+	if (!gconf_client_key_is_writable (dlg->priv->gconf_client,
+					   SAVE_DIFF_KEY,
+					   NULL))
+		return;
+
+	gconf_client_set_bool (dlg->priv->gconf_client,
+			       SAVE_DIFF_KEY,
+			       active,
+			       NULL);
+	
+
+	
+	gtk_widget_set_sensitive (dlg->priv->diff_filename_entry, active);
+	gtk_widget_set_sensitive (dlg->priv->diff_find, active);
+}
+
+static void
+on_diff_find_clicked (GtkButton *button,
+		      GtranslatorDiffDialog *dlg)
+{
+	GtkWidget *dialog;
+	gint res;
+	
+	dialog = gtk_file_chooser_dialog_new (_("Diff file"),
+					      GTK_WINDOW (dlg->priv->window),
+					      GTK_FILE_CHOOSER_ACTION_SAVE,
+					      GTK_STOCK_CANCEL,
+					      GTK_RESPONSE_CANCEL,
+					      GTK_STOCK_OK,
+					      GTK_RESPONSE_OK,
+					      NULL);
+	res = gtk_dialog_run (GTK_DIALOG (dialog));
+	switch (res)
+	{
+		case GTK_RESPONSE_OK: 
+		{
+			gchar *filename;
+			
+			filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+			gtk_entry_set_text (GTK_ENTRY (dlg->priv->diff_filename_entry),
+					    filename);
+			g_free (filename);
+			break;
+		}
+		default:
+			break;
+	}
+	gtk_widget_destroy (dialog);
+}
+
+static void
+set_values (GtranslatorDiffDialog *dlg)
+{
+	gboolean data;
+	
+	/* Use configured program */
+	data = gconf_client_get_bool (dlg->priv->gconf_client,
+				      USE_CONFIGURED_PROGRAM_KEY,
+				      NULL);
+	
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->use_configured_program),
+				      data);
+	
+	/* Save diff */
+	data = gconf_client_get_bool (dlg->priv->gconf_client,
+				      SAVE_DIFF_KEY,
+				      NULL);
+	
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->save_diff),
+				      data);
+}
+
+static void
+gtranslator_diff_dialog_init (GtranslatorDiffDialog *dlg)
+{
+	gboolean ret;
+	GtkWidget *error_widget;
+	gboolean active;
+	
+	dlg->priv = GTR_DIFF_DIALOG_GET_PRIVATE (dlg);
+	
+	dlg->priv->gconf_client = gconf_client_get_default ();
+	dlg->priv->filename = NULL;
+	
+	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
+				GTK_STOCK_CLOSE,
+				GTK_RESPONSE_CLOSE,
+				GTK_STOCK_OK,
+				GTK_RESPONSE_OK,
+				NULL);
+	
+	gtk_window_set_title (GTK_WINDOW (dlg), _("Diff"));
+	gtk_window_set_default_size (GTK_WINDOW (dlg), 500, 300);
+	gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
+	
+	/* HIG defaults */
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 2); /* 2 * 5 + 2 = 12 */
+	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 4);
+	
+	g_signal_connect (dlg,
+			  "response",
+			  G_CALLBACK (dialog_response_handler),
+			  NULL);
+	
+	/*Glade*/
+	ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+		"diff_main_box",
+		&error_widget,
+		
+		"diff_main_box", &dlg->priv->main_box,
+		"use_configured_program", &dlg->priv->use_configured_program,
+		"save_diff", &dlg->priv->save_diff,
+		"diff_filename_entry", &dlg->priv->diff_filename_entry,
+		"diff_find", &dlg->priv->diff_find,
+		
+		NULL);
+	
+	if(!ret)
+	{
+		gtk_widget_show (error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+					     error_widget);
+		
+		return;
+	}
+	
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+			    dlg->priv->main_box, TRUE, TRUE, 0);
+	
+	gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->main_box), 5);
+	
+	g_signal_connect (dlg->priv->use_configured_program, "toggled",
+			  G_CALLBACK (use_configured_program_toggled), dlg);
+	
+	g_signal_connect (dlg->priv->save_diff, "toggled",
+			  G_CALLBACK (save_diff_toggled), dlg);
+	
+	g_signal_connect (dlg->priv->diff_find, "clicked",
+			  G_CALLBACK (on_diff_find_clicked), dlg);
+	
+	/*
+	 * Set values
+	 */
+	set_values (dlg);
+	
+	active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->save_diff));
+	gtk_widget_set_sensitive (dlg->priv->diff_filename_entry, active);
+	gtk_widget_set_sensitive (dlg->priv->diff_find, active);
+}
+
+static void
+gtranslator_diff_dialog_finalize (GObject *object)
+{
+	GtranslatorDiffDialog *dlg = GTR_DIFF_DIALOG (object);
+	
+	gconf_client_suggest_sync (dlg->priv->gconf_client, NULL);
+
+	g_object_unref (G_OBJECT (dlg->priv->gconf_client));
+	
+	g_free (dlg->priv->filename);
+	
+	G_OBJECT_CLASS (gtranslator_diff_dialog_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_diff_dialog_class_init (GtranslatorDiffDialogClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorDiffDialogPrivate));
+
+	object_class->finalize = gtranslator_diff_dialog_finalize;
+}
+
+void
+gtranslator_show_diff_dialog (GtranslatorWindow *window)
+{
+	static GtranslatorDiffDialog *dlg = NULL;
+	GtranslatorTab *tab;
+	GtranslatorPo *po;
+	GFile *location;
+	
+	g_return_if_fail (GTR_IS_WINDOW (window));
+	
+	tab = gtranslator_window_get_active_tab (window);
+	po = gtranslator_tab_get_po (tab);
+	location = gtranslator_po_get_location (po);
+	
+	if(dlg == NULL)
+	{
+		dlg = g_object_new (GTR_TYPE_DIFF_DIALOG, NULL);
+		
+		gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg),
+						    TRUE);
+		
+		dlg->priv->window = window;
+		
+		g_signal_connect (dlg,
+				  "destroy",
+				  G_CALLBACK (gtk_widget_destroyed),
+				  &dlg);
+
+		gtk_widget_show (GTK_WIDGET (dlg));
+	}
+	
+	//As we are not destroying the dialog we have to free the filename
+	g_free (dlg->priv->filename);
+	dlg->priv->filename = g_file_get_path (location);
+	setup_diff_filename_entry (dlg);
+	
+	if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (dlg)))
+	{
+		gtk_window_set_transient_for (GTK_WINDOW (dlg),
+					      GTK_WINDOW (window));
+	}
+
+	gtk_window_present (GTK_WINDOW (dlg));
+}

Added: trunk/plugins/subversion/diff-dialog.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/diff-dialog.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __DIFF_DIALOG_H__
+#define __DIFF_DIALOG_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "window.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_DIFF_DIALOG		(gtranslator_diff_dialog_get_type ())
+#define GTR_DIFF_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_DIFF_DIALOG, GtranslatorDiffDialog))
+#define GTR_DIFF_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_DIFF_DIALOG, GtranslatorDiffDialogClass))
+#define GTR_IS_DIFF_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_DIFF_DIALOG))
+#define GTR_IS_DIFF_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_DIFF_DIALOG))
+#define GTR_DIFF_DIALOG_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_DIFF_DIALOG, GtranslatorDiffDialogClass))
+
+/* Private structure type */
+typedef struct _GtranslatorDiffDialogPrivate	GtranslatorDiffDialogPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorDiffDialog		GtranslatorDiffDialog;
+
+struct _GtranslatorDiffDialog
+{
+	GtkDialog parent_instance;
+	
+	/*< private > */
+	GtranslatorDiffDialogPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorDiffDialogClass	GtranslatorDiffDialogClass;
+
+struct _GtranslatorDiffDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_diff_dialog_get_type               (void) G_GNUC_CONST;
+
+GType		 gtranslator_diff_dialog_register_type          (GTypeModule * module);
+
+void	     gtranslator_show_diff_dialog                   (GtranslatorWindow *window);
+
+G_END_DECLS
+
+#endif /* __DIFF_DIALOG_H__ */

Added: trunk/plugins/subversion/subversion-enum-types.c.template
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion-enum-types.c.template	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,39 @@
+/*** BEGIN file-header ***/
+#include "subversion-enum-types.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+#include "@filename@"
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+ enum_name@_get_type (void)
+{
+	static GType the_type = 0;
+	
+	if (the_type == 0)
+	{
+		static const G Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+			{ @VALUENAME@,
+			  "@VALUENAME@",
+			  "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+			{ 0, NULL, NULL }
+		};
+		the_type = g_ type@_register_static (
+				g_intern_static_string ("@EnumName@"),
+				values);
+	}
+	return the_type;
+}
+
+/*** END value-tail ***/

Added: trunk/plugins/subversion/subversion-enum-types.h.template
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion-enum-types.h.template	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,26 @@
+/*** BEGIN file-header ***/
+#ifndef __GTR_ENUM_TYPES_H__
+#define __GTR_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* Enumerations from "@filename@" */
+
+/*** END file-production ***/
+
+/*** BEGIN enumeration-production ***/
+#define GTR_TYPE_ ENUMSHORT@	(@enum_name _get_type())
+GType @enum_name _get_type	(void) G_GNUC_CONST;
+
+/*** END enumeration-production ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __GEDIT_ENUM_TYPES_H__ */
+/*** END file-tail ***/

Added: trunk/plugins/subversion/subversion-icon.png
==============================================================================
Binary files (empty file) and trunk/plugins/subversion/subversion-icon.png	Tue Sep 16 07:58:13 2008 differ

Added: trunk/plugins/subversion/subversion-plugin.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion-plugin.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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
+ *     MERCHANPOILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "subversion-plugin.h"
+#include "subversion-utils.h"
+#include "svn-add-command.h"
+#include "window.h"
+#include "statusbar.h"
+#include "commit-dialog.h"
+#include "update-dialog.h"
+#include "diff-dialog.h"
+#include "checkout-dialog.h"
+#include "utils.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <gconf/gconf-client.h>
+
+#define WINDOW_DATA_KEY "GtranslatorSubversionPluginWindowData"
+
+#define GTR_SUBVERSION_PLUGIN_GET_PRIVATE(object) \
+				(G_TYPE_INSTANCE_GET_PRIVATE ((object),	\
+				GTR_TYPE_SUBVERSION_PLUGIN,		\
+				GtranslatorSubversionPluginPrivate))
+
+GTR_PLUGIN_REGISTER_TYPE(GtranslatorSubversionPlugin, gtranslator_subversion_plugin)
+
+struct _GtranslatorSubversionPluginPrivate
+{
+	GConfClient *gconf_client;
+	
+	/* Dialog stuff */
+	GtkWidget *dialog;
+	
+	GtkWidget *main_box;
+	GtkWidget *program_name_entry;
+	GtkWidget *line_argument_entry;
+};
+
+static void
+on_update_activated (GtkAction *action,
+		     GtranslatorWindow *window)
+{
+	gtranslator_show_update_dialog (window);
+}
+
+static void
+on_commit_activated (GtkAction *action,
+		     GtranslatorWindow *window)
+{
+	gtranslator_show_commit_dialog (window);
+}
+
+static void
+on_add_command_finished (GtranslatorCommand *command,
+			 guint return_code, 
+			 GtranslatorWindow *window)
+{
+	GtranslatorStatusbar *statusbar;
+	
+	statusbar = GTR_STATUSBAR (gtranslator_window_get_statusbar (window));
+	
+	gtranslator_statusbar_flash_message (statusbar, 0,
+					     _("Subversion: File will be added on next "
+					       "commit."));
+
+	subversion_utils_report_errors (window, command, return_code);
+	
+	svn_add_command_destroy (SVN_ADD_COMMAND (command));
+}
+
+static void
+on_add_activated (GtkAction *action,
+		  GtranslatorWindow *window)
+{
+	GtranslatorTab *tab;
+	GtranslatorPo *po;
+	SvnAddCommand *add_command;
+	GFile *location;
+	gchar *path;
+	
+	tab = gtranslator_window_get_active_tab (window);
+	po = gtranslator_tab_get_po (tab);
+	
+	location = gtranslator_po_get_location (po);
+	path = g_file_get_path (location);
+	g_object_unref (location);
+	
+	add_command = svn_add_command_new (path,
+					   FALSE,
+					   FALSE);
+	
+	g_free (path);
+
+	g_signal_connect (G_OBJECT (add_command), "command-finished",
+			  G_CALLBACK (on_add_command_finished),
+			  window);
+	
+	gtranslator_command_start (GTR_COMMAND (add_command));
+}
+
+static void
+on_diff_activated (GtkAction *action,
+		   GtranslatorWindow *window)
+{
+	gtranslator_show_diff_dialog (window);
+}
+
+static void
+on_checkout_activated (GtkAction *action,
+		       GtranslatorWindow *window)
+{
+	gtranslator_show_checkout_dialog (window);
+}
+
+static const GtkActionEntry action_entries[] =
+{	
+	{ "SubversionUpdate", GTK_STOCK_REFRESH, N_("_Update"), NULL,
+	 N_("Sync your local copy with the Subversion tree"),
+	 G_CALLBACK (on_update_activated)},
+	
+	{ "SubversionCommit", GTK_STOCK_YES, N_("_Commit"), NULL,
+	 N_("Commit your changes to the Subversion tree"),
+	 G_CALLBACK (on_commit_activated)},
+	
+	{ "SubversionAdd", GTK_STOCK_ADD, N_("_Add"), NULL,
+	 N_("Add a new file/directory to the Subversion tree"),
+	 G_CALLBACK (on_add_activated)},
+	
+	{ "SubversionDiff", GTK_STOCK_ZOOM_100, N_("_Diff"), NULL,
+	 N_("Diff local PO file with repository PO file"),
+	 G_CALLBACK (on_diff_activated)},
+	
+	{ "SubversionCheckout", GTK_STOCK_SAVE, N_("C_heckout"), "",
+	 N_("Get a new repository copy"),
+	 G_CALLBACK (on_checkout_activated)},
+	
+	{ "Subversion", NULL, N_("S_ubversion") }
+};
+
+static const gchar submenu[] =
+"<ui>"
+"  <menubar name=\"MainMenu\">"
+"    <placeholder name=\"SubversionPlaceholder\">"
+"      <menu name=\"SubversionMenu\" action=\"Subversion\">"
+"        <menuitem name=\"SubversionUpdateMenu\" action=\"SubversionUpdate\"/>"
+"        <menuitem name=\"SubversionCommitMenu\" action=\"SubversionCommit\"/>"
+"        <separator />"
+"        <menuitem name=\"SubversionAddMenu\" action=\"SubversionAdd\"/>"
+"        <separator />"
+"        <menuitem name=\"SubversionDiffMenu\" action=\"SubversionDiff\"/>"
+"        <separator />"
+"        <menuitem name=\"SubversionCheckoutMenu\" action=\"SubversionCheckout\"/>"
+"      </menu>"
+"    </placeholder>"
+"  </menubar>"
+"</ui>";
+
+typedef struct
+{
+	GtkActionGroup *action_group;
+	guint           ui_id;
+} WindowData;
+
+static void
+free_window_data (WindowData *data)
+{
+	g_return_if_fail (data != NULL);
+
+	g_free (data);
+}
+
+static void
+update_ui_real (GtranslatorWindow *window,
+		WindowData   *data)
+{
+	GList *tabs;
+	GtkAction *action;
+
+	tabs = gtranslator_window_get_all_tabs (window);
+
+	action = gtk_action_group_get_action (data->action_group,
+					      "SubversionAdd");
+	gtk_action_set_sensitive (action,
+				  tabs != NULL);
+	
+	action = gtk_action_group_get_action (data->action_group,
+					      "SubversionUpdate");
+	gtk_action_set_sensitive (action,
+				  tabs != NULL);
+	
+	action = gtk_action_group_get_action (data->action_group,
+					      "SubversionCommit");
+	gtk_action_set_sensitive (action,
+				  tabs != NULL);
+	
+	action = gtk_action_group_get_action (data->action_group,
+					      "SubversionDiff");
+	gtk_action_set_sensitive (action,
+				  tabs != NULL);
+}
+
+static void
+gtranslator_subversion_plugin_init (GtranslatorSubversionPlugin *plugin)
+{
+	plugin->priv = GTR_SUBVERSION_PLUGIN_GET_PRIVATE (plugin);
+
+	plugin->priv->gconf_client = gconf_client_get_default ();
+
+	gconf_client_add_dir (plugin->priv->gconf_client,
+			      SUBVERSION_BASE_KEY,
+			      GCONF_CLIENT_PRELOAD_ONELEVEL,
+			      NULL);
+	
+	apr_initialize ();
+}
+
+static void
+gtranslator_subversion_plugin_finalize (GObject *object)
+{
+	GtranslatorSubversionPlugin *plugin = GTR_SUBVERSION_PLUGIN (object);
+	
+	gconf_client_suggest_sync (plugin->priv->gconf_client, NULL);
+
+	g_object_unref (G_OBJECT (plugin->priv->gconf_client));
+	
+	apr_terminate ();
+	
+	G_OBJECT_CLASS (gtranslator_subversion_plugin_parent_class)->finalize (object);
+}
+
+static void
+impl_activate (GtranslatorPlugin *plugin,
+	       GtranslatorWindow *window)
+{
+	GtkUIManager *manager;
+	WindowData *data;
+	GError *error = NULL;
+	
+	g_return_if_fail (GTR_IS_WINDOW (window));
+
+	data = g_new (WindowData, 1);
+
+	manager = gtranslator_window_get_ui_manager (window);
+
+	data->action_group = gtk_action_group_new ("GtranslatorSubversionPluginActions");
+	gtk_action_group_set_translation_domain (data->action_group, 
+						 GETTEXT_PACKAGE);
+	gtk_action_group_add_actions (data->action_group,
+				      action_entries,
+				      G_N_ELEMENTS (action_entries), 
+				      window);
+
+	gtk_ui_manager_insert_action_group (manager, data->action_group, 0);
+
+	g_object_set_data_full (G_OBJECT (window), 
+				WINDOW_DATA_KEY, 
+				data,
+				(GDestroyNotify) free_window_data);
+	
+	data->ui_id = gtk_ui_manager_add_ui_from_string (manager,
+							 submenu,
+							 -1,
+							 &error);
+	
+	if (data->ui_id == 0)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+		return;
+	}
+
+	gtk_ui_manager_ensure_update (manager);
+	update_ui_real (window, data);
+}
+
+static void
+impl_deactivate (GtranslatorPlugin *plugin,
+		 GtranslatorWindow *window)
+{
+	GtkUIManager *manager;
+	WindowData *data;
+	
+	manager = gtranslator_window_get_ui_manager (window);
+
+	data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
+	g_return_if_fail (data != NULL);
+
+	gtk_ui_manager_remove_ui (manager, data->ui_id);
+	gtk_ui_manager_remove_action_group (manager, data->action_group);
+
+	g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL);	
+}
+
+static void
+impl_update_ui (GtranslatorPlugin *plugin,
+		GtranslatorWindow *window)
+{
+	WindowData *data;
+
+	data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
+	g_return_if_fail (data != NULL);
+
+	update_ui_real (window, data);
+}
+
+static void
+get_program (GtranslatorSubversionPlugin *plugin)
+{
+	gchar *data;
+	
+	/* Program name */
+	data = gconf_client_get_string (plugin->priv->gconf_client,
+					PROGRAM_NAME_KEY,
+					NULL);
+	
+	if (!data)
+		data = g_strdup ("meld");
+	
+	gtk_entry_set_text (GTK_ENTRY (plugin->priv->program_name_entry), data);
+	
+	g_free (data);
+	
+	/* Line argument */
+	data = gconf_client_get_string (plugin->priv->gconf_client,
+					LINE_ARGUMENT_KEY,
+					NULL);
+	
+	if (!data)
+		data = g_strdup ("");
+	
+	gtk_entry_set_text (GTK_ENTRY (plugin->priv->line_argument_entry), data);
+	
+	g_free (data);
+}
+
+static GtkWidget *
+get_configuration_dialog (GtranslatorSubversionPlugin *plugin)
+{
+
+	gboolean ret;
+	GtkWidget *error_widget;
+	
+	ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+						   "settings_dialog",
+						   &error_widget,
+						   "settings_dialog", &plugin->priv->dialog,
+						   "main_box", &plugin->priv->main_box,
+						   "program_name", &plugin->priv->program_name_entry,
+						   "line_argument", &plugin->priv->line_argument_entry,
+						   NULL);
+
+	if(!ret)
+	{
+		gtk_widget_show (error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (plugin->priv->dialog)->vbox),
+					     error_widget);
+		
+		return plugin->priv->dialog;
+	}
+
+	get_program (plugin);
+	
+	return plugin->priv->dialog;
+}
+
+static void
+ok_button_pressed (GtranslatorSubversionPlugin *plugin)
+{
+	const gchar *program_name;
+	const gchar *line_argument;
+	
+	/* We have to get the text from the entries */
+	program_name = gtk_entry_get_text (GTK_ENTRY (plugin->priv->program_name_entry));
+	line_argument = gtk_entry_get_text (GTK_ENTRY (plugin->priv->line_argument_entry));
+	
+	/* Now we store the data in gconf */
+	if (!gconf_client_key_is_writable (plugin->priv->gconf_client,
+					   PROGRAM_NAME_KEY,
+					   NULL))
+		return;
+
+	gconf_client_set_string (plugin->priv->gconf_client,
+				 PROGRAM_NAME_KEY,
+		       		 program_name,
+		       		 NULL);
+	
+	if (!gconf_client_key_is_writable (plugin->priv->gconf_client,
+					   LINE_ARGUMENT_KEY,
+					   NULL))
+		return;
+
+	gconf_client_set_string (plugin->priv->gconf_client,
+				 LINE_ARGUMENT_KEY,
+		       		 line_argument,
+		       		 NULL);
+}
+
+static void
+configure_dialog_response_cb (GtkWidget           *widget,
+			      gint                 response,
+			      GtranslatorSubversionPlugin *plugin)
+{
+	switch (response)
+	{
+		case GTK_RESPONSE_OK:
+		{
+			ok_button_pressed (plugin);
+
+			gtk_widget_destroy (plugin->priv->dialog);
+			break;
+		}
+		case GTK_RESPONSE_CANCEL:
+		{
+			gtk_widget_destroy (plugin->priv->dialog);
+		}
+	}
+}
+
+static GtkWidget *
+impl_create_configure_dialog (GtranslatorPlugin *plugin)
+{
+	GtkWidget *dialog;
+	
+	dialog = get_configuration_dialog (GTR_SUBVERSION_PLUGIN (plugin));
+	
+	g_signal_connect (dialog,
+			  "response",
+			  G_CALLBACK (configure_dialog_response_cb),
+			  GTR_SUBVERSION_PLUGIN (plugin));
+	g_signal_connect (dialog,
+			  "destroy",
+			  G_CALLBACK (gtk_widget_destroy),
+			  &dialog);
+	
+	return dialog;
+}
+
+static void
+gtranslator_subversion_plugin_class_init (GtranslatorSubversionPluginClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtranslatorPluginClass *plugin_class = GTR_PLUGIN_CLASS (klass);
+
+	object_class->finalize = gtranslator_subversion_plugin_finalize;
+
+	plugin_class->activate = impl_activate;
+	plugin_class->deactivate = impl_deactivate;
+	plugin_class->update_ui = impl_update_ui;
+	plugin_class->create_configure_dialog = impl_create_configure_dialog;
+	
+	g_type_class_add_private (object_class, sizeof (GtranslatorSubversionPluginPrivate));
+}

Added: trunk/plugins/subversion/subversion-plugin.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion-plugin.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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
+ *     MERCHANPOILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __GTR_SUBVERSION_PLUGIN_H__
+#define __GTR_SUBVERSION_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "plugin.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_SUBVERSION_PLUGIN		(gtranslator_subversion_plugin_get_type ())
+#define GTR_SUBVERSION_PLUGIN(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_SUBVERSION_PLUGIN, GtranslatorSubversionPlugin))
+#define GTR_SUBVERSION_PLUGIN_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_SUBVERSION_PLUGIN, GtranslatorSubversionPluginClass))
+#define GTR_IS_SUBVERSION_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_SUBVERSION_PLUGIN))
+#define GTR_IS_SUBVERSION_PLUGIN_CLASS(k)		(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_SUBVERSION_PLUGIN))
+#define GTR_SUBVERSION_PLUGIN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_SUBVERSION_PLUGIN_PLUGIN, GtranslatorSubversionPluginClass))
+
+#define GLADE_FILE DATADIR "/subversion.glade"
+
+/* Gconf keys */
+#define SUBVERSION_BASE_KEY "/apps/gtranslator/plugins/subversion"
+#define PROGRAM_NAME_KEY SUBVERSION_BASE_KEY "/program_name"
+#define LINE_ARGUMENT_KEY SUBVERSION_BASE_KEY "/line_argument"
+
+/* Private structure type */
+typedef struct _GtranslatorSubversionPluginPrivate	GtranslatorSubversionPluginPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorSubversionPlugin		GtranslatorSubversionPlugin;
+
+struct _GtranslatorSubversionPlugin
+{
+	GtranslatorPlugin parent_instance;
+
+	GtranslatorSubversionPluginPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorSubversionPluginClass	GtranslatorSubversionPluginClass;
+
+struct _GtranslatorSubversionPluginClass
+{
+	GtranslatorPluginClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType	gtranslator_subversion_plugin_get_type	(void) G_GNUC_CONST;
+
+/* All the plugins must implement this function */
+G_MODULE_EXPORT GType register_gtranslator_plugin (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* __GTR_SUBVERSION_PLUGIN_H__ */

Added: trunk/plugins/subversion/subversion-utils.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion-utils.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based on anjuta subversion plugin.
+ *     Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "command.h"
+#include "subversion-utils.h"
+#include "utils.h"
+#include "statusbar.h"
+#include "svn-command.h"
+#include "application.h"
+#include "profile.h"
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+typedef struct _PulseProgressData
+{
+	GtranslatorStatusbar *status;
+	gchar *text;
+}PulseProgressData;
+
+void
+subversion_utils_report_errors (GtranslatorWindow *window,
+				GtranslatorCommand *command,
+				guint error_code)
+{
+	GtkWidget *dialog;
+	
+	if (error_code)
+	{
+		gchar *message;
+		
+		message = gtranslator_command_get_error_message (command);
+		dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_ERROR,
+						 GTK_BUTTONS_CLOSE,
+						 message);
+		g_free (message);
+		
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+	}
+}
+
+gchar * 
+subversion_utils_get_log_from_textview (GtkWidget* textview)
+{
+	gchar* log;
+	GtkTextBuffer* textbuf;
+	GtkTextIter iterbegin, iterend;
+	gchar* escaped_log;
+	
+	textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+	gtk_text_buffer_get_start_iter(textbuf, &iterbegin);
+	gtk_text_buffer_get_end_iter(textbuf, &iterend) ;
+	log = gtk_text_buffer_get_text(textbuf, &iterbegin, &iterend, FALSE);
+
+	escaped_log = gtranslator_utils_escape_search_text (log);
+	return escaped_log;
+}
+
+/*guint
+subversion_utils_status_bar_progress_pulse (GtranslatorWindow *window, gchar *text)
+{
+	PulseProgressData *data;
+	
+	data = g_new0 (PulseProgressData, 1);
+	data->status = gtranslator_window_get_statusbar (window);
+	data->text = g_strdup (text);
+	
+	return g_timeout_add_full (G_PRIORITY_DEFAULT, 100,  
+				   (GSourceFunc) status_pulse_timer, data,
+				   (GDestroyNotify) on_pulse_timer_destroyed);
+}*/
+
+void
+subversion_utils_from_file_to_file (GInputStream *istream,
+				    GOutputStream *ostream)
+{
+	gsize bytes = 1;
+	GError *error = NULL;
+	gchar buffer[4096];
+	
+	while (bytes != 0 && bytes != -1)
+	{
+		bytes = g_input_stream_read (istream, buffer,
+					     sizeof (buffer),
+					     NULL, &error);
+		if (error)
+			break;
+
+		g_output_stream_write (ostream, buffer,
+				       bytes,
+				       NULL, &error);
+		if (error)
+			break;
+	}
+	
+	if (error)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+		error = NULL;
+	}
+	
+	if (!g_output_stream_close (ostream, NULL, &error))
+	{
+		g_warning (error->message);
+		g_error_free (error);
+		error = NULL;
+	}
+	if (!g_input_stream_close (istream, NULL, &error))
+	{
+		g_warning (error->message);
+		g_error_free (error);
+	}
+}
+
+gchar *
+subversion_utils_get_changelog_entry_from_view (GtkWidget *view)
+{
+	gchar *log;
+	GtranslatorProfile *profile;
+	gchar *name;
+	gchar *email;
+	gchar *changelog_entry;
+	gchar *date;
+	gchar *code;
+	
+	log = subversion_utils_get_log_from_textview (view);
+	
+	profile = gtranslator_application_get_active_profile (GTR_APP);
+	name = gtranslator_profile_get_author_name (profile);
+	email = gtranslator_profile_get_author_email (profile);
+	code = gtranslator_profile_get_language_code (profile);
+	date = gtranslator_utils_get_current_date ();
+	
+	changelog_entry = g_strdup_printf ("%s  %s  <%s>\n"
+					   "\n\t %s.po: %s\n\n", date, name, email,
+					   code, log);
+	g_free (log);
+	g_free (date);
+	//g_free (name);
+	//g_free (email);
+	
+	return changelog_entry;
+}
\ No newline at end of file

Added: trunk/plugins/subversion/subversion-utils.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion-utils.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based on anjuta subversion plugin.
+ *     Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef GTR_SUBVERSION_UTILS_H
+#define GTR_SUBVERSION_UTILS_H 1
+
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkwindow.h>
+#include <gio/gio.h>
+#include "window.h"
+#include "command.h"
+
+void        subversion_utils_report_errors         (GtranslatorWindow *window,
+						    GtranslatorCommand *command,
+						    guint error_code);
+
+gchar      *subversion_utils_get_log_from_textview (GtkWidget* textview);
+
+void        subversion_utils_from_file_to_file     (GInputStream *istream,
+						    GOutputStream *ostream);
+
+gchar      *subversion_utils_get_changelog_entry_from_view (GtkWidget *view);
+
+#endif

Added: trunk/plugins/subversion/subversion.glade
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion.glade	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,1169 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Tue Jul 15 15:43:24 2008 -->
+<glade-interface>
+  <widget class="GtkDialog" id="svn_user_auth">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Repository authorization</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkHBox" id="hbox1">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Realm:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="auth_realm">
+                    <property name="visible">True</property>
+                    <property name="label">Realm</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox2">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Username:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="username_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox3">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Password:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="password_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox4">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="remember_pwd">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Remember Password</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-5</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkDialog" id="svn_server_trust">
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox2">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="vbox2">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkHBox" id="hbox5">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Realm:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="realm_label">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">label</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="server_info_label">
+                <property name="visible">True</property>
+                <property name="xalign">0.10000000149011612</property>
+                <property name="label" translatable="yes">label</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkCheckButton" id="remember_check">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="label" translatable="yes">Remember this decision</property>
+                <property name="response_id">0</property>
+                <property name="draw_indicator">True</property>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area2">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button3">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button4">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-yes</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkDialog" id="commit_dialog">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Send Changes</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox3">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="commit_main_box">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label6">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Log Message:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox6">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkScrolledWindow" id="scrolledwindow1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="shadow_type">GTK_SHADOW_IN</property>
+                    <child>
+                      <widget class="GtkTextView" id="changelog_view">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox11">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label22">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="add_log_checkbutton">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Add Log Message to ChangeLog file</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label7">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Select files to Commit:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox7">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label8">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkScrolledWindow" id="sw_view">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="shadow_type">GTK_SHADOW_IN</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox17">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label24">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkProgressBar" id="status_progress_bar">
+                    <property name="visible">True</property>
+                    <property name="text" translatable="yes">Retrieving status...</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">5</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox8">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label23">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">  </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="select_all_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="label" translatable="no">gtk-select-all</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="clear_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="label" translatable="no">gtk-clear</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">6</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area3">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button6">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button5">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-3</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkDialog" id="update_dialog">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Update repository</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox4">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="update_main_box">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label11">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Directory to update:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox10">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label12">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkFileChooserButton" id="dir_button">
+                    <property name="visible">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label9">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Information:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox9">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label10">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkScrolledWindow" id="scrolledwindow2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="shadow_type">GTK_SHADOW_IN</property>
+                    <child>
+                      <widget class="GtkTreeView" id="update_treeview">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="headers_clickable">True</property>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area4">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button8">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-refresh</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button7">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-close</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-7</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkDialog" id="settings_dialog">
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox5">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="main_box">
+            <property name="visible">True</property>
+            <property name="border_width">12</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label13">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Diff program:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox12">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label14">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label15">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Program name:</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="program_name">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="padding">6</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox13">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label16">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label17">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Line argument:</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="line_argument">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area5">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button10">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button9">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-5</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkDialog" id="diff_dialog">
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox6">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="diff_main_box">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label18">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Diff options:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox14">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label19">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="use_configured_program">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Use configured program to view the diff</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox15">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label20">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="save_diff">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Save the diff file</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox16">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label21">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">        </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="diff_filename_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="diff_find">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="label" translatable="no">gtk-find</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area6">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button12">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button11">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkDialog" id="checkout_dialog">
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox7">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="checkout_main_box">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label25">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Directory to checkout:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox18">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="label26">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">  </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="path_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="dir_find_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="label" translatable="no">gtk-find</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label29">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Subversion URL:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox20">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label30">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="url_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="tooltip_text">svn+ssh://[login ]svn gnome org/svn/[module]/trunk</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label27">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Information:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox19">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label28">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkScrolledWindow" id="scrolledwindow3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="shadow_type">GTK_SHADOW_IN</property>
+                    <child>
+                      <widget class="GtkTreeView" id="checkout_treeview">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="headers_clickable">True</property>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">5</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area7">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button14">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-apply</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-10</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button13">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-close</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

Added: trunk/plugins/subversion/subversion.gtranslator-plugin.desktop.in
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion.gtranslator-plugin.desktop.in	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,9 @@
+[Gtranslator Plugin]
+Module=subversion
+IAge=2
+_Name=Subversion
+_Description=A Subversion client plugin based on libsvn.
+Icon=subversion-icon
+Authors=Ignacio Casal Quinteiro  <nacho resa gmail com>
+Copyright=Copyright @ 2008 Ignacio Casal Quinteiro
+Website=http://gtranslator.sf.net

Added: trunk/plugins/subversion/svn-add-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-add-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,119 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-add-command.h"
+
+struct _SvnAddCommandPriv
+{
+	gchar *path;
+	gboolean force;
+	gboolean recursive;
+};
+
+G_DEFINE_TYPE (SvnAddCommand, svn_add_command, SVN_TYPE_COMMAND);
+
+static void
+svn_add_command_init (SvnAddCommand *self)
+{
+	self->priv = g_new0 (SvnAddCommandPriv, 1);
+}
+
+static void
+svn_add_command_finalize (GObject *object)
+{
+	SvnAddCommand *self;
+	
+	self = SVN_ADD_COMMAND (object);
+	
+	g_free (self->priv->path);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_add_command_parent_class)->finalize (object);
+}
+
+static guint
+svn_add_command_run (GtranslatorCommand *command)
+{
+	SvnAddCommand *self;
+	SvnCommand *svn_command;
+	svn_error_t *error;
+	svn_depth_t depth;
+	
+	self = SVN_ADD_COMMAND (command);
+	svn_command = SVN_COMMAND (command);
+
+	if (self->priv->recursive == TRUE)
+		depth = svn_depth_infinity;
+	else depth = svn_depth_empty;
+	
+	error = svn_client_add4 (self->priv->path,
+							 depth,
+							 self->priv->force,
+							 FALSE,
+							 FALSE, 
+							 svn_command_get_client_context (svn_command), 
+							 svn_command_get_pool (svn_command));
+
+	if (error)
+	{
+		svn_command_set_error (svn_command, error);
+		return 1;
+	}
+	
+	return 0;
+}
+
+static void
+svn_add_command_class_init (SvnAddCommandClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass *command_class = GTR_COMMAND_CLASS (klass);
+
+	object_class->finalize = svn_add_command_finalize;
+	command_class->run = svn_add_command_run;
+}
+
+
+SvnAddCommand *
+svn_add_command_new (const gchar *path, gboolean force, gboolean recursive)
+{
+	SvnAddCommand *self;
+	
+	self = g_object_new (SVN_TYPE_ADD_COMMAND, NULL);
+	self->priv->path = svn_command_make_canonical_path (SVN_COMMAND (self),
+														path);
+	self->priv->force = force;
+	self->priv->recursive = recursive;
+	
+	return self;
+}
+
+void
+svn_add_command_destroy (SvnAddCommand *self)
+{
+	g_object_unref (self);
+}

Added: trunk/plugins/subversion/svn-add-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-add-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,65 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_ADD_COMMAND_H_
+#define _SVN_ADD_COMMAND_H_
+
+#include <glib-object.h>
+#include "svn-command.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_ADD_COMMAND             (svn_add_command_get_type ())
+#define SVN_ADD_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_ADD_COMMAND, SvnAddCommand))
+#define SVN_ADD_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_ADD_COMMAND, SvnAddCommandClass))
+#define SVN_IS_ADD_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_ADD_COMMAND))
+#define SVN_IS_ADD_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_ADD_COMMAND))
+#define SVN_ADD_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_ADD_COMMAND, SvnAddCommandClass))
+
+typedef struct _SvnAddCommandClass SvnAddCommandClass;
+typedef struct _SvnAddCommand SvnAddCommand;
+typedef struct _SvnAddCommandPriv SvnAddCommandPriv;
+
+struct _SvnAddCommandClass
+{
+	SvnCommandClass parent_class;
+};
+
+struct _SvnAddCommand
+{
+	SvnCommand parent_instance;
+	
+	SvnAddCommandPriv *priv;
+};
+
+GType svn_add_command_get_type (void) G_GNUC_CONST;
+SvnAddCommand * svn_add_command_new (const gchar *path, gboolean force, gboolean recursive);
+void svn_add_command_destroy (SvnAddCommand *self);
+
+G_END_DECLS
+
+#endif /* _SVN_ADD_COMMAND_H_ */

Added: trunk/plugins/subversion/svn-cat-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-cat-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,169 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-cat-command.h"
+
+struct _SvnCatCommandPriv
+{
+	gchar *path;
+	glong revision;
+	GQueue *output;
+};
+
+G_DEFINE_TYPE (SvnCatCommand, svn_cat_command, SVN_TYPE_COMMAND);
+
+static void
+svn_cat_command_init (SvnCatCommand *self)
+{
+	self->priv = g_new0 (SvnCatCommandPriv, 1);
+}
+
+static void
+svn_cat_command_finalize (GObject *object)
+{
+	SvnCatCommand *self;
+	GList *current_output;
+	
+	self = SVN_CAT_COMMAND (object);
+	
+	g_free (self->priv->path);
+	
+	current_output = self->priv->output->head;
+	
+	while (current_output)
+	{
+		g_free (current_output->data);
+		current_output = g_list_next (current_output);
+	}
+	
+	g_queue_free (self->priv->output);
+	
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_cat_command_parent_class)->finalize (object);
+}
+
+static guint
+svn_cat_command_run (GtranslatorCommand *command)
+{
+	SvnCatCommand *self;
+	SvnCommand *svn_command;
+	svn_opt_revision_t revision;
+	svn_opt_revision_t peg_revision;
+	svn_stream_t *cat_stream;
+	apr_file_t *cat_input;
+	apr_file_t *cat_output;
+	apr_size_t read_size;
+	gchar *line;
+	svn_error_t *error;
+	apr_status_t apr_error;
+	
+	self = SVN_CAT_COMMAND (command);
+	svn_command = SVN_COMMAND (command);
+	
+	apr_file_pipe_create (&cat_output, &cat_input, 
+						  svn_command_get_pool (svn_command));
+	apr_file_pipe_timeout_set (cat_output, 0);
+	apr_file_pipe_timeout_set (cat_input, 0);
+	cat_stream = svn_stream_from_aprfile2 (cat_input, FALSE, 
+										   svn_command_get_pool (svn_command));
+	
+	revision.kind = svn_opt_revision_base;
+	revision.value.number = self->priv->revision;
+	peg_revision.kind = svn_opt_revision_unspecified;
+	
+	error = svn_client_cat2 (cat_stream,
+							 self->priv->path,
+							 &peg_revision,
+							 &revision,
+							 svn_command_get_client_context (svn_command),
+							 svn_command_get_pool (svn_command));
+	
+	if (error)
+	{
+		svn_command_set_error (svn_command, error);
+		return 1;
+	}
+	
+	while (apr_file_eof (cat_output) != APR_EOF)
+	{
+		read_size = 80;
+		line = g_new0 (gchar, (read_size + 1));
+		
+		apr_error = apr_file_read (cat_output, line, &read_size);
+		
+		if (apr_error)
+			break;
+		
+		if (strlen (line))
+		{
+			gtranslator_async_command_lock (GTR_ASYNC_COMMAND (command));
+			g_queue_push_tail (self->priv->output, g_strdup (line));
+			gtranslator_async_command_unlock (GTR_ASYNC_COMMAND (command));
+			
+			g_free (line);
+			
+			gtranslator_command_notify_data_arrived (command);
+		}
+	}
+								 
+	return 0;
+}
+
+static void
+svn_cat_command_class_init (SvnCatCommandClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass* command_class = GTR_COMMAND_CLASS (klass);
+
+	object_class->finalize = svn_cat_command_finalize;
+	command_class->run = svn_cat_command_run;
+}
+
+
+SvnCatCommand *
+svn_cat_command_new (const gchar *path, glong revision)
+{
+	SvnCatCommand *self;
+	
+	self = g_object_new (SVN_TYPE_CAT_COMMAND, NULL);
+	self->priv->path = svn_command_make_canonical_path (SVN_COMMAND (self),
+														path);
+	self->priv->revision = revision;
+	self->priv->output = g_queue_new ();
+	
+	return self;
+}
+
+void
+svn_cat_command_destroy (SvnCatCommand *self)
+{
+	g_object_unref (self);
+}
+
+GQueue *
+svn_cat_command_get_output (SvnCatCommand *self)
+{
+	return self->priv->output;
+}

Added: trunk/plugins/subversion/svn-cat-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-cat-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,63 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_CAT_COMMAND_H_
+#define _SVN_CAT_COMMAND_H_
+
+#include <glib-object.h>
+#include "svn-command.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_CAT_COMMAND             (svn_cat_command_get_type ())
+#define SVN_CAT_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_CAT_COMMAND, SvnCatCommand))
+#define SVN_CAT_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_CAT_COMMAND, SvnCatCommandClass))
+#define SVN_IS_CAT_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_CAT_COMMAND))
+#define SVN_IS_CAT_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_CAT_COMMAND))
+#define SVN_CAT_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_CAT_COMMAND, SvnCatCommandClass))
+
+typedef struct _SvnCatCommandClass SvnCatCommandClass;
+typedef struct _SvnCatCommand SvnCatCommand;
+typedef struct _SvnCatCommandPriv SvnCatCommandPriv;
+
+struct _SvnCatCommandClass
+{
+	SvnCommandClass parent_class;
+};
+
+struct _SvnCatCommand
+{
+	SvnCommand parent_instance;
+	
+	SvnCatCommandPriv *priv;
+};
+
+GType svn_cat_command_get_type (void) G_GNUC_CONST;
+SvnCatCommand * svn_cat_command_new (const gchar *path, glong revision);
+void svn_cat_command_destroy (SvnCatCommand *self);
+GQueue *svn_cat_command_get_output (SvnCatCommand *self);
+
+G_END_DECLS
+
+#endif /* _SVN_CAT_COMMAND_H_ */

Added: trunk/plugins/subversion/svn-checkout-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-checkout-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "svn-checkout-command.h"
+
+struct _SvnCheckoutCommandPriv
+{
+	gchar *url;
+	gchar *path;
+};
+
+G_DEFINE_TYPE (SvnCheckoutCommand, svn_checkout_command, SVN_TYPE_COMMAND);
+
+static void
+svn_checkout_command_init (SvnCheckoutCommand *self)
+{	
+	self->priv = g_new0 (SvnCheckoutCommandPriv, 1);
+}
+
+static void
+svn_checkout_command_finalize (GObject *object)
+{
+	SvnCheckoutCommand *self;
+	
+	self = SVN_CHECKOUT_COMMAND (object);
+	
+	g_free (self->priv->url);
+	g_free (self->priv->path);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_checkout_command_parent_class)->finalize (object);
+}
+
+static guint
+svn_checkout_command_run (GtranslatorCommand *command)
+{
+	SvnCheckoutCommand *self;
+	SvnCommand *svn_command;
+	svn_opt_revision_t revision;
+	svn_opt_revision_t peg_revision;
+	svn_revnum_t revnum;
+	svn_error_t *error = NULL;
+	svn_revnum_t revision_number;
+	gchar *revision_message;
+	
+	self = SVN_CHECKOUT_COMMAND (command);
+	svn_command = SVN_COMMAND (command);
+	
+	revision.kind = svn_opt_revision_head;
+	peg_revision.kind = svn_opt_revision_unspecified;
+	
+	error = svn_client_checkout3 (&revnum,
+				      self->priv->url,
+				      self->priv->path,
+				      &peg_revision,
+				      &revision,
+				      svn_depth_unknown,
+				      TRUE,
+				      FALSE,
+				      svn_command_get_client_context (svn_command),
+				      svn_command_get_pool (svn_command));
+	
+	if (error)
+	{
+		svn_command_set_error (svn_command, error);
+		return 1;
+	}
+	
+	return 0;
+}
+
+static void
+svn_checkout_command_class_init (SvnCheckoutCommandClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass *command_class = GTR_COMMAND_CLASS (klass);
+
+	object_class->finalize = svn_checkout_command_finalize;
+	command_class->run = svn_checkout_command_run;
+}
+
+
+SvnCheckoutCommand *
+svn_checkout_command_new (const gchar *url, const gchar *path)
+{
+	SvnCheckoutCommand *self;
+	
+	self = g_object_new (SVN_TYPE_CHECKOUT_COMMAND, NULL);
+	
+	self->priv->url = svn_command_make_canonical_path (SVN_COMMAND (self),
+							    (gchar*)url);
+	self->priv->path = svn_command_make_canonical_path (SVN_COMMAND (self),
+							    (gchar*)path);
+	
+	return self;
+}
+
+void
+svn_checkout_command_destroy (SvnCheckoutCommand *self)
+{
+	g_object_unref (self);
+}

Added: trunk/plugins/subversion/svn-checkout-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-checkout-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _SVN_CHECKOUT_COMMAND_H_
+#define _SVN_CHECKOUT_COMMAND_H_
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include "svn-command.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_CHECKOUT_COMMAND             (svn_checkout_command_get_type ())
+#define SVN_CHECKOUT_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_CHECKOUT_COMMAND, SvnCheckoutCommand))
+#define SVN_CHECKOUT_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_CHECKOUT_COMMAND, SvnCheckoutCommandClass))
+#define SVN_IS_CHECKOUT_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_CHECKOUT_COMMAND))
+#define SVN_IS_CHECKOUT_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_CHECKOUT_COMMAND))
+#define SVN_CHECKOUT_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_CHECKOUT_COMMAND, SvnCheckoutCommandClass))
+
+typedef struct _SvnCheckoutCommandClass SvnCheckoutCommandClass;
+typedef struct _SvnCheckoutCommand SvnCheckoutCommand;
+typedef struct _SvnCheckoutCommandPriv SvnCheckoutCommandPriv;
+
+struct _SvnCheckoutCommandClass
+{
+	SvnCommandClass parent_class;
+};
+
+struct _SvnCheckoutCommand
+{
+	SvnCommand parent_instance;
+	
+	SvnCheckoutCommandPriv *priv;
+};
+
+GType svn_checkout_command_get_type (void) G_GNUC_CONST;
+SvnCheckoutCommand * svn_checkout_command_new (const gchar *url, const gchar *path);
+void svn_checkout_command_destroy (SvnCheckoutCommand *self);
+
+G_END_DECLS
+
+#endif /* _SVN_CHECKOUT_COMMAND_H_ */

Added: trunk/plugins/subversion/svn-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,708 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-command.h"
+#include "utils.h"
+#include <glib/gi18n.h>
+
+struct _SvnCommandPriv
+{
+	svn_client_ctx_t *client_context;
+	apr_pool_t *pool;
+	GQueue *info_messages;
+	GMutex *ui_lock;
+	gboolean main_thread_has_ui_lock;
+};
+
+G_DEFINE_TYPE (SvnCommand, svn_command, GTR_TYPE_ASYNC_COMMAND);
+
+static gboolean
+svn_command_acquire_ui_lock (SvnCommand *self)
+{
+	gboolean got_lock;
+	
+	if (!self->priv->main_thread_has_ui_lock)
+	{
+		got_lock = g_mutex_trylock (self->priv->ui_lock);
+		
+		if (got_lock)
+			self->priv->main_thread_has_ui_lock = TRUE;
+		
+		return !got_lock;
+	}
+	else
+		return FALSE;
+}
+
+static gboolean
+svn_command_release_ui_lock (GMutex *ui_lock)
+{
+	g_mutex_unlock (ui_lock);
+	g_mutex_free (ui_lock);
+	
+	return FALSE;
+}
+
+/* Auth functions */
+/* In order to prevent deadlocking when Subversion prompts for something, we
+ * have to make sure that no GTK calls are made from the command threads by way
+ * of the authentication baton. To do this, the dialog code will be called from
+ * idle sources. */
+
+/* svn_auth_simple_prompt_func_cb argumements */
+typedef struct
+{
+	svn_auth_cred_simple_t **cred;
+	void *baton;
+	gchar *realm;
+	gchar *username;
+	svn_boolean_t may_save;
+	apr_pool_t *pool;
+	svn_error_t *error;
+} SimplePromptArgs;
+
+/* svn_auth_ssl_server_trust_prompt_func_cb arguements */
+typedef struct
+{
+	svn_auth_cred_ssl_server_trust_t **cred;
+	void *baton; 
+	gchar *realm;
+	apr_uint32_t failures;
+	svn_auth_ssl_server_cert_info_t *cert_info;
+	svn_boolean_t may_save;
+	apr_pool_t *pool;
+	svn_error_t *error;
+} SSLServerTrustArgs;
+
+static gboolean
+simple_prompt (SimplePromptArgs *args)
+{
+	GtkWidget* svn_user_auth;
+	GtkWidget* auth_realm;
+	GtkWidget* username_entry;
+	GtkWidget* password_entry;
+	GtkWidget* remember_pwd;
+	GtkWidget *error_widget;
+	gboolean ret;
+	svn_error_t *err = NULL;
+	SvnCommand *svn_command;
+
+	ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+											   "svn_user_auth",
+											   &error_widget,
+											   
+											   "svn_user_auth", &svn_user_auth,
+											   "auth_realm", &auth_realm,
+											   "username_entry", &username_entry,
+											   "password_entry", &password_entry,
+											   "remember_pwd", &remember_pwd,
+											   
+											   NULL);
+	
+	if(!ret)
+	{
+		GtkWidget *dlg = gtk_dialog_new ();
+		gtk_widget_show (error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+					     error_widget);
+		gtk_dialog_run (GTK_DIALOG (dlg));
+		gtk_widget_destroy (dlg);
+		
+		return FALSE;
+	}
+	
+	gtk_dialog_set_default_response (GTK_DIALOG (svn_user_auth),
+									 GTK_RESPONSE_OK);
+	
+	if (args->realm)
+		gtk_label_set_text (GTK_LABEL (auth_realm), args->realm);
+	if (args->username)
+	{
+		gtk_entry_set_text (GTK_ENTRY (username_entry), args->username);
+		gtk_widget_grab_focus (password_entry);
+	}
+	if (!args->may_save)
+		gtk_widget_set_sensitive(remember_pwd, FALSE);
+		
+	/* Then the dialog is prompted to user and when user clicks ok, the
+	 * values entered, i.e username, password and remember password (true
+	 * by default) should be used to initialized the memebers below. If the
+	 * user cancels the dialog, I think we return an error struct
+	 * appropriately initialized. -- naba
+	 */
+	 
+ 	switch (gtk_dialog_run (GTK_DIALOG (svn_user_auth)))
+	{
+		case GTK_RESPONSE_OK:
+		{
+			*args->cred = apr_pcalloc (args->pool, sizeof(*(args->cred)));
+			(*(args->cred))->may_save = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
+															       (remember_pwd));
+			(*(args->cred))->username = apr_pstrdup (args->pool,
+								 	  gtk_entry_get_text(GTK_ENTRY(username_entry)));
+			(*(args->cred))->password = apr_pstrdup (args->pool,
+								 	  gtk_entry_get_text(GTK_ENTRY(password_entry)));
+															 			
+			err = SVN_NO_ERROR;
+			break;
+		}
+		default:
+			err = svn_error_create (SVN_ERR_AUTHN_CREDS_UNAVAILABLE, NULL,
+									_("Authentication canceled"));
+									 
+			break;
+	}
+	gtk_widget_destroy (svn_user_auth);
+	args->error = err;
+	
+	/* Release because main thread should already have the lock */
+	svn_command = SVN_COMMAND (args->baton);
+	svn_command_unlock_ui (svn_command);
+	
+	return FALSE;
+}
+
+static gboolean
+ssl_server_trust_prompt (SSLServerTrustArgs *args)
+{
+	GtkWidget* svn_server_trust;
+	GtkWidget* auth_realm;
+	GtkWidget* server_info;
+	GtkWidget* remember_check;
+	GtkWidget *error_widget;
+	gboolean ret;
+	svn_error_t *err = NULL;
+	gchar* info;
+	SvnCommand *svn_command;
+	
+	ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+											   "svn_server_trust",
+											   &error_widget,
+											   
+											   "svn_server_trust", &svn_server_trust,
+											   "realm_label", &auth_realm,
+											   "server_info_label", &server_info,
+											   "remember_check", &remember_check,
+											   
+											   NULL);
+	
+	if(!ret)
+	{
+		GtkWidget *dlg = gtk_dialog_new ();
+		gtk_widget_show (error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+					     error_widget);
+		gtk_dialog_run (GTK_DIALOG (dlg));
+		gtk_widget_destroy (dlg);
+		
+		return FALSE;
+	}
+	
+	if (args->realm)
+		gtk_label_set_text (GTK_LABEL (auth_realm), args->realm);
+	
+	info = g_strconcat(_("Hostname: "), args->cert_info->hostname, "\n",
+					   _("Fingerprint: "), args->cert_info->fingerprint, "\n",
+					   _("Valid from: "), args->cert_info->valid_from, "\n",
+					   _("Valid until: "), args->cert_info->valid_until, "\n",
+					   _("Issuer DN: "), args->cert_info->issuer_dname, "\n",
+					   _("DER certificate: "), args->cert_info->ascii_cert, "\n",
+					   NULL);
+	gtk_label_set_text (GTK_LABEL (server_info), info);
+	
+	if (!args->may_save)
+		gtk_widget_set_sensitive(remember_check, FALSE);
+	
+	gtk_dialog_set_default_response (GTK_DIALOG (svn_server_trust), GTK_RESPONSE_YES);
+
+	
+	switch (gtk_dialog_run(GTK_DIALOG(svn_server_trust)))
+	{
+		case GTK_RESPONSE_YES:
+			*args->cred = apr_pcalloc (args->pool, 
+									   sizeof(*(args->cred)));
+			(*(args->cred))->may_save = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
+															 	   (remember_check));
+			err = SVN_NO_ERROR;
+		/* TODO: Set bitmask for accepted_failures */
+			break;
+		default:
+			err = svn_error_create (SVN_ERR_AUTHN_CREDS_UNAVAILABLE, NULL,
+									_("Authentication canceled"));									 
+			break;
+	}
+	gtk_widget_destroy (svn_server_trust);
+	args->error = err;
+	
+	/* Release because main thread should already have the lock */
+	svn_command = SVN_COMMAND (args->baton);
+	svn_command_unlock_ui (svn_command);
+	
+	return FALSE;
+}
+
+/* User authentication prompts handlers */
+static svn_error_t*
+svn_auth_simple_prompt_func_cb (svn_auth_cred_simple_t **cred, void *baton,
+								const char *realm, const char *username,
+								svn_boolean_t may_save, apr_pool_t *pool)
+{
+	SimplePromptArgs *args;
+	SvnCommand *svn_command;
+	svn_error_t *error;
+	
+	args = g_new0 (SimplePromptArgs, 1);
+	args->cred = cred;
+	args->baton = baton;
+	args->realm = g_strdup (realm);
+	args->username = g_strdup (username);
+	args->may_save = may_save;
+	args->pool = pool;
+	
+	svn_command = SVN_COMMAND (baton);
+	
+	g_idle_add ((GSourceFunc) simple_prompt, args);
+	
+	svn_command_lock_ui (svn_command);
+	svn_command_unlock_ui (svn_command);
+	
+	error = args->error;
+	g_free (args->realm);
+	g_free (args->username);
+	g_free (args);
+	
+	return error;
+
+}
+
+static svn_error_t*
+svn_auth_ssl_server_trust_prompt_func_cb (svn_auth_cred_ssl_server_trust_t **cred,
+										  void *baton, const char *realm,
+										  apr_uint32_t failures,
+										  const svn_auth_ssl_server_cert_info_t *cert_info,
+										  svn_boolean_t may_save,
+										  apr_pool_t *pool)
+{
+	SSLServerTrustArgs *args;
+	SvnCommand *svn_command;
+	svn_error_t *error;
+	
+	args = g_new0 (SSLServerTrustArgs, 1);
+	args->cred = cred;
+	args->baton = baton;
+	args->realm = g_strdup (realm);
+	args->failures = failures;
+	args->cert_info = g_memdup (cert_info, 
+								sizeof (svn_auth_ssl_server_cert_info_t));
+	args->may_save = may_save;
+	args->pool = pool;
+	
+	svn_command = SVN_COMMAND (baton);
+	
+	g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+					 (GSourceFunc) ssl_server_trust_prompt, args, NULL);
+	
+	svn_command_lock_ui (svn_command);
+	svn_command_unlock_ui (svn_command);
+	
+	error = args->error;
+	g_free (args->realm);
+	g_free (args->cert_info);
+	g_free (args);
+	
+	return error;
+}
+
+static svn_error_t*
+svn_auth_ssl_client_cert_prompt_func_cb (svn_auth_cred_ssl_client_cert_t **cred,
+										 void *baton, const char *realm,
+										 svn_boolean_t may_save,
+										 apr_pool_t *pool)
+{
+	
+	/* Ask for the file where client certificate of authenticity is.
+	 * I think it is some sort of private key. */
+	return SVN_NO_ERROR;
+}
+
+static svn_error_t*
+svn_auth_ssl_client_cert_pw_prompt_func_cb (svn_auth_cred_ssl_client_cert_pw_t **cred,
+											void *baton, const char *realm,
+											svn_boolean_t may_save,
+											apr_pool_t *pool)
+{
+	
+	/* Prompt for password only. I think it is pass-phrase of the above key. */
+	return SVN_NO_ERROR;;
+}
+
+/* Notification callback to handle notifications from Subversion itself */
+static void
+on_svn_notify (gpointer baton,
+			   const svn_wc_notify_t *notify,
+			   apr_pool_t *pool)
+{
+	SvnCommand *self;
+	gchar *action_message;
+	gchar *state_message;
+	
+	self = SVN_COMMAND (baton);
+	action_message = NULL;
+	state_message = NULL;
+	
+	switch (notify->action)
+	{
+		case svn_wc_notify_delete:
+			action_message = g_strdup_printf (_("Deleted: %s"), notify->path);
+			break;
+		case svn_wc_notify_add:
+			action_message = g_strdup_printf (_("Added: %s"), notify->path);
+			break;
+		case svn_wc_notify_revert:
+			action_message = g_strdup_printf (_("Reverted: %s"), notify->path);
+			break;
+		case svn_wc_notify_failed_revert:
+			action_message = g_strdup_printf (_("Revert failed: %s"), 
+											  notify->path);
+			break;
+		case svn_wc_notify_resolved:
+			action_message = g_strdup_printf (_("Resolved: %s"), notify->path);
+			break;
+		case svn_wc_notify_update_delete:
+			action_message = g_strdup_printf (_("Deleted: %s"), notify->path);
+			break;
+		case svn_wc_notify_update_update:
+			action_message = g_strdup_printf (_("Updated: %s"), notify->path);
+			break;
+		case svn_wc_notify_update_add:
+			action_message = g_strdup_printf (_("Added: %s"), notify->path);
+			break;
+		case svn_wc_notify_update_external:
+			action_message = g_strdup_printf (_("Externally Updated: %s"), 
+									   notify->path);
+			break;
+		case svn_wc_notify_commit_modified:
+			action_message = g_strdup_printf (_("Commit Modified: %s"), 
+											  notify->path);
+			break;
+		case svn_wc_notify_commit_added:
+			action_message = g_strdup_printf (_("Commit Added: %s"), notify->path);
+			break;
+		case svn_wc_notify_commit_deleted:
+			action_message = g_strdup_printf (_("Commit Deleted: %s"), 
+											  notify->path);
+			break;
+		case svn_wc_notify_commit_replaced:
+			action_message = g_strdup_printf (_("Commit Replaced: %s"), 
+											  notify->path);
+			break;
+		case svn_wc_notify_copy:
+			action_message = g_strdup_printf (_("Created File: %s"), notify->path);
+			break;
+		default:
+			break;
+	}
+	
+	if (action_message)
+	{
+		svn_command_push_info (self, action_message);
+		g_free (action_message);
+	}
+	
+	switch (notify->content_state)
+	{
+		case svn_wc_notify_state_changed:
+			state_message = g_strdup_printf (_("Modified: %s"), notify->path);
+			break;
+		case svn_wc_notify_state_merged:
+			state_message = g_strdup_printf (_("Merged: %s"), notify->path);
+			break;
+		case svn_wc_notify_state_conflicted:
+			state_message = g_strdup_printf (_("Conflicted: %s"), 
+											 notify->path);
+			break;
+		case svn_wc_notify_state_missing:
+			state_message = g_strdup_printf (_("Missing: %s"), notify->path);
+			break;
+		case svn_wc_notify_state_obstructed:
+			state_message = g_strdup_printf (_("Obstructed: %s"), notify->path);
+			break;
+		default:
+			break;
+	}
+	
+	if (state_message)
+	{
+		svn_command_push_info (self, state_message);
+		g_free (state_message);
+	}
+}
+
+static void
+svn_command_init (SvnCommand *self)
+{
+	svn_auth_baton_t *auth_baton;
+	apr_array_header_t *providers;
+	svn_auth_provider_object_t *provider;
+	
+	self->priv = g_new0 (SvnCommandPriv, 1);
+
+	self->priv->pool = svn_pool_create (NULL);
+	svn_client_create_context (&self->priv->client_context, self->priv->pool);
+	self->priv->client_context->notify_func2 = on_svn_notify;
+	self->priv->client_context->notify_baton2 = self;
+
+	svn_config_get_config (&(self->priv->client_context)->config,
+						   NULL, /* default dir */
+						   self->priv->pool);
+
+	self->priv->info_messages = g_queue_new ();
+	self->priv->ui_lock = g_mutex_new ();
+
+	/* Make sure that the main thread holds the lock */
+	g_idle_add ((GSourceFunc) svn_command_acquire_ui_lock, self);
+	
+	/* Fill in the auth baton callbacks */
+	providers = apr_array_make (self->priv->pool, 1, 
+								sizeof (svn_auth_provider_object_t *));
+	
+	/* Provider that authenticates username/password from ~/.subversion */
+	provider = apr_pcalloc (self->priv->pool, sizeof(*provider));
+	svn_client_get_simple_provider (&provider, self->priv->pool);
+	*(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+	
+	/* Provider that authenticates server trust from ~/.subversion */
+	provider = apr_pcalloc (self->priv->pool, sizeof(*provider));
+	svn_client_get_ssl_server_trust_file_provider (&provider, self->priv->pool);
+	*(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+	
+	/* Provider that authenticates client cert from ~/.subversion */
+	provider = apr_pcalloc (self->priv->pool, sizeof(*provider));
+	svn_client_get_ssl_client_cert_file_provider (&provider, self->priv->pool);
+	*(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+	
+	/* Provider that authenticates client cert password from ~/.subversion */
+	provider = apr_pcalloc (self->priv->pool, sizeof(*provider));
+	svn_client_get_ssl_client_cert_pw_file_provider (&provider, 
+													 self->priv->pool);
+	*(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+	
+	/* Provider that prompts for username/password */
+	provider = apr_pcalloc (self->priv->pool, sizeof(*provider));
+	svn_client_get_simple_prompt_provider(&provider,
+										  svn_auth_simple_prompt_func_cb,
+										  self, 3, self->priv->pool);
+	*(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+	
+	/* Provider that prompts for server trust */
+	provider = apr_pcalloc (self->priv->pool, sizeof(*provider));
+	svn_client_get_ssl_server_trust_prompt_provider (&provider,
+													 svn_auth_ssl_server_trust_prompt_func_cb,
+													 self, 
+													 self->priv->pool);
+	*(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+	
+	/* Provider that prompts for client certificate file */
+	provider = apr_pcalloc (self->priv->pool, sizeof(*provider));
+	svn_client_get_ssl_client_cert_prompt_provider (&provider,
+													svn_auth_ssl_client_cert_prompt_func_cb,
+													NULL, 3, self->priv->pool);
+	*(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+	
+	/* Provider that prompts for client certificate file password */
+	provider = apr_pcalloc (self->priv->pool, sizeof(*provider));
+	svn_client_get_ssl_client_cert_pw_prompt_provider (&provider,
+													   svn_auth_ssl_client_cert_pw_prompt_func_cb,
+													   NULL, 3, 
+													   self->priv->pool);
+	*(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+	
+	svn_auth_open (&auth_baton, providers, self->priv->pool);
+	self->priv->client_context->auth_baton = auth_baton;
+}
+
+static void
+svn_command_finalize (GObject *object)
+{
+	SvnCommand *self;
+	GList *current_message_line;
+	
+	self = SVN_COMMAND (object);
+	
+	svn_pool_clear (self->priv->pool);
+	
+	current_message_line = self->priv->info_messages->head;
+	
+	while (current_message_line)
+	{
+		g_free (current_message_line->data);
+		current_message_line = g_list_next (current_message_line);
+	}
+	
+	g_idle_add ((GSourceFunc) svn_command_release_ui_lock, self->priv->ui_lock);
+	
+	g_queue_free (self->priv->info_messages);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_command_parent_class)->finalize (object);
+}
+
+static void
+svn_command_class_init (SvnCommandClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = svn_command_finalize;
+}
+
+
+void
+svn_command_push_info (SvnCommand *self, const gchar *message)
+{
+	gtranslator_async_command_lock (GTR_ASYNC_COMMAND (self));
+	g_queue_push_tail (self->priv->info_messages, g_strdup (message));
+	gtranslator_async_command_unlock (GTR_ASYNC_COMMAND (self));
+	
+	gtranslator_command_notify_data_arrived (GTR_COMMAND (self));
+}
+
+GQueue *
+svn_command_get_info_queue (SvnCommand *self)
+{
+	return self->priv->info_messages;
+}
+
+void
+svn_command_set_error (SvnCommand *self, svn_error_t *error)
+{
+	GString *error_string;
+	svn_error_t *current_error;
+	gchar *error_c_string;
+	
+	error_string = g_string_new ("");
+	current_error = error;
+	
+	while (current_error)
+	{
+		g_string_append (error_string, current_error->message);
+
+		if (current_error->child)
+			g_string_append_c (error_string, '\n');
+		
+		current_error = current_error->child;
+	}
+	
+	error_c_string = g_string_free (error_string, FALSE);
+	gtranslator_async_command_set_error_message (GTR_COMMAND (self), 
+											error_c_string);
+	
+	g_free (error_c_string);
+}
+
+svn_client_ctx_t *
+svn_command_get_client_context (SvnCommand *self)
+{
+	return self->priv->client_context;
+}
+
+apr_pool_t *
+svn_command_get_pool (SvnCommand *self)
+{
+	return self->priv->pool;
+}
+
+void
+svn_command_lock_ui (SvnCommand *self)
+{
+	g_mutex_lock (self->priv->ui_lock);
+	
+	/* Have the main thread acquire the lock as soon as the other thread is done
+	 * with it. The main thread should *not* acqure the lock, only release 
+	 * it. */
+	self->priv->main_thread_has_ui_lock = FALSE;
+	g_idle_add ((GSourceFunc) svn_command_acquire_ui_lock, self);
+}
+
+void
+svn_command_unlock_ui (SvnCommand *self)
+{
+	g_mutex_unlock (self->priv->ui_lock);
+}
+
+gchar *
+svn_command_make_canonical_path (SvnCommand *self, const gchar *path)
+{
+	const gchar *canonical_path;
+	
+	canonical_path = svn_path_canonicalize (path, self->priv->pool);
+	
+	return g_strdup (canonical_path);
+}
+
+svn_opt_revision_t *
+svn_command_get_revision (const gchar *revision)
+{
+	svn_opt_revision_t* svn_revision; 
+	
+	svn_revision = g_new0 (svn_opt_revision_t, 1);
+	
+	/* FIXME: Parse the revision string */
+	svn_revision->kind = svn_opt_revision_head;
+	
+	return svn_revision;
+}
+
+GList *
+svn_command_copy_path_list (GList *list)
+{
+	GList *current_path;
+	GList *new_list;
+	
+	new_list = NULL;
+	current_path = list;
+	
+	while (current_path)
+	{
+		new_list = g_list_append (new_list, g_strdup (current_path->data));
+		current_path = g_list_next (current_path);
+	}
+	
+	return new_list;
+}
+
+void
+svn_command_free_path_list (GList *list)
+{
+	GList *current_path;
+	
+	current_path = list;
+	
+	while (current_path)
+	{
+		g_free (current_path->data);
+		current_path = g_list_next (current_path);
+	}
+	
+	g_list_free (list);
+}

Added: trunk/plugins/subversion/svn-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,88 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_COMMAND_H_
+#define _SVN_COMMAND_H_
+
+#include <glib-object.h>
+#include <svn_client.h>
+#include <svn_pools.h>
+#include <svn_config.h>
+#include <svn_path.h>
+#include "subversion-plugin.h"
+#include "async-command.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_COMMAND             (svn_command_get_type ())
+#define SVN_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_COMMAND, SvnCommand))
+#define SVN_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_COMMAND, SvnCommandClass))
+#define SVN_IS_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_COMMAND))
+#define SVN_IS_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_COMMAND))
+#define SVN_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_COMMAND, SvnCommandClass))
+
+typedef struct _SvnCommandClass SvnCommandClass;
+typedef struct _SvnCommand SvnCommand;
+typedef struct _SvnCommandPriv SvnCommandPriv;
+
+struct _SvnCommandClass
+{
+	GtranslatorAsyncCommandClass parent_class;
+};
+
+struct _SvnCommand
+{
+	GtranslatorAsyncCommand parent_instance;
+	
+	SvnCommandPriv *priv;
+};
+
+GType svn_command_get_type (void) G_GNUC_CONST;
+
+void svn_command_push_info (SvnCommand *self, const gchar *message);
+
+GQueue * svn_command_get_info_queue (SvnCommand *self);
+
+void svn_command_set_error (SvnCommand *self, svn_error_t *error);
+
+svn_client_ctx_t *svn_command_get_client_context (SvnCommand *self);
+
+apr_pool_t *svn_command_get_pool (SvnCommand *self);
+
+void svn_command_lock_ui (SvnCommand *self);
+
+void svn_command_unlock_ui (SvnCommand *self);
+
+gchar *svn_command_make_canonical_path (SvnCommand *self, const gchar *path);
+
+/* Static methods */
+svn_opt_revision_t *svn_command_get_revision (const gchar *revision);
+
+GList *svn_command_copy_path_list (GList *list);
+
+void svn_command_free_path_list (GList *list);
+
+G_END_DECLS
+
+#endif /* _SVN_COMMAND_H_ */

Added: trunk/plugins/subversion/svn-commit-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-commit-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,169 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-commit-command.h"
+
+struct _SvnCommitCommandPriv
+{
+	GList *paths;
+	gchar *log_message;
+	gboolean recursive;
+};
+
+G_DEFINE_TYPE (SvnCommitCommand, svn_commit_command, SVN_TYPE_COMMAND);
+
+static svn_error_t*
+on_log_callback (const char **log_msg,
+				 const char **tmp_file,
+				 apr_array_header_t *commit_items,
+				 void *baton,
+				 apr_pool_t *pool)
+{
+	
+	SvnCommitCommand *self;
+	
+	self = SVN_COMMIT_COMMAND (baton);
+	
+	*log_msg = self->priv->log_message;
+	*tmp_file = NULL;
+	
+	return SVN_NO_ERROR;
+}
+
+static void
+svn_commit_command_init (SvnCommitCommand *self)
+{
+	svn_client_ctx_t *client_context;
+	
+	self->priv = g_new0 (SvnCommitCommandPriv, 1);
+	client_context = svn_command_get_client_context (SVN_COMMAND (self));
+	
+	client_context->log_msg_func = on_log_callback;
+	client_context->log_msg_baton = self;
+	
+}
+
+static void
+svn_commit_command_finalize (GObject *object)
+{
+	SvnCommitCommand *self;
+	
+	self = SVN_COMMIT_COMMAND (object);
+	
+	svn_command_free_path_list (self->priv->paths);
+	g_free (self->priv->log_message);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_commit_command_parent_class)->finalize (object);
+}
+
+static guint
+svn_commit_command_run (GtranslatorCommand *command)
+{
+	SvnCommitCommand *self;
+	SvnCommand *svn_command;
+	GList *current_path;
+	apr_array_header_t *commit_paths;
+	gchar *revision_message;
+	svn_error_t *error;
+	svn_commit_info_t *commit_info;
+	svn_depth_t depth;
+	
+	self = SVN_COMMIT_COMMAND (command);
+	svn_command = SVN_COMMAND (command);
+	current_path = self->priv->paths;
+	commit_paths = apr_array_make (svn_command_get_pool (svn_command),
+								   g_list_length (self->priv->paths), 
+								   sizeof (char *));
+	
+	while (current_path)
+	{
+		/* I just copied this so don't blame me... */
+		(*((const char **) apr_array_push (commit_paths))) = current_path->data;
+		current_path = g_list_next (current_path);
+	}
+	
+	if (self->priv->recursive == TRUE)
+		depth = svn_depth_infinity;
+	else depth = svn_depth_files;
+	
+	error = svn_client_commit4 (&commit_info, 
+								commit_paths, 
+								depth,
+								TRUE,
+								FALSE,
+								NULL,
+								NULL,
+								svn_command_get_client_context (svn_command), 
+								svn_command_get_pool (svn_command));
+
+	if (error)
+	{
+		svn_command_set_error (svn_command, error);
+		return 1;
+	}
+	
+	if (commit_info)
+	{
+		revision_message = g_strdup_printf ("Committed revision %ld.", 
+											commit_info->revision);
+		svn_command_push_info (SVN_COMMAND (command), revision_message);
+		g_free (revision_message);
+	}
+	
+	return 0;
+}
+
+static void
+svn_commit_command_class_init (SvnCommitCommandClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass *command_class = GTR_COMMAND_CLASS (klass);
+
+	object_class->finalize = svn_commit_command_finalize;
+	command_class->run = svn_commit_command_run;
+}
+
+SvnCommitCommand *
+svn_commit_command_new (GList *paths, const gchar *log_message, 
+						gboolean recursive)
+{
+	SvnCommitCommand *self;
+	
+	self = g_object_new (SVN_TYPE_COMMIT_COMMAND, NULL);
+	self->priv->paths = svn_command_copy_path_list (paths);
+	self->priv->log_message = g_strdup (log_message);
+	self->priv->recursive = recursive;
+	
+	return self;
+}
+
+void
+svn_commit_command_destroy (SvnCommitCommand *self)
+{
+	g_object_unref (self);
+}

Added: trunk/plugins/subversion/svn-commit-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-commit-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,66 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_COMMIT_COMMAND_H_
+#define _SVN_COMMIT_COMMAND_H_
+
+#include <glib-object.h>
+#include "svn-command.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_COMMIT_COMMAND             (svn_commit_command_get_type ())
+#define SVN_COMMIT_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_COMMIT_COMMAND, SvnCommitCommand))
+#define SVN_COMMIT_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_COMMIT_COMMAND, SvnCommitCommandClass))
+#define SVN_IS_COMMIT_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_COMMIT_COMMAND))
+#define SVN_IS_COMMIT_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_COMMIT_COMMAND))
+#define SVN_COMMIT_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_COMMIT_COMMAND, SvnCommitCommandClass))
+
+typedef struct _SvnCommitCommandClass SvnCommitCommandClass;
+typedef struct _SvnCommitCommand SvnCommitCommand;
+typedef struct _SvnCommitCommandPriv SvnCommitCommandPriv;
+
+struct _SvnCommitCommandClass
+{
+	SvnCommandClass parent_class;
+};
+
+struct _SvnCommitCommand
+{
+	SvnCommand parent_instance;
+	
+	SvnCommitCommandPriv *priv;
+};
+
+GType svn_commit_command_get_type (void) G_GNUC_CONST;
+SvnCommitCommand * svn_commit_command_new (GList *paths, const gchar *log_message, 
+										   gboolean recursive);
+void svn_commit_command_destroy (SvnCommitCommand *self);
+
+G_END_DECLS
+
+#endif /* _SVN_COMMIT_COMMAND_H_ */

Added: trunk/plugins/subversion/svn-diff-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-diff-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,223 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-diff-command.h"
+
+struct _SvnDiffCommandPriv
+{
+	GQueue *output;
+	gchar *path;
+	glong revision1;
+	glong revision2;
+	gboolean recursive;
+};
+
+G_DEFINE_TYPE (SvnDiffCommand, svn_diff_command, SVN_TYPE_COMMAND);
+
+static void
+svn_diff_command_init (SvnDiffCommand *self)
+{
+	self->priv = g_new0 (SvnDiffCommandPriv, 1);
+	self->priv->output = g_queue_new ();
+}
+
+static void
+svn_diff_command_finalize (GObject *object)
+{
+	SvnDiffCommand *self;
+	GList *current_line;
+	
+	self = SVN_DIFF_COMMAND (object);
+	
+	current_line = self->priv->output->head;
+	
+	while (current_line)
+	{
+		g_free (current_line->data);
+		current_line = g_list_next (current_line);
+	}
+	
+	g_queue_free (self->priv->output);
+	g_free (self->priv->path);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_diff_command_parent_class)->finalize (object);
+}
+
+static guint 
+svn_diff_command_run (GtranslatorCommand *command)
+{
+	SvnDiffCommand *self;
+	SvnCommand *svn_command;
+	svn_opt_revision_t revision1;
+	svn_opt_revision_t revision2;
+	apr_array_header_t *options;
+	apr_file_t *diff_file;
+	gchar file_template[] = "gtranslator-svn-diffXXXXXX";
+	apr_size_t read_size;
+	gchar *line;
+	svn_error_t *error;
+	apr_status_t apr_error;
+	apr_off_t offset;
+	svn_depth_t depth;
+	
+	self = SVN_DIFF_COMMAND (command);
+	svn_command = SVN_COMMAND (self);
+	
+	switch (self->priv->revision1)
+	{
+		case SVN_DIFF_REVISION_NONE:
+			/* Treat this as a diff between working copy and base 
+			 * (show only mods made to the revision of this working copy.) */
+			revision1.kind = svn_opt_revision_base;
+			revision2.kind = svn_opt_revision_working;
+			break;
+		case SVN_DIFF_REVISION_PREVIOUS:
+			/* Diff between selected revision and the one before it.
+			 * This is relative to revision2. */
+			revision1.kind = svn_opt_revision_number;
+			revision1.value.number = self->priv->revision2 - 1;
+			revision2.kind = svn_opt_revision_number;
+			revision2.value.number = self->priv->revision2;
+			break;
+		default:
+			/* Diff between two distinct revisions */
+			revision1.kind = svn_opt_revision_number;
+			revision1.value.number = self->priv->revision1;
+			revision2.kind = svn_opt_revision_number;
+			revision2.value.number = self->priv->revision2;
+			break;
+	}
+	
+	options = apr_array_make(svn_command_get_pool (SVN_COMMAND (command)), 
+							 0, sizeof (char *));
+	
+	apr_file_mktemp (&diff_file, file_template, 0, 
+					 svn_command_get_pool (SVN_COMMAND (command)));
+	
+	if (self->priv->recursive == TRUE)
+		depth = svn_depth_infinity;
+	else depth = svn_depth_empty;
+	
+	error = svn_client_diff4 (options,
+							  self->priv->path,
+							  &revision1,
+							  self->priv->path,
+							  &revision2,
+							  NULL,
+							  depth,
+							  FALSE,
+							  FALSE,
+							  FALSE,
+							  SVN_APR_LOCALE_CHARSET,
+							  diff_file,
+							  NULL,
+							  NULL,
+							  svn_command_get_client_context (svn_command),
+							  svn_command_get_pool (svn_command));
+	
+	if (error)
+	{
+		svn_command_set_error (svn_command, error);
+		return 1;
+	}
+	
+	offset = 0;
+	apr_file_seek (diff_file, APR_SET, &offset);
+	
+	while (apr_file_eof (diff_file) != APR_EOF)
+	{
+		read_size = 80;
+		line = g_new0 (gchar, (read_size + 1));
+		
+		apr_error = apr_file_read (diff_file, line, &read_size);
+
+		if (strlen (line))
+		{
+			gtranslator_async_command_lock (GTR_ASYNC_COMMAND (command));
+			
+			/* Make sure that we only output UTF-8. We could have done this by
+			 * passing in "UTF-8" for header encoding to the diff API, but there
+			 * is the possiblity that an external diff program could be used, in
+			 * which case that arguement wouldn't do anything. As a workaround,
+			 * have the internal diff system return things in the system 
+			 * charset, and make the (hopefully safe) assumption that any 
+			 * external diff program also outputs in the current locale. */
+			g_queue_push_tail (self->priv->output, 
+							   g_locale_to_utf8 (line, read_size, NULL, NULL,
+												 NULL));
+			gtranslator_async_command_unlock (GTR_ASYNC_COMMAND (command));
+			
+			g_free (line);
+			
+			gtranslator_command_notify_data_arrived (command);
+		}
+	}
+	
+	apr_file_close (diff_file);
+	
+	return 0;
+								 
+}
+
+static void
+svn_diff_command_class_init (SvnDiffCommandClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass *command_class = GTR_COMMAND_CLASS (klass);
+
+	object_class->finalize = svn_diff_command_finalize;
+	command_class->run = svn_diff_command_run;
+}
+
+SvnDiffCommand *
+svn_diff_command_new (const gchar *path, glong revision1, glong revision2, 
+					  gboolean recursive)
+{
+	SvnDiffCommand *self;
+	
+	self = g_object_new (SVN_TYPE_DIFF_COMMAND, NULL);
+	self->priv->path = svn_command_make_canonical_path (SVN_COMMAND (self),
+														path);
+	self->priv->revision1 = revision1;
+	self->priv->revision2 = revision2;
+	self->priv->recursive = recursive;
+	
+	return self;
+}
+
+void
+svn_diff_command_destroy (SvnDiffCommand *self)
+{
+	g_object_unref (self);
+}
+
+GQueue *
+svn_diff_command_get_output (SvnDiffCommand *self)
+{
+	return self->priv->output;
+}

Added: trunk/plugins/subversion/svn-diff-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-diff-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,72 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * anjuta is free software.
+ * 
+ * You may 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.
+ * 
+ * anjuta 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 anjuta.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_DIFF_COMMAND_H_
+#define _SVN_DIFF_COMMAND_H_
+
+#include <glib-object.h>
+#include <svn_utf.h>
+#include "svn-command.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_DIFF_COMMAND             (svn_diff_command_get_type ())
+#define SVN_DIFF_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_DIFF_COMMAND, SvnDiffCommand))
+#define SVN_DIFF_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_DIFF_COMMAND, SvnDiffCommandClass))
+#define SVN_IS_DIFF_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_DIFF_COMMAND))
+#define SVN_IS_DIFF_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_DIFF_COMMAND))
+#define SVN_DIFF_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_DIFF_COMMAND, SvnDiffCommandClass))
+
+typedef struct _SvnDiffCommandClass SvnDiffCommandClass;
+typedef struct _SvnDiffCommand SvnDiffCommand;
+typedef struct _SvnDiffCommandPriv SvnDiffCommandPriv;
+
+struct _SvnDiffCommandClass
+{
+	SvnCommandClass parent_class;
+};
+
+struct _SvnDiffCommand
+{
+	SvnCommandClass parent_instance;
+	
+	SvnDiffCommandPriv *priv;
+};
+
+enum
+{
+	SVN_DIFF_REVISION_PREVIOUS = -1,
+	SVN_DIFF_REVISION_NONE = 0
+}; 
+
+GType svn_diff_command_get_type (void) G_GNUC_CONST;
+SvnDiffCommand *svn_diff_command_new (const gchar *path, glong revision1,
+									  glong revision2, gboolean recursive);
+void svn_diff_command_destroy (SvnDiffCommand *self);
+
+GQueue *svn_diff_command_get_output (SvnDiffCommand *self);
+
+G_END_DECLS
+
+#endif /* _SVN_DIFF_COMMAND_H_ */

Added: trunk/plugins/subversion/svn-resolve-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-resolve-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,112 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-resolve-command.h"
+
+struct _SvnResolveCommandPriv
+{
+	GList *paths;
+	gboolean recursive;
+};
+
+G_DEFINE_TYPE (SvnResolveCommand, svn_resolve_command, SVN_TYPE_COMMAND);
+
+static void
+svn_resolve_command_init (SvnResolveCommand *self)
+{	
+	self->priv = g_new0 (SvnResolveCommandPriv, 1);
+}
+
+static void
+svn_resolve_command_finalize (GObject *object)
+{
+	SvnResolveCommand *self;
+	
+	self = SVN_RESOLVE_COMMAND (object);
+	
+	svn_command_free_path_list (self->priv->paths);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_resolve_command_parent_class)->finalize (object);
+}
+
+static guint
+svn_resolve_command_run (GtranslatorCommand *command)
+{
+	SvnResolveCommand *self;
+	SvnCommand *svn_command;
+	GList *current_path;
+	svn_error_t *error;
+	
+	self = SVN_RESOLVE_COMMAND (command);
+	svn_command = SVN_COMMAND (command);
+	current_path = self->priv->paths;
+	
+	while (current_path)
+	{
+		error = svn_client_resolved (current_path->data, 
+									 self->priv->recursive,
+									 svn_command_get_client_context (svn_command), 
+									 svn_command_get_pool (svn_command));
+
+		if (error)
+		{
+			svn_command_set_error (svn_command, error);
+			return 1;
+		}
+		
+		current_path = g_list_next (current_path);
+	}
+	
+	return 0;
+}
+
+static void
+svn_resolve_command_class_init (SvnResolveCommandClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass *command_class = GTR_COMMAND_CLASS (klass);
+
+	object_class->finalize = svn_resolve_command_finalize;
+	command_class->run = svn_resolve_command_run;
+}
+
+
+SvnResolveCommand *
+svn_resolve_command_new (GList *paths, gboolean recursive)
+{
+	SvnResolveCommand *self;
+	
+	self = g_object_new (SVN_TYPE_RESOLVE_COMMAND, NULL);
+	self->priv->paths = svn_command_copy_path_list (paths);
+	self->priv->recursive = recursive;
+	
+	return self;
+}
+
+void
+svn_resolve_command_destroy (SvnResolveCommand *self)
+{
+	g_object_unref (self);
+}

Added: trunk/plugins/subversion/svn-resolve-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-resolve-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,62 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * anjuta is free software.
+ * 
+ * You may 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.
+ * 
+ * anjuta 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 anjuta.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_RESOLVE_COMMAND_H_
+#define _SVN_RESOLVE_COMMAND_H_
+
+#include <glib-object.h>
+#include "svn-command.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_RESOLVE_COMMAND             (svn_resolve_command_get_type ())
+#define SVN_RESOLVE_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_RESOLVE_COMMAND, SvnResolveCommand))
+#define SVN_RESOLVE_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_RESOLVE_COMMAND, SvnResolveCommandClass))
+#define SVN_IS_RESOLVE_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_RESOLVE_COMMAND))
+#define SVN_IS_RESOLVE_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_RESOLVE_COMMAND))
+#define SVN_RESOLVE_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_RESOLVE_COMMAND, SvnResolveCommandClass))
+
+typedef struct _SvnResolveCommandClass SvnResolveCommandClass;
+typedef struct _SvnResolveCommand SvnResolveCommand;
+typedef struct _SvnResolveCommandPriv SvnResolveCommandPriv;
+
+struct _SvnResolveCommandClass
+{
+	SvnCommandClass parent_class;
+};
+
+struct _SvnResolveCommand
+{
+	SvnCommand parent_instance;
+	
+	SvnResolveCommandPriv *priv;
+};
+
+GType svn_resolve_command_get_type (void) G_GNUC_CONST;
+SvnResolveCommand *svn_resolve_command_new (GList *paths, gboolean recursive);
+void svn_resolve_command_destroy (SvnResolveCommand *self);
+
+G_END_DECLS
+
+#endif /* _SVN_RESOLVE_COMMAND_H_ */

Added: trunk/plugins/subversion/svn-status-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-status-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,173 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-status-command.h"
+
+struct _SvnStatusCommandPriv
+{
+	gchar *path;
+	gboolean recursive;
+	gboolean get_all_items;
+	GQueue *status_queue;
+};
+
+G_DEFINE_TYPE (SvnStatusCommand, svn_status_command, SVN_TYPE_COMMAND);
+
+static void
+svn_status_command_init (SvnStatusCommand *self)
+{	
+	self->priv = g_new0 (SvnStatusCommandPriv, 1);
+	self->priv->status_queue = g_queue_new ();	
+}
+
+static void
+svn_status_command_finalize (GObject *object)
+{
+	SvnStatusCommand *self;
+	GList *current_status;
+	
+	self = SVN_STATUS_COMMAND (object);
+	current_status = self->priv->status_queue->head;
+	
+	g_free (self->priv->path);
+	
+	while (current_status)
+	{
+		svn_status_destroy (current_status->data);
+		current_status = g_list_next (current_status);
+	}
+	
+	g_queue_free (self->priv->status_queue);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_status_command_parent_class)->finalize (object);
+}
+
+static void
+on_svn_status_notify (void *baton, const char *path, svn_wc_status2_t *status)
+{
+	SvnStatusCommand *self;
+	SvnStatus *status_object;
+	
+	self = SVN_STATUS_COMMAND (baton);
+	
+	/* Right now we only support text status (no properties.) */
+	
+	switch (status->text_status)
+	{
+		case svn_wc_status_modified:
+		case svn_wc_status_added:
+		case svn_wc_status_deleted:
+		case svn_wc_status_conflicted:
+		case svn_wc_status_missing:
+			status_object = svn_status_new ((gchar *) path, 
+											status->text_status);
+		
+			gtranslator_async_command_lock (GTR_ASYNC_COMMAND (self));
+			g_queue_push_tail (self->priv->status_queue, status_object);
+			gtranslator_async_command_unlock (GTR_ASYNC_COMMAND (self));
+		
+			gtranslator_command_notify_data_arrived (GTR_COMMAND (self));
+		
+			break;
+		default:
+			break;
+	}
+}
+
+static guint 
+svn_status_command_run (GtranslatorCommand *command)
+{
+	SvnStatusCommand *self;
+	SvnCommand *svn_command;
+	svn_opt_revision_t revision;
+	svn_error_t *error;
+	svn_depth_t depth;
+	
+	self = SVN_STATUS_COMMAND (command);
+	svn_command = SVN_COMMAND (command);
+	revision.kind = svn_opt_revision_working;
+	
+	if (self->priv->recursive == TRUE)
+		depth = svn_depth_infinity;
+	else depth = svn_depth_immediates;
+	
+	error = svn_client_status3 (NULL, 
+								self->priv->path, 
+								&revision,
+								on_svn_status_notify, 
+								self, 
+								depth,
+								self->priv->get_all_items, 
+								FALSE, 
+								FALSE,
+								TRUE,
+								NULL,
+								svn_command_get_client_context (svn_command),
+								svn_command_get_pool (svn_command));
+	
+	if (error)
+	{
+		svn_command_set_error (svn_command, error);
+		return 1;
+	}
+	
+	return 0;
+}
+
+static void
+svn_status_command_class_init (SvnStatusCommandClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass *command_class = GTR_COMMAND_CLASS (klass);
+
+	command_class->run = svn_status_command_run;
+	object_class->finalize = svn_status_command_finalize;
+}
+
+SvnStatusCommand *
+svn_status_command_new (const gchar *path, gboolean recursive, gboolean get_all_items)
+{
+	SvnStatusCommand *self;
+	
+	self = g_object_new (SVN_TYPE_STATUS_COMMAND, NULL);
+	self->priv->path = svn_command_make_canonical_path (SVN_COMMAND (self),
+														path);
+	self->priv->recursive = recursive;
+	self->priv->get_all_items = get_all_items;
+	
+	return self;
+}
+
+void
+svn_status_command_destroy (SvnStatusCommand *self)
+{
+	g_object_unref (self);
+}
+
+GQueue *
+svn_status_command_get_status_queue (SvnStatusCommand *self)
+{
+	return self->priv->status_queue;
+}

Added: trunk/plugins/subversion/svn-status-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-status-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,65 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * anjuta is free software.
+ * 
+ * You may 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.
+ * 
+ * anjuta 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 anjuta.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_STATUS_COMMAND_H_
+#define _SVN_STATUS_COMMAND_H_
+
+#include <glib-object.h>
+#include "svn-command.h"
+#include "svn-status.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_STATUS_COMMAND             (svn_status_command_get_type ())
+#define SVN_STATUS_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_STATUS_COMMAND, SvnStatusCommand))
+#define SVN_STATUS_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_STATUS_COMMAND, SvnStatusCommandClass))
+#define SVN_IS_STATUS_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_STATUS_COMMAND))
+#define SVN_IS_STATUS_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_STATUS_COMMAND))
+#define SVN_STATUS_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_STATUS_COMMAND, SvnStatusCommandClass))
+
+typedef struct _SvnStatusCommandClass SvnStatusCommandClass;
+typedef struct _SvnStatusCommand SvnStatusCommand;
+typedef struct _SvnStatusCommandPriv SvnStatusCommandPriv;
+
+struct _SvnStatusCommandClass
+{
+	SvnCommandClass parent_class;
+};
+
+struct _SvnStatusCommand
+{
+	SvnCommand parent_instance;
+	
+	SvnStatusCommandPriv *priv;
+};
+
+GType svn_status_command_get_type (void) G_GNUC_CONST;
+SvnStatusCommand *svn_status_command_new (const gchar *path, gboolean recursive, 
+										  gboolean get_all_items);
+void svn_status_command_destroy (SvnStatusCommand *self);
+GQueue *svn_status_command_get_status_queue (SvnStatusCommand *self);
+
+G_END_DECLS
+
+#endif /* _SVN_STATUS_COMMAND_H_ */

Added: trunk/plugins/subversion/svn-status.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-status.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,115 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-status.h"
+
+struct _SvnStatusPriv
+{
+	gchar *path;
+	enum svn_wc_status_kind status;
+};
+
+G_DEFINE_TYPE (SvnStatus, svn_status, G_TYPE_OBJECT);
+
+static void
+svn_status_init (SvnStatus *self)
+{
+	self->priv = g_new0 (SvnStatusPriv, 1);
+}
+
+static void
+svn_status_finalize (GObject *object)
+{
+	SvnStatus *self;
+	
+	self = SVN_STATUS (object);
+	
+	g_free (self->priv->path);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_status_parent_class)->finalize (object);
+}
+
+static void
+svn_status_class_init (SvnStatusClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = svn_status_finalize;
+}
+
+SvnStatus *
+svn_status_new (gchar *path, enum svn_wc_status_kind status)
+{
+	SvnStatus *self;
+	
+	self = g_object_new (SVN_TYPE_STATUS, NULL);
+	
+	self->priv->path = g_strdup (path);
+	self->priv->status = status;
+	
+	return self;
+}
+
+void
+svn_status_destroy (SvnStatus *self)
+{
+	g_object_unref (self);
+}
+
+gchar *
+svn_status_get_path (SvnStatus *self)
+{
+	return g_strdup (self->priv->path);
+}
+
+GtranslatorVcsStatus
+svn_status_get_vcs_status (SvnStatus *self)
+{
+	GtranslatorVcsStatus status;
+	
+	switch (self->priv->status)
+	{
+		case svn_wc_status_modified:
+			status = GTR_VCS_STATUS_MODIFIED;
+			break;
+		case svn_wc_status_added:
+			status = GTR_VCS_STATUS_ADDED;
+			break;
+		case svn_wc_status_deleted:
+			status = GTR_VCS_STATUS_DELETED;
+			break;
+		case svn_wc_status_conflicted:
+			status = GTR_VCS_STATUS_CONFLICTED;
+			break;
+		case svn_wc_status_missing:
+			status = GTR_VCS_STATUS_MISSING;
+			break;
+		default:
+			status = GTR_VCS_STATUS_NONE;
+			break;
+	}
+	
+	return status;
+}

Added: trunk/plugins/subversion/svn-status.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-status.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,65 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * anjuta is free software.
+ * 
+ * You may 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.
+ * 
+ * anjuta 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 anjuta.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_STATUS_H_
+#define _SVN_STATUS_H_
+
+#include <glib-object.h>
+#include <svn_wc.h>
+#include "vcs-status-tree-view.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_STATUS             (svn_status_get_type ())
+#define SVN_STATUS(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_STATUS, SvnStatus))
+#define SVN_STATUS_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_STATUS, SvnStatusClass))
+#define SVN_IS_STATUS(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_STATUS))
+#define SVN_IS_STATUS_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_STATUS))
+#define SVN_STATUS_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_STATUS, SvnStatusClass))
+
+typedef struct _SvnStatusClass SvnStatusClass;
+typedef struct _SvnStatus SvnStatus;
+typedef struct _SvnStatusPriv SvnStatusPriv;
+
+struct _SvnStatusClass
+{
+	GObjectClass parent_class;
+};
+
+struct _SvnStatus
+{
+	GObject parent_instance;
+	
+	SvnStatusPriv *priv;
+};
+
+GType svn_status_get_type (void) G_GNUC_CONST;
+SvnStatus *svn_status_new (gchar *path, enum svn_wc_status_kind status);
+void svn_status_destroy (SvnStatus *self);
+gchar * svn_status_get_path (SvnStatus *self);
+GtranslatorVcsStatus svn_status_get_vcs_status (SvnStatus *self);
+
+G_END_DECLS
+
+#endif /* _SVN_STATUS_H_ */

Added: trunk/plugins/subversion/svn-update-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-update-command.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,141 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "svn-update-command.h"
+
+struct _SvnUpdateCommandPriv
+{
+	gchar *path;
+	gchar *revision;
+	gboolean recursive;
+};
+
+G_DEFINE_TYPE (SvnUpdateCommand, svn_update_command, SVN_TYPE_COMMAND);
+
+static void
+svn_update_command_init (SvnUpdateCommand *self)
+{	
+	self->priv = g_new0 (SvnUpdateCommandPriv, 1);
+}
+
+static void
+svn_update_command_finalize (GObject *object)
+{
+	SvnUpdateCommand *self;
+	
+	self = SVN_UPDATE_COMMAND (object);
+	
+	g_free (self->priv->path);
+	g_free (self->priv->revision);
+	g_free (self->priv);
+
+	G_OBJECT_CLASS (svn_update_command_parent_class)->finalize (object);
+}
+
+static guint
+svn_update_command_run (GtranslatorCommand *command)
+{
+	SvnUpdateCommand *self;
+	SvnCommand *svn_command;
+	svn_opt_revision_t *revision;
+	apr_array_header_t *update_paths;
+	apr_array_header_t *update_revisions;
+	svn_error_t *error;
+	svn_revnum_t revision_number;
+	gchar *revision_message;
+	svn_depth_t depth;
+	
+	self = SVN_UPDATE_COMMAND (command);
+	svn_command = SVN_COMMAND (command);
+	revision = svn_command_get_revision (self->priv->revision);
+	
+	/* I just copied this so don't blame me... */
+	update_paths = apr_array_make (svn_command_get_pool (svn_command), 1,
+								   sizeof (char *));
+	(*((const char **) apr_array_push (update_paths))) = self->priv->path;
+	
+	if (self->priv->recursive == TRUE)
+		depth = svn_depth_infinity;
+	else depth = svn_depth_files;
+	
+	error = svn_client_update3 (&update_revisions, 
+								update_paths, 
+								revision, 
+								depth,
+								FALSE,
+								FALSE,
+								FALSE,
+								svn_command_get_client_context (svn_command),
+								svn_command_get_pool (svn_command));
+	
+	if (error)
+	{
+		svn_command_set_error (svn_command, error);
+		return 1;
+	}
+	
+	revision_number = (*(svn_revnum_t *) apr_array_pop (update_revisions));
+	
+	revision_message = g_strdup_printf (_("Updated to revision %ld."), 
+										(glong) revision_number);
+	svn_command_push_info (SVN_COMMAND (command), revision_message);
+	g_free (revision_message);
+	
+	return 0;
+}
+
+static void
+svn_update_command_class_init (SvnUpdateCommandClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtranslatorCommandClass *command_class = GTR_COMMAND_CLASS (klass);
+
+	object_class->finalize = svn_update_command_finalize;
+	command_class->run = svn_update_command_run;
+}
+
+
+SvnUpdateCommand *
+svn_update_command_new (const gchar *path, const gchar *revision, gboolean recursive)
+{
+	SvnUpdateCommand *self;
+	
+	self = g_object_new (SVN_TYPE_UPDATE_COMMAND, NULL);
+	
+	self->priv->path = svn_command_make_canonical_path (SVN_COMMAND (self),
+														path);
+	self->priv->revision = g_strdup (revision);
+	self->priv->recursive = recursive;
+	
+	return self;
+}
+
+void
+svn_update_command_destroy (SvnUpdateCommand *self)
+{
+	g_object_unref (self);
+}

Added: trunk/plugins/subversion/svn-update-command.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/svn-update-command.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,68 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ *
+ * Portions based on the original Subversion plugin 
+ * Copyright (C) Johannes Schmid 2005 
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _SVN_UPDATE_COMMAND_H_
+#define _SVN_UPDATE_COMMAND_H_
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include "svn-command.h"
+
+G_BEGIN_DECLS
+
+#define SVN_TYPE_UPDATE_COMMAND             (svn_update_command_get_type ())
+#define SVN_UPDATE_COMMAND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVN_TYPE_UPDATE_COMMAND, SvnUpdateCommand))
+#define SVN_UPDATE_COMMAND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SVN_TYPE_UPDATE_COMMAND, SvnUpdateCommandClass))
+#define SVN_IS_UPDATE_COMMAND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SVN_TYPE_UPDATE_COMMAND))
+#define SVN_IS_UPDATE_COMMAND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SVN_TYPE_UPDATE_COMMAND))
+#define SVN_UPDATE_COMMAND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SVN_TYPE_UPDATE_COMMAND, SvnUpdateCommandClass))
+
+typedef struct _SvnUpdateCommandClass SvnUpdateCommandClass;
+typedef struct _SvnUpdateCommand SvnUpdateCommand;
+typedef struct _SvnUpdateCommandPriv SvnUpdateCommandPriv;
+
+struct _SvnUpdateCommandClass
+{
+	SvnCommandClass parent_class;
+};
+
+struct _SvnUpdateCommand
+{
+	SvnCommand parent_instance;
+	
+	SvnUpdateCommandPriv *priv;
+};
+
+GType svn_update_command_get_type (void) G_GNUC_CONST;
+SvnUpdateCommand * svn_update_command_new (const gchar *path, const gchar *revision, 
+										   gboolean recursive);
+void svn_update_command_destroy (SvnUpdateCommand *self);
+
+G_END_DECLS
+
+#endif /* _SVN_UPDATE_COMMAND_H_ */

Added: trunk/plugins/subversion/update-dialog.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/update-dialog.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "update-dialog.h"
+#include "subversion-plugin.h"
+#include "svn-update-command.h"
+#include "utils.h"
+#include "svn-command.h"
+#include "statusbar.h"
+#include "subversion-utils.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+
+#define GTR_UPDATE_DIALOG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 	(object),	\
+						 	GTR_TYPE_UPDATE_DIALOG,     \
+						 	GtranslatorUpdateDialogPrivate))
+
+
+G_DEFINE_TYPE(GtranslatorUpdateDialog, gtranslator_update_dialog, GTK_TYPE_DIALOG)
+
+struct _GtranslatorUpdateDialogPrivate
+{
+	GtkWidget *main_box;
+	GtkWidget *dir_button;
+	
+	GtkListStore *store;
+	GtkWidget *update_treeview;
+	
+	GtranslatorWindow *window;
+};
+
+enum 
+{
+	ICON_COLUMN,
+	TEXT_COLUMN,
+	N_COLUMNS
+};
+
+static void
+on_update_command_finished (GtranslatorCommand *command,
+			    guint return_code,
+			    GtranslatorUpdateDialog *dlg)
+{
+	GtranslatorStatusbar *status;
+	
+	status = GTR_STATUSBAR (gtranslator_window_get_statusbar (dlg->priv->window));
+	
+	gtranslator_statusbar_flash_message (status, 0,
+					     _("Subversion: Update complete."));
+	
+	subversion_utils_report_errors (dlg->priv->window, 
+					command, return_code);
+	
+	svn_update_command_destroy (SVN_UPDATE_COMMAND (command));	
+}
+
+static void
+on_update_command_info_arrived (GtranslatorCommand *command,
+				GtranslatorUpdateDialog *dlg)
+{
+	GQueue *info;
+	gchar *message;
+	GtkTreeIter iter;
+	
+	info = svn_command_get_info_queue (SVN_COMMAND (command));
+	
+	while (g_queue_peek_head (info))
+	{
+		message = g_queue_pop_head (info);
+		
+		gtk_list_store_append(dlg->priv->store, &iter);
+		gtk_list_store_set (dlg->priv->store, &iter,
+				    TEXT_COLUMN, message,
+				    -1);
+		
+		g_free (message);
+	}
+}
+
+static void
+dialog_response_handler (GtranslatorUpdateDialog *dlg, 
+			 gint       res_id)
+{
+	switch (res_id)
+	{
+		case GTK_RESPONSE_APPLY:
+		{
+			gchar *filename;
+			SvnUpdateCommand *update_command;
+			
+			filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg->priv->dir_button));
+			
+			update_command = svn_update_command_new ((gchar *) filename,
+								 (gchar *)"", 
+								 TRUE);
+			g_free (filename);
+			
+			gtk_list_store_clear (dlg->priv->store);
+			
+			g_signal_connect (G_OBJECT (update_command), "command-finished",
+					  G_CALLBACK (on_update_command_finished),
+					  dlg);
+			
+			g_signal_connect (G_OBJECT (update_command), "data-arrived",
+					  G_CALLBACK (on_update_command_info_arrived),
+					  dlg);
+			
+			gtranslator_command_start (GTR_COMMAND (update_command));
+			
+			break;
+		}
+		default:
+			gtk_widget_hide (GTK_WIDGET (dlg));
+	}
+}
+
+static void
+setup_treeview (GtranslatorUpdateDialog *dlg)
+{
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+	
+	dlg->priv->store = gtk_list_store_new (N_COLUMNS,
+					       GDK_TYPE_PIXBUF,
+					       G_TYPE_STRING);
+	
+	gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->update_treeview),
+				 GTK_TREE_MODEL (dlg->priv->store));
+	
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (dlg->priv->update_treeview),
+					   FALSE);
+	
+	column = gtk_tree_view_column_new ();
+	/*
+	 * Icon column
+	 */
+	renderer = gtk_cell_renderer_pixbuf_new ();
+	g_object_set (renderer,
+		      "stock-id", GTK_STOCK_INFO,
+		      "stock-size", GTK_ICON_SIZE_MENU,
+		      "xalign", 1.0,
+		      "xpad", 6,
+		      NULL);
+
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	
+	/*
+	 * Text column
+	 */
+	
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_set_attributes (column,
+					     renderer,
+					     "text", TEXT_COLUMN,
+					     NULL);
+
+	gtk_tree_view_column_set_resizable (column, FALSE);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->update_treeview),
+				     column);
+}
+
+static void
+setup_dir (GtranslatorUpdateDialog *dlg)
+{
+	GtranslatorTab *tab;
+	GtranslatorPo *po;
+	gchar *dir;
+	GFile *location, *parent, *file;
+	
+	tab = gtranslator_window_get_active_tab (dlg->priv->window);
+	po = gtranslator_tab_get_po (tab);
+	location = gtranslator_po_get_location (po);
+	
+	/* Get the directory of the po file */
+	parent = g_file_get_parent (location);
+	g_object_unref (location);
+	
+	/* Get the parent directory */
+	file = g_file_get_parent (parent);
+
+	dir = g_file_get_uri (file);
+	
+	gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dlg->priv->dir_button),
+				  dir);
+	g_free (dir);
+	g_object_unref (file);
+}
+
+static void
+gtranslator_update_dialog_init (GtranslatorUpdateDialog *dlg)
+{
+	gboolean ret;
+	GtkWidget *error_widget;
+	
+	dlg->priv = GTR_UPDATE_DIALOG_GET_PRIVATE (dlg);
+	
+	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
+				GTK_STOCK_REFRESH,
+				GTK_RESPONSE_APPLY,
+				GTK_STOCK_CLOSE,
+				GTK_RESPONSE_CLOSE,
+				NULL);
+	
+	gtk_window_set_title (GTK_WINDOW (dlg), _("Update repository"));
+	gtk_window_set_default_size (GTK_WINDOW (dlg), 600, 600);
+	gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
+	
+	/* HIG defaults */
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 2); /* 2 * 5 + 2 = 12 */
+	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 4);
+	
+	g_signal_connect (dlg,
+			  "response",
+			  G_CALLBACK (dialog_response_handler),
+			  NULL);
+	
+	/*Glade*/
+	ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+		"update_main_box",
+		&error_widget,
+		
+		"update_main_box", &dlg->priv->main_box,
+		"dir_button", &dlg->priv->dir_button,
+		"update_treeview", &dlg->priv->update_treeview,
+		
+		NULL);
+	
+	if(!ret)
+	{
+		gtk_widget_show (error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+					     error_widget);
+		
+		return;
+	}
+	
+	setup_treeview (dlg);
+	
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+			    dlg->priv->main_box, TRUE, TRUE, 0);
+	
+	gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->main_box), 5);
+	
+}
+
+static void
+gtranslator_update_dialog_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_update_dialog_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_update_dialog_class_init (GtranslatorUpdateDialogClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorUpdateDialogPrivate));
+
+	object_class->finalize = gtranslator_update_dialog_finalize;
+}
+
+void
+gtranslator_show_update_dialog (GtranslatorWindow *window)
+{
+	static GtranslatorUpdateDialog *dlg = NULL;
+	
+	g_return_if_fail (GTR_IS_WINDOW (window));
+	
+	if(dlg == NULL)
+	{
+		dlg = g_object_new (GTR_TYPE_UPDATE_DIALOG, NULL);
+		
+		gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg),
+						    TRUE);
+		
+		dlg->priv->window = window;
+
+		setup_dir (dlg);
+		
+		g_signal_connect (dlg,
+				  "destroy",
+				  G_CALLBACK (gtk_widget_destroyed),
+				  &dlg);
+
+		gtk_widget_show (GTK_WIDGET (dlg));
+	}
+	
+	if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (dlg)))
+	{
+		gtk_window_set_transient_for (GTK_WINDOW (dlg),
+					      GTK_WINDOW (window));
+	}
+
+	gtk_window_present (GTK_WINDOW (dlg));
+}

Added: trunk/plugins/subversion/update-dialog.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/update-dialog.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __UPDATE_DIALOG_H__
+#define __UPDATE_DIALOG_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "window.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_UPDATE_DIALOG		(gtranslator_update_dialog_get_type ())
+#define GTR_UPDATE_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_UPDATE_DIALOG, GtranslatorUpdateDialog))
+#define GTR_UPDATE_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_UPDATE_DIALOG, GtranslatorUpdateDialogClass))
+#define GTR_IS_UPDATE_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_UPDATE_DIALOG))
+#define GTR_IS_UPDATE_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_UPDATE_DIALOG))
+#define GTR_UPDATE_DIALOG_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_UPDATE_DIALOG, GtranslatorUpdateDialogClass))
+
+/* Private structure type */
+typedef struct _GtranslatorUpdateDialogPrivate	GtranslatorUpdateDialogPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorUpdateDialog		GtranslatorUpdateDialog;
+
+struct _GtranslatorUpdateDialog
+{
+	GtkDialog parent_instance;
+	
+	/*< private > */
+	GtranslatorUpdateDialogPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorUpdateDialogClass	GtranslatorUpdateDialogClass;
+
+struct _GtranslatorUpdateDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_update_dialog_get_type               (void) G_GNUC_CONST;
+
+GType		 gtranslator_update_dialog_register_type          (GTypeModule * module);
+
+void	     gtranslator_show_update_dialog                   (GtranslatorWindow *window);
+
+G_END_DECLS
+
+#endif /* __UPDATE_DIALOG_H__ */

Added: trunk/plugins/subversion/vcs-status-tree-view.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/vcs-status-tree-view.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,395 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+* gtranslator
+* Copyright (C) James Liggett 2007 <jrliggett cox net>
+* 
+* gtranslator is free software.
+* 
+* You may 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.
+* 
+* gtranslator 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 gtranslator.  If not, write to:
+* 	The Free Software Foundation, Inc.,
+* 	51 Franklin Street, Fifth Floor
+* 	Boston, MA  02110-1301, USA.
+*/
+
+#include "vcs-status-tree-view.h"
+#include <string.h>
+#include <glib/gi18n.h>
+
+enum 
+{
+	COL_SELECTED,
+	COL_STATUS,
+	COL_PATH,
+	NUM_COLS
+};
+
+enum
+{
+	GTR_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES = 1,
+	GTR_VCS_STATUS_TREE_VIEW_SHOW_STATUS
+};
+
+struct _GtranslatorVcsStatusTreeViewPriv
+{
+	GtkListStore *store;
+	GHashTable *selected_paths;
+	guint status_codes;
+	gboolean show_status;
+};
+
+G_DEFINE_TYPE (GtranslatorVcsStatusTreeView, gtranslator_vcs_status_tree_view, 
+			   GTK_TYPE_TREE_VIEW);
+
+static void
+on_selected_column_toggled (GtkCellRendererToggle *renderer,
+							gchar *tree_path,
+							GtranslatorVcsStatusTreeView *self)
+{
+	GtkTreeIter iter;
+	gchar *vcs_path;
+	gboolean selected;
+	
+	gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (self->priv->store),
+										 &iter, tree_path);
+	
+	gtk_tree_model_get (GTK_TREE_MODEL (self->priv->store), &iter,
+						COL_PATH, &vcs_path,
+						COL_SELECTED, &selected, -1);
+	
+	gtk_list_store_set (self->priv->store, &iter, 
+						COL_SELECTED, !selected, -1);
+	
+	g_free (vcs_path);
+	
+}
+
+static void
+gtranslator_vcs_status_tree_view_create_columns (GtranslatorVcsStatusTreeView *self)
+{
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+	
+	/* Selected column */
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_toggle_new ();
+	gtk_tree_view_column_pack_start (column, renderer, TRUE);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (self), column);
+	gtk_tree_view_column_add_attribute (column, renderer, "active",
+										COL_SELECTED);
+	
+	g_signal_connect (G_OBJECT (renderer), "toggled",
+					  G_CALLBACK (on_selected_column_toggled),
+					  self);
+	
+	/* Status column */
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, renderer, TRUE);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (self), column);
+	gtk_tree_view_column_add_attribute (column, renderer, "text",
+										COL_STATUS);
+	
+	/* Path column */
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, renderer, TRUE);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (self), column);
+	gtk_tree_view_column_add_attribute (column, renderer, "text",
+										COL_PATH);
+	
+	gtk_tree_view_set_model (GTK_TREE_VIEW (self), 
+							 GTK_TREE_MODEL (self->priv->store));
+	g_object_unref (self->priv->store);
+	
+}
+
+static gint
+path_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, 
+		   gpointer user_data)
+{
+	gint compare_value;
+	gchar *path1;
+	gchar *path2;
+	
+	gtk_tree_model_get (model, a, COL_PATH, &path1, -1);
+	gtk_tree_model_get (model, b, COL_PATH, &path2, -1);
+	
+	compare_value = strcmp (path1, path2);
+	
+	g_free (path1);
+	g_free (path2);
+	
+	return compare_value;
+}
+
+static void
+gtranslator_vcs_status_tree_view_init (GtranslatorVcsStatusTreeView *self)
+{
+	GtkTreeSortable *sortable;
+	
+	self->priv = g_new0 (GtranslatorVcsStatusTreeViewPriv, 1);
+	self->priv->store = gtk_list_store_new (NUM_COLS,
+											G_TYPE_BOOLEAN,
+											G_TYPE_STRING,
+											G_TYPE_STRING);
+	self->priv->selected_paths = g_hash_table_new_full (g_str_hash,
+														g_str_equal,
+														g_free,
+														NULL);
+	
+	gtranslator_vcs_status_tree_view_create_columns (self);
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self), FALSE);
+	
+	sortable = GTK_TREE_SORTABLE (self->priv->store);
+	gtk_tree_sortable_set_sort_column_id (sortable, COL_PATH,
+										  GTK_SORT_ASCENDING);
+	gtk_tree_sortable_set_sort_func (sortable, COL_PATH, path_sort, NULL,
+									 NULL);
+}
+
+static void
+gtranslator_vcs_status_tree_view_finalize (GObject *object)
+{
+	GtranslatorVcsStatusTreeView *self;
+	
+	self = GTR_VCS_STATUS_TREE_VIEW (object);
+	
+	g_hash_table_destroy (self->priv->selected_paths);
+	g_free (self->priv);
+	
+	G_OBJECT_CLASS (gtranslator_vcs_status_tree_view_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_vcs_status_tree_view_set_property (GObject *object, guint property_id,
+										  const GValue *value, 
+										  GParamSpec *param_spec)
+{
+	GtranslatorVcsStatusTreeView *self;
+	GtkTreeView *tree_view;
+	GtkTreeViewColumn *column;
+	
+	self = GTR_VCS_STATUS_TREE_VIEW (object);
+	
+	switch (property_id)
+	{
+		case GTR_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES:
+			self->priv->status_codes = g_value_get_flags (value);
+			break;
+		case GTR_VCS_STATUS_TREE_VIEW_SHOW_STATUS:
+			tree_view = GTK_TREE_VIEW (object);
+			column = gtk_tree_view_get_column (tree_view, COL_STATUS);
+			self->priv->show_status = g_value_get_boolean (value);
+		
+			gtk_tree_view_column_set_visible (column, self->priv->show_status);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec);
+			break;
+	}
+}
+
+static void
+gtranslator_vcs_status_tree_view_get_property (GObject *object, guint property_id,
+										  GValue *value, GParamSpec *param_spec)
+{
+	GtranslatorVcsStatusTreeView *self;
+	
+	self = GTR_VCS_STATUS_TREE_VIEW (object);
+	
+	switch (property_id)
+	{
+		case GTR_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES:
+			g_value_set_flags (value, self->priv->status_codes);
+			break;
+		case GTR_VCS_STATUS_TREE_VIEW_SHOW_STATUS:
+			g_value_set_boolean (value, self->priv->show_status);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec);
+			break;
+	}
+}
+
+static void
+gtranslator_vcs_status_tree_view_class_init (GtranslatorVcsStatusTreeViewClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	GParamSpec *param_spec;
+	
+	object_class->finalize = gtranslator_vcs_status_tree_view_finalize;
+	object_class->get_property = gtranslator_vcs_status_tree_view_get_property;
+	object_class->set_property = gtranslator_vcs_status_tree_view_set_property;
+	
+	param_spec = g_param_spec_flags ("status-codes", "Status codes",
+									 "Control which status codes are shown in "
+									 "the list.",
+									 GTR_TYPE_VCS_STATUS,
+									 GTR_VCS_DEFAULT_STATUS_CODES,
+									 G_PARAM_READWRITE | 
+									 G_PARAM_CONSTRUCT_ONLY);
+	g_object_class_install_property (object_class,
+									 GTR_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES,
+									 param_spec);
+	
+	param_spec = g_param_spec_boolean ("show-status", "Show status",
+									   "Show or hide status description",
+									   TRUE,
+									   G_PARAM_READWRITE);
+	g_object_class_install_property (object_class,
+									 GTR_VCS_STATUS_TREE_VIEW_SHOW_STATUS,
+									 param_spec);
+}
+
+
+GtkWidget *
+gtranslator_vcs_status_tree_view_new (void)
+{
+	return g_object_new (GTR_VCS_TYPE_STATUS_TREE_VIEW, NULL);
+}
+
+void
+gtranslator_vcs_status_tree_view_destroy (GtranslatorVcsStatusTreeView *self)
+{
+	g_object_unref (self);
+}
+
+void
+gtranslator_vcs_status_tree_view_add (GtranslatorVcsStatusTreeView *self, gchar *path, 
+								 GtranslatorVcsStatus status, gboolean selected)
+{
+	GtkTreeIter iter;
+	
+	if (status & self->priv->status_codes)
+	{
+		gtk_list_store_append (self->priv->store, &iter);
+		
+		gtk_list_store_set (self->priv->store, &iter,
+							COL_SELECTED, selected,
+							COL_PATH, path, 
+							-1);
+		
+		if (selected)
+		{
+			g_hash_table_insert (self->priv->selected_paths, g_strdup (path), 
+								 NULL);
+		}
+		
+		switch (status)
+		{
+			case GTR_VCS_STATUS_MODIFIED:
+				gtk_list_store_set (self->priv->store, &iter, COL_STATUS, 
+									_("Modified"), -1);
+			break;
+			case GTR_VCS_STATUS_ADDED:
+				gtk_list_store_set (self->priv->store, &iter, COL_STATUS, 
+									_("Added"), -1);
+			break;
+			case GTR_VCS_STATUS_DELETED:
+				gtk_list_store_set (self->priv->store, &iter, COL_STATUS, 
+									_("Deleted"), -1);
+			break;
+			case GTR_VCS_STATUS_CONFLICTED:
+				gtk_list_store_set (self->priv->store, &iter, COL_STATUS, 
+									_("Conflicted"), -1);
+			break;
+			case GTR_VCS_STATUS_MISSING:
+				gtk_list_store_set (self->priv->store, &iter, COL_STATUS, 
+									_("Missing"), -1);
+			break;
+			case GTR_VCS_STATUS_NONE:
+				default:
+				break;
+			
+		}
+	}
+}
+
+static gboolean
+select_all_paths (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, 
+				  GtranslatorVcsStatusTreeView *self)
+{	
+	gtk_list_store_set (self->priv->store, iter, 
+						COL_SELECTED, TRUE, 
+						-1);
+	
+	return FALSE;
+}
+
+void
+gtranslator_vcs_status_tree_view_select_all (GtranslatorVcsStatusTreeView *self)
+{
+	gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->store),
+						    (GtkTreeModelForeachFunc) select_all_paths,
+							self);
+}
+
+static gboolean 
+unselect_all_paths (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, 
+					GtranslatorVcsStatusTreeView *self)
+{
+	gtk_list_store_set (self->priv->store, iter, 
+						COL_SELECTED, FALSE, 
+						-1);
+	
+	return FALSE;
+}
+
+void
+gtranslator_vcs_status_tree_view_unselect_all (GtranslatorVcsStatusTreeView *self)
+{
+	gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->store),
+							(GtkTreeModelForeachFunc) unselect_all_paths,
+							self);
+}
+
+static gboolean
+create_selected_paths_list (GtkTreeModel *model, GtkTreePath *path,  
+							GtkTreeIter *iter, GList **list)
+{
+	gboolean selected;
+	gchar *file_path;
+	
+	gtk_tree_model_get (model, iter, 
+						COL_SELECTED, &selected,
+						COL_PATH, &file_path, 
+						-1);
+	
+	if (selected)
+		*list = g_list_append (*list, g_strdup (file_path));
+	
+	return FALSE;
+}
+
+GList *
+gtranslator_vcs_status_tree_view_get_selected (GtranslatorVcsStatusTreeView *self)
+{
+	GList *list;
+	
+	list = NULL;
+	
+	gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->store),
+							(GtkTreeModelForeachFunc) create_selected_paths_list,
+							&list);
+	
+	return list;
+}
+
+void
+gtranslator_vsc_status_tree_view_clear (GtranslatorVcsStatusTreeView *self)
+{
+	g_return_if_fail (GTR_VCS_IS_STATUS_TREE_VIEW (self));
+	
+	gtk_list_store_clear (self->priv->store);
+}
\ No newline at end of file

Added: trunk/plugins/subversion/vcs-status-tree-view.h
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/vcs-status-tree-view.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,89 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * gtranslator
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * gtranslator is free software.
+ * 
+ * You may 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.
+ * 
+ * gtranslator 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 gtranslator.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _GTR_VCS_STATUS_TREE_VIEW_H_
+#define _GTR_VCS_STATUS_TREE_VIEW_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "subversion-enum-types.h"
+
+G_BEGIN_DECLS
+
+#define GTR_VCS_TYPE_STATUS_TREE_VIEW             (gtranslator_vcs_status_tree_view_get_type ())
+#define GTR_VCS_STATUS_TREE_VIEW(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTR_VCS_TYPE_STATUS_TREE_VIEW, GtranslatorVcsStatusTreeView))
+#define GTR_VCS_STATUS_TREE_VIEW_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTR_VCS_TYPE_STATUS_TREE_VIEW, GtranslatorVcsStatusTreeViewClass))
+#define GTR_VCS_IS_STATUS_TREE_VIEW(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTR_VCS_TYPE_STATUS_TREE_VIEW))
+#define GTR_VCS_IS_STATUS_TREE_VIEW_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_VCS_TYPE_STATUS_TREE_VIEW))
+#define GTR_VCS_STATUS_TREE_VIEW_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTR_VCS_TYPE_STATUS_TREE_VIEW, GtranslatorVcsStatusTreeViewClass))
+
+/* Show default status codes: Modified, Added, Deleted, and Conflicted */
+#define GTR_VCS_DEFAULT_STATUS_CODES (GTR_VCS_STATUS_MODIFIED | \
+										 GTR_VCS_STATUS_ADDED |    \
+										 GTR_VCS_STATUS_DELETED |  \
+										 GTR_VCS_STATUS_CONFLICTED)
+
+typedef struct _GtranslatorVcsStatusTreeViewClass GtranslatorVcsStatusTreeViewClass;
+typedef struct _GtranslatorVcsStatusTreeView GtranslatorVcsStatusTreeView;
+typedef struct _GtranslatorVcsStatusTreeViewPriv GtranslatorVcsStatusTreeViewPriv;
+
+struct _GtranslatorVcsStatusTreeViewClass
+{
+	GtkTreeViewClass parent_class;
+};
+
+struct _GtranslatorVcsStatusTreeView
+{
+	GtkTreeView parent_instance;
+	
+	GtranslatorVcsStatusTreeViewPriv *priv;
+};
+
+typedef enum
+{
+	/* Unversioned, ignored, or uninteresting items */
+	GTR_VCS_STATUS_NONE = 0, /*< skip >*/
+	
+	GTR_VCS_STATUS_MODIFIED = 1 << 0,
+	GTR_VCS_STATUS_ADDED = 1 << 1,
+	GTR_VCS_STATUS_DELETED = 1 << 2,
+	GTR_VCS_STATUS_CONFLICTED = 1 << 3,
+	GTR_VCS_STATUS_MISSING = 1 << 4,
+} GtranslatorVcsStatus;
+
+GType gtranslator_vcs_status_tree_view_get_type (void) G_GNUC_CONST;
+GtkWidget *gtranslator_vcs_status_tree_view_new (void);
+void gtranslator_vcs_status_tree_view_destroy (GtranslatorVcsStatusTreeView *self);
+void gtranslator_vcs_status_tree_view_add (GtranslatorVcsStatusTreeView *self, 
+									  gchar *path, 
+									  GtranslatorVcsStatus status, 
+									  gboolean selected);
+void gtranslator_vsc_status_tree_view_clear (GtranslatorVcsStatusTreeView *self);
+void gtranslator_vcs_status_tree_view_select_all (GtranslatorVcsStatusTreeView *self);
+void gtranslator_vcs_status_tree_view_unselect_all (GtranslatorVcsStatusTreeView *self);
+GList *gtranslator_vcs_status_tree_view_get_selected (GtranslatorVcsStatusTreeView *self);
+
+G_END_DECLS
+
+#endif /* _GTR_VCS_STATUS_TREE_VIEW_H_ */

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Tue Sep 16 07:58:13 2008
@@ -20,16 +20,33 @@
 plugins/open-tran/open-tran-panel.c
 plugins/open-tran/open-tran-plugin.c
 plugins/open-tran/open-tran.gtranslator-plugin.desktop.in
+plugins/source-code-view/source-code-view-dialog.glade
+plugins/source-code-view/source-code-view-plugin.c
+plugins/source-code-view/source-code-view.gtranslator-plugin.desktop.in
+plugins/source-code-view/viewer.c
+plugins/source-code-view/viewer.glade
+plugins/subversion/checkout-dialog.c
+plugins/subversion/commit-dialog.c
+plugins/subversion/diff-dialog.c
+plugins/subversion/subversion-plugin.c
+plugins/subversion/subversion.glade
+plugins/subversion/subversion.gtranslator-plugin.desktop.in
+plugins/subversion/svn-command.c
+plugins/subversion/svn-update-command.c
+plugins/subversion/update-dialog.c
+plugins/subversion/vcs-status-tree-view.c
 src/actions-file.c
 src/actions-help.c
-src/comment.c
-src/dialogs/bookmarks-dialog.glade
+src/context.c
+src/dialogs/assistant.c
 src/dialogs/close-confirmation-dialog.c
 src/dialogs/comment-dialog.c
 src/dialogs/comment-dialog.glade
 src/dialogs/file-dialogs.c
 src/dialogs/header-dialog.c
 src/dialogs/header-dialog.glade
+src/dialogs/jump-dialog.c
+src/dialogs/jump-dialog.glade
 src/dialogs/preferences-dialog.c
 src/dialogs/preferences-dialog.glade
 src/dialogs/profile-dialog.c
@@ -46,6 +63,11 @@
 src/tab.c
 src/toolbareditor/egg-editable-toolbar.c
 src/toolbareditor/egg-toolbar-editor.c
+src/translation-memory/berkeley/db-base.c
+src/translation-memory/berkeley/db-orig.c
+src/translation-memory/berkeley/db-trans.c
+src/translation-memory/berkeley/db-words.c
+src/translation-memory/translation-memory-ui.c
 src/utils.c
 src/view.c
 src/window.c

Modified: trunk/po/POTFILES.skip
==============================================================================
--- trunk/po/POTFILES.skip	(original)
+++ trunk/po/POTFILES.skip	Tue Sep 16 07:58:13 2008
@@ -0,0 +1 @@
+data/desktop/gtranslator.desktop.in

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -4,7 +4,8 @@
 
 SUBDIRS = toolbareditor \
 	  dialogs \
-	  plugin-system
+	  plugin-system \
+	  translation-memory
 
 noinst_LTLIBRARIES = libgtranslator.la
 
@@ -14,10 +15,13 @@
 	-I$(top_srcdir)/src/dialogs				\
 	-I$(top_srcdir)/src/toolbareditor			\
 	-I$(top_srcdir)/src/plugin-system			\
+	-I$(top_srcdir)/src/translation-memory			\
+	-I$(top_srcdir)/src/translation-memory/berkeley		\
 	-DGNOMELOCALEDIR=\""$(prefix)/${DATADIRNAME}/locale"\"	\
 	-DPREFIX=\""$(prefix)"\"                                \
 	-DSYSCONFDIR=\""$(sysconfdir)"\"                        \
-	-DDATADIR=\""$(pkgdatadir)"\"                              \
+	-DPKGDATADIR=\""$(pkgdatadir)"\"                        \
+	-DDATADIR=\""$(datadir)"\"                              \
 	-DLIBDIR=\""$(libdir)"\"                                \
 	$(GTRANSLATOR_CFLAGS)                                   \
 	$(GTKSPELL_CFLAGS)                                      \
@@ -50,7 +54,8 @@
 
 INST_H_FILES =				\
 	application.h \
-	comment.h \
+	context.h \
+	debug.h \
 	header.h \
 	io-error-message-area.h \
 	message-area.h \
@@ -103,14 +108,15 @@
 	actions-search.c \
 	header.c \
 	statusbar.c \
-	comment.c \
+	context.c \
 	$(INST_H_FILES) 
 
 libgtranslator_la_LIBADD = \
 	$(GTRANSLATOR_LIBS) \
 	dialogs/libdialogs.la \
 	toolbareditor/libtoolbareditor.la \
-	plugin-system/libpluginsystem.la 
+	plugin-system/libpluginsystem.la \
+	translation-memory/libtranslationmemory.la
 	
 #gtranslator_auto_learn_SOURCES = \
 #	auto-learn.c
@@ -134,7 +140,10 @@
 gtranslator-marshal.c: gtranslator-marshal.list $(GLIB_GENMARSHAL)
 	$(GLIB_GENMARSHAL) $< --body --header --prefix=gtranslator_marshal > $@
 
-EXTRA_DIST = ChangeLog gtranslator-marshal.list
-
+EXTRA_DIST =	\
+	ChangeLog			\
+	gtranslator-marshal.list	\
+	gtranslator-enum-types.h.template	\
+	gtranslator-enum-types.c.template
 
 CLEANFILES = $(BUILT_SOURCES)

Modified: trunk/src/actions-edit.c
==============================================================================
--- trunk/src/actions-edit.c	(original)
+++ trunk/src/actions-edit.c	Tue Sep 16 07:58:13 2008
@@ -126,15 +126,11 @@
 	GList *msg;
 	gint page_index;
 	
-	current = gtranslator_window_get_active_tab(window);
-	po = gtranslator_tab_get_po(current);
-	msg = gtranslator_po_get_current_message(po);
+	current = gtranslator_window_get_active_tab (window);
+	po = gtranslator_tab_get_po (current);
+	msg = gtranslator_po_get_current_message (po);
 	
-	page_index = gtranslator_tab_get_active_text_tab(current);
-	
-	if(page_index == 0)
-		msgid = gtranslator_msg_get_msgid(msg->data);
-	else msgid = gtranslator_msg_get_msgid_plural(msg->data);
+	msgid = gtranslator_msg_get_msgid (msg->data);
 	
 	if(msgid)
 	{
@@ -153,7 +149,7 @@
 	if(gtranslator_msg_is_fuzzy(msg->data) && gtranslator_prefs_manager_get_unmark_fuzzy())
 		gtranslator_msg_set_fuzzy(msg->data, FALSE);
 		
-	gtranslator_tab_message_go_to(current, msg);
+	gtranslator_tab_message_go_to(current, msg, FALSE, GTR_TAB_MOVE_NONE);
 	
 	/*
 	 * Emit that message was changed.
@@ -207,3 +203,16 @@
 {	
 	gtranslator_show_comment_dialog(window);
 }
+
+void
+gtranslator_actions_edit_clear (GtkAction *action,
+				GtranslatorWindow *window)
+{
+	GtranslatorTab *tab;
+	
+	g_return_if_fail (GTR_IS_WINDOW (window));
+	
+	tab = gtranslator_window_get_active_tab (window);
+	
+	gtranslator_tab_clear_msgstr_views (tab);
+}

Modified: trunk/src/actions-file.c
==============================================================================
--- trunk/src/actions-file.c	(original)
+++ trunk/src/actions-file.c	Tue Sep 16 07:58:13 2008
@@ -26,15 +26,20 @@
 
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
+#include <gio/gio.h>
 #include <string.h>
+#include <gio/gio.h>
 
 #include "actions.h"
+#include "application.h"
 #include "dialogs/close-confirmation-dialog.h"
 #include "file-dialogs.h"
 #include "notebook.h"
 #include "po.h"
+#include "profile.h"
 #include "statusbar.h"
 #include "tab.h"
+#include "utils.h"
 #include "window.h"
 
 #define GTR_TAB_SAVE_AS "gtranslator-tab-save-as"
@@ -49,9 +54,9 @@
  * and if not, opens it in a new tab.
  */
 gboolean 
-gtranslator_open(const gchar *filename,
-		 GtranslatorWindow *window,
-		 GError **error)
+gtranslator_open (GFile *location,
+		  GtranslatorWindow *window,
+		  GError **error)
 {
 	GtranslatorHeader *header;
 	GtranslatorPo	*po;
@@ -65,8 +70,8 @@
 	 * to handle.
 	 */
 	po = gtranslator_po_new();
-	gtranslator_po_parse(po, filename, error);
-	
+	gtranslator_po_parse (po, location, error);
+
 	if((*error != NULL) && (((GError *)*error)->code != GTR_PO_ERROR_RECOVERY))
 		return FALSE;
 
@@ -76,29 +81,30 @@
 	/*
 	 * If not a crash/temporary file, add to the history.
 	 */
-	gtranslator_recent_add(window, filename, project_id);
+	gtranslator_recent_add (window, location, project_id);
 
 	/*
 	 * Create a page to add to our list of open files
 	 */
 	tab = gtranslator_window_create_tab(window, po);
-	
+	gtranslator_window_set_active_tab (window, GTK_WIDGET (tab));
+
 	/*
 	 * Show the current message.
 	 */
 	current = gtranslator_po_get_current_message(po);
-	gtranslator_tab_message_go_to(tab, current);
-	
+	gtranslator_tab_message_go_to (tab, current, FALSE, GTR_TAB_MOVE_NONE);
+
 	/*
 	 * Grab the focus
 	 */
 	active_view = gtranslator_tab_get_active_view(tab);
 	gtk_widget_grab_focus(GTK_WIDGET(active_view));
-	
+
 	gtranslator_statusbar_update_progress_bar (GTR_STATUSBAR (gtranslator_window_get_statusbar (window)),
 						   (gdouble)gtranslator_po_get_translated_count (po),
 						   (gdouble)gtranslator_po_get_messages_count (po));
-	
+
 	return TRUE;
 }
 
@@ -106,17 +112,44 @@
 gtranslator_po_parse_files_from_dialog (GtkWidget * dialog,
 					GtranslatorWindow *window)
 {
-	GSList *po_files;
+	GSList *po_files, *l;
+	GSList *locations = NULL;
+	GFile *file, *parent;
+	gchar *uri;
 	
 	po_files = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
+	for (l = po_files; l != NULL; l = g_slist_next (l))
+	{
+		GFile *file;
+		
+		file = g_file_new_for_uri (l->data);
+		locations = g_slist_prepend (locations, file);
+	}
 
 	/*
-	 * Open the file via our centralized opening function.
+	 * We store latest directory
 	 */
-	load_file_list (window, (const GSList *)po_files);
-
+	file = g_file_new_for_uri (po_files->data);
+	g_slist_foreach (po_files, (GFunc)g_free, NULL);
 	g_slist_free (po_files);
 	
+	parent = g_file_get_parent (file);
+	g_object_unref (file);
+
+	uri = g_file_get_uri (parent);
+	g_object_unref (parent);
+	_gtranslator_application_set_last_dir (GTR_APP,
+					       uri);
+	
+	g_free (uri);
+
+	/*
+	 * Open the file via our centralized opening function.
+	 */
+	load_file_list (window, (const GSList *)locations);
+	g_slist_foreach (locations, (GFunc)g_object_unref, NULL);
+	g_slist_free (locations);
+	
 	/*
 	 * Destroy the dialog 
 	 */
@@ -166,7 +199,9 @@
 	}
 	dialog = gtranslator_file_chooser_new (GTK_WINDOW(window), 
 					       FILESEL_OPEN,
-					       _("Open file for translation"));	
+					       _("Open file for translation"),
+					       _gtranslator_application_get_last_dir (GTR_APP));	
+	
 	/*
 	 * With the gettext parser/writer API, we can't currently read/write
 	 * to remote files with gnome-vfs. Eventually, we should intercept
@@ -187,6 +222,8 @@
 	GtranslatorPo *po;
 	GtranslatorTab *tab;
 	gchar *filename;
+	GFile *location;
+	GtranslatorStatusbar *status;
 	
 	tab = GTR_TAB (g_object_get_data (G_OBJECT (dialog),
 					  GTR_TAB_SAVE_AS));
@@ -204,11 +241,16 @@
 	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
 	g_return_if_fail (filename != NULL);
 	
+	location = g_file_new_for_path (filename);
+	g_free (filename);
+	
 	gtk_widget_destroy (GTK_WIDGET (dialog));
 	
 	if (po != NULL)
 	{
-		gtranslator_po_set_filename (po, filename);
+		gtranslator_po_set_location (po, location);
+		
+		g_object_unref (location);
 		
 		gtranslator_po_save_file (po, &error);
 	
@@ -223,15 +265,17 @@
 			gtk_dialog_run(GTK_DIALOG(dialog));
 			gtk_widget_destroy(dialog);
 			g_clear_error(&error);
-			g_free (filename);
 			return;
 		}
 	
 		/* We have to change the state of the tab */
-		gtranslator_po_set_state(po, GTR_PO_STATE_SAVED);	
-			
-		g_free (filename);
+		gtranslator_po_set_state(po, GTR_PO_STATE_SAVED);
+		
+		/* Flash a message */
+		status = GTR_STATUSBAR (gtranslator_window_get_statusbar (window));
+		gtranslator_statusbar_flash_message (status, 0, _("File saved."));
 	}
+	g_object_unref (location);
 }
 
 static GtkFileChooserConfirmation
@@ -265,7 +309,7 @@
 	GtkWidget *dialog = NULL;
 	GtranslatorTab *current_page;
 	GtranslatorPo *po;
-	const gchar *filename;
+	GFile *location;
 	gchar *uri = NULL;
 	gboolean uri_set = FALSE;
 	
@@ -279,7 +323,8 @@
 	
 	dialog = gtranslator_file_chooser_new (GTK_WINDOW (window),
 					       FILESEL_SAVE,
-					       _("Save file as..."));
+					       _("Save file as..."),
+					       _gtranslator_application_get_last_dir (GTR_APP));
 	
 	gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
 							TRUE);
@@ -291,9 +336,11 @@
 	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 	
 	/*Set the suggested file */
-	filename = gtranslator_po_get_filename (po);
+	location = gtranslator_po_get_location (po);
 	
-	uri = g_filename_to_uri (filename, NULL, NULL);
+	uri = g_file_get_uri (location);
+	
+	g_object_unref (location);
 	
 	if (uri)
 		uri_set = gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog),
@@ -327,6 +374,7 @@
 	GError *error = NULL;
 	GtranslatorTab *current;
 	GtranslatorPo *po;
+	GtranslatorStatusbar *status;
 	
 	current = gtranslator_window_get_active_tab (window);
 	po = gtranslator_tab_get_po (current);
@@ -349,83 +397,78 @@
 	
 	/* We have to change the state of the tab */
 	gtranslator_po_set_state(po, GTR_PO_STATE_SAVED);
+	
+	/* Flash a message */
+	status = GTR_STATUSBAR (gtranslator_window_get_statusbar (window));
+	gtranslator_statusbar_flash_message (status, 0, _("File saved."));
 }
 
 static gboolean
-is_duplicated_uri (const GSList *uris, 
-		   const gchar  *u)
+is_duplicated_location (const GSList *locations, 
+			GFile  *u)
 {
-	while (uris != NULL)
+	GSList *l;
+	
+	for (l = (GSList *)locations; l != NULL; l = g_slist_next (l))
 	{
-		if (strcmp (u, (const gchar*)uris->data) == 0)
+		if (g_file_equal (u, l->data))
 			return TRUE;
-			
-		uris = g_slist_next (uris);
 	}
 	
 	return FALSE;
 }
 
 static void
-load_file_list(GtranslatorWindow *window,
-	       const GSList *uris)
+load_file_list (GtranslatorWindow *window,
+	        const GSList *locations)
 {
-	GSList        *uris_to_load = NULL;
+	GSList *locations_to_load = NULL;
 	const GSList  *l;
 	GError *error = NULL;
-	gchar *path;
 	GtkWidget *tab;
-	
-	g_return_if_fail ((uris != NULL) && (uris->data != NULL));
+
+	g_return_if_fail ((locations != NULL) && (locations->data != NULL));
 
 	/* Remove the uris corresponding to documents already open
 	 * in "window" and remove duplicates from "uris" list */
-	l = uris;
-	while (uris != NULL)
+	l = locations;
+	while (locations != NULL)
 	{
-		if (!is_duplicated_uri (uris_to_load, uris->data))
+		if (!is_duplicated_location (locations_to_load, locations->data))
 		{
 			/*We need to now if is already loaded in any tab*/
-			tab = gtranslator_window_get_tab_from_uri (window,
-								   (const gchar *)uris->data);
+			tab = gtranslator_window_get_tab_from_location (window,
+									(GFile *)locations->data);
 
 			if (tab != NULL)
 			{
-				if (uris == l)
-				{
+				if (locations == l)
 					gtranslator_window_set_active_tab (window,
 									   tab);
-				}
-
 			}
 			else
-			{
-				uris_to_load = g_slist_prepend (uris_to_load, 
-								uris->data);
-			}
+				locations_to_load = g_slist_prepend (locations_to_load, 
+								     locations->data);
 
 		}
 
-		uris = g_slist_next (uris);
+		locations = g_slist_next (locations);
 	}
 
-	if (uris_to_load == NULL)
+	if (locations_to_load == NULL)
 		return;
+
+	locations_to_load = g_slist_reverse (locations_to_load);
+	l = locations_to_load;
 	
-	uris_to_load = g_slist_reverse (uris_to_load);
-	l = uris_to_load;
-	
-	while (uris_to_load != NULL)
+	while (locations_to_load != NULL)
 	{
-		g_return_if_fail (uris_to_load->data != NULL);
+		g_return_if_fail (locations_to_load->data != NULL);
 
-		path = g_filename_from_uri((const gchar *)uris_to_load->data,
-					   NULL, NULL);
-		if(!gtranslator_open(path, window, &error))
+		if (!gtranslator_open (locations_to_load->data, window, &error))
 			break;
-		
-		g_free(path);
-		uris_to_load = g_slist_next (uris_to_load);
+
+		locations_to_load = g_slist_next (locations_to_load);
 	}
 	
 	/*
@@ -433,9 +476,7 @@
 	 * and free the path
 	 */
 	if(error != NULL)
-	{
-		g_free(path);
-		
+	{	
 		GtkWidget *dialog;
 		/*
 		 * We have to show the error in a dialog
@@ -461,13 +502,13 @@
  * Ignore non-existing URIs 
  */
 void
-gtranslator_actions_load_uris (GtranslatorWindow *window,
-			       const GSList        *uris)
+gtranslator_actions_load_locations (GtranslatorWindow *window,
+				    const GSList      *locations)
 {	
 	g_return_if_fail (GTR_IS_WINDOW (window));
-	g_return_if_fail ((uris != NULL) && (uris->data != NULL));
+	g_return_if_fail ((locations != NULL) && (locations->data != NULL));
 	
-	load_file_list (window, uris);
+	load_file_list (window, locations);
 }
 
 static void
@@ -614,14 +655,10 @@
 	gtk_widget_destroy (GTK_WIDGET (dlg));
 }
 
-void 
-gtranslator_file_close (GtkAction * widget,
-			GtranslatorWindow *window)
+void
+gtranslator_close_tab (GtranslatorTab *tab,
+		       GtranslatorWindow *window)
 {
-	GtranslatorTab *tab;
-	
-	tab = gtranslator_window_get_active_tab (window);
-	
 	g_object_set_data (G_OBJECT (window),
 			   GTR_IS_CLOSING_ALL,
 			   GINT_TO_POINTER (0));
@@ -645,6 +682,17 @@
 		_gtranslator_window_close_tab (window, tab);
 }
 
+void 
+gtranslator_file_close (GtkAction * widget,
+			GtranslatorWindow *window)
+{
+	GtranslatorTab *tab;
+	
+	tab = gtranslator_window_get_active_tab (window);
+	
+	gtranslator_close_tab (tab, window);
+}
+
 void
 gtranslator_file_quit (GtkAction *action,
 		       GtranslatorWindow *window)
@@ -654,7 +702,35 @@
 	GtranslatorPo *po;
 	gint pages;
 	GList *list = NULL;
-	
+	GList *profiles_list = NULL;
+	gchar *config_folder;
+	gchar *filename;
+	GFile *file;
+        
+        config_folder = gtranslator_utils_get_user_config_dir ();
+ 	filename = g_build_filename (config_folder,
+ 				     "profiles.xml",
+ 				     NULL);
+	
+	file = g_file_new_for_path (filename);
+	
+	profiles_list = gtranslator_application_get_profiles (GTR_APP);
+
+	if (profiles_list != NULL) {
+	  if (g_file_query_exists (file, NULL)) {
+	    g_file_delete (file, NULL, NULL);
+	    gtranslator_profile_save_profiles_in_xml (filename);
+	  } else {
+	    g_file_create (file,
+			   G_FILE_CREATE_NONE,
+			   NULL,
+			   NULL);
+	    gtranslator_profile_save_profiles_in_xml (filename);
+	  }
+	}
+	g_free (config_folder);
+	g_object_unref (file);
+
 	nb = gtranslator_window_get_notebook (window);
 	pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK(nb));
 

Modified: trunk/src/actions-go.c
==============================================================================
--- trunk/src/actions-go.c	(original)
+++ trunk/src/actions-go.c	Tue Sep 16 07:58:13 2008
@@ -25,6 +25,7 @@
 #include <glib/gi18n.h>
 
 #include "actions.h"
+#include "jump-dialog.h"
 #include "po.h"
 #include "tab.h"
 #include "window.h"
@@ -39,8 +40,7 @@
 	
 	current = gtranslator_window_get_active_tab(window);
 	po = gtranslator_tab_get_po(current);
-	gtranslator_tab_message_go_to(current,
-				      g_list_first(gtranslator_po_get_current_message(po)));
+	gtranslator_tab_go_to_first (current);
 	set_sensitive_according_to_message(window, po);
 }
 
@@ -53,8 +53,7 @@
 	
 	current = gtranslator_window_get_active_tab(window);
 	po = gtranslator_tab_get_po(current);
-	gtranslator_tab_message_go_to(current,
-				      g_list_previous(gtranslator_po_get_current_message(po)));
+	gtranslator_tab_go_to_prev (current);
 	set_sensitive_according_to_message(window, po);
 }
 
@@ -67,8 +66,7 @@
 	
 	current = gtranslator_window_get_active_tab(window);
 	po = gtranslator_tab_get_po(current);
-	gtranslator_tab_message_go_to(current,
-				  g_list_next(gtranslator_po_get_current_message(po)));
+	gtranslator_tab_go_to_next (current);
 	set_sensitive_according_to_message(window, po);
 }
 
@@ -81,35 +79,21 @@
 	
 	current = gtranslator_window_get_active_tab(window);
 	po = gtranslator_tab_get_po(current);
-	gtranslator_tab_message_go_to(current,
-				      g_list_last(gtranslator_po_get_current_message(po)));
+	gtranslator_tab_go_to_last (current);
 	set_sensitive_according_to_message(window, po);
 }
 
-void 
-gtranslator_message_go_to_no(GtkAction *action,
-			     GtranslatorWindow *window)
-{
-	/*gtranslator_message_go_to(g_list_nth(current_page->po->messages,
-					     GPOINTER_TO_UINT(number)));*/
-}
-
 void
 gtranslator_message_go_to_next_fuzzy(GtkAction *action,
 				     GtranslatorWindow *window)
 {
 	GtranslatorTab *current;
 	GtranslatorPo *po;
-	GList *msg;
 	
-	current = gtranslator_window_get_active_tab(window);
-	po = gtranslator_tab_get_po(current);
-	msg = gtranslator_po_get_next_fuzzy(po);
-	if(msg != NULL)
-	{
-		gtranslator_tab_message_go_to(current, msg);
-		set_sensitive_according_to_message(window, po);
-	}
+	current = gtranslator_window_get_active_tab (window);
+	po = gtranslator_tab_get_po (current);
+	if (gtranslator_tab_go_to_next_fuzzy (current))
+		set_sensitive_according_to_message (window, po);
 }
 
 void
@@ -118,16 +102,11 @@
 {
 	GtranslatorTab *current;
 	GtranslatorPo *po;
-	GList *msg;
 	
 	current = gtranslator_window_get_active_tab(window);
 	po = gtranslator_tab_get_po(current);
-	msg = gtranslator_po_get_prev_fuzzy(po);
-	if(msg != NULL)
-	{
-		gtranslator_tab_message_go_to(current, msg);
-		set_sensitive_according_to_message(window, po);
-	}
+	if (gtranslator_tab_go_to_prev_fuzzy (current))
+		set_sensitive_according_to_message (window, po);
 }
 
 void
@@ -140,12 +119,8 @@
 	
 	current = gtranslator_window_get_active_tab(window);
 	po = gtranslator_tab_get_po(current);
-	msg = gtranslator_po_get_next_untrans(po);
-	if(msg != NULL)
-	{
-		gtranslator_tab_message_go_to(current, msg);
-		set_sensitive_according_to_message(window, po);
-	}
+	if (gtranslator_tab_go_to_next_untrans (current))
+		set_sensitive_according_to_message (window, po);
 }
 
 void
@@ -158,10 +133,41 @@
 	
 	current = gtranslator_window_get_active_tab(window);
 	po = gtranslator_tab_get_po(current);
-	msg = gtranslator_po_get_prev_untrans(po);
-	if(msg != NULL)
-	{
-		gtranslator_tab_message_go_to(current, msg);
-		set_sensitive_according_to_message(window, po);
-	}
+	if (gtranslator_tab_go_to_prev_untrans (current))
+		set_sensitive_according_to_message (window, po);
 }
+
+void
+gtranslator_message_go_to_next_fuzzy_or_untranslated (GtkAction *action,
+						      GtranslatorWindow *window)
+{
+	GtranslatorTab *current;
+	GtranslatorPo *po;
+	GList *msg;
+	
+	current = gtranslator_window_get_active_tab (window);
+	po = gtranslator_tab_get_po (current);
+	if (gtranslator_tab_go_to_next_fuzzy_or_untrans (current))
+		set_sensitive_according_to_message (window, po);
+}
+
+void
+gtranslator_message_go_to_prev_fuzzy_or_untranslated (GtkAction *action,
+						      GtranslatorWindow *window)
+{
+	GtranslatorTab *current;
+	GtranslatorPo *po;
+	GList *msg;
+	
+	current = gtranslator_window_get_active_tab (window);
+	po = gtranslator_tab_get_po (current);
+	if (gtranslator_tab_go_to_prev_fuzzy_or_untrans (current))
+		set_sensitive_according_to_message (window, po);
+}
+
+void
+gtranslator_message_jump (GtkAction *action,
+			  GtranslatorWindow *window)
+{
+	gtranslator_show_jump_dialog (window);
+}
\ No newline at end of file

Modified: trunk/src/actions-help.c
==============================================================================
--- trunk/src/actions-help.c	(original)
+++ trunk/src/actions-help.c	Tue Sep 16 07:58:13 2008
@@ -30,6 +30,31 @@
 
 #include <gtk/gtkaboutdialog.h>
 
+/*
+ * Show the user's guide for gtranslator
+ */
+void
+gtranslator_cmd_help_contents (GtkAction   *action,
+			       GtranslatorWindow *window)
+{
+  GError *error = NULL;
+  gboolean ret;
+  GtkWidget *dialog;
+
+  ret = g_app_info_launch_default_for_uri ("ghelp:gtranslator", NULL, &error);
+
+  if (ret == FALSE) 
+  {
+    dialog = gtk_message_dialog_new (GTK_WINDOW (window), 
+				     GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+				     GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, 
+				     _("Unable to open help file for gtranslator"));
+   
+    gtk_dialog_run (GTK_DIALOG (dialog));
+    gtk_widget_destroy (dialog);
+    g_error_free (error);
+  }
+}
 
 /*
  * Creates and shows the about box for gtranslator.

Modified: trunk/src/actions-search.c
==============================================================================
--- trunk/src/actions-search.c	(original)
+++ trunk/src/actions-search.c	Tue Sep 16 07:58:13 2008
@@ -274,7 +274,7 @@
 				if(l->next == NULL)
 				{
 					if(!wrap_around)
-						return;
+						return FALSE;
 					l = g_list_first(l);
 				}
 				else l = l->next;
@@ -283,19 +283,25 @@
 				if(l->prev == NULL)
 				{
 					if(!wrap_around)
-						return;
+						return FALSE;
 					l = g_list_last(l);
 				}
 				else l = l->prev;
 			}
-			gtranslator_tab_message_go_to(tab, l);
+			gtranslator_tab_message_go_to(tab, l, TRUE, GTR_TAB_MOVE_NONE);
 		}
 		else{
 			while(viewsaux != NULL)
 			{
+				gboolean aux = found;
+				
 				found = run_search(GTR_VIEW(viewsaux->data), found);
 				if(found)
+				{
+					gtranslator_tab_message_go_to (tab, l, FALSE, GTR_TAB_MOVE_NONE);
+					run_search (GTR_VIEW (viewsaux->data), aux);
 					return TRUE;
+				}
 				viewsaux = viewsaux->next;
 			}
 			if(!search_backwards)
@@ -303,7 +309,7 @@
 				if(l->next == NULL)
 				{
 					if(!wrap_around)
-						return;
+						return FALSE;
 					l = g_list_first(l);
 				}
 				else l = l->next;
@@ -312,16 +318,16 @@
 				if(l->prev == NULL)
 				{
 					if(!wrap_around)
-						return;
+						return FALSE;
 					l = g_list_last(l);
 				}
 				else l = l->prev;
 			}
-			gtranslator_tab_message_go_to(tab, l);
+			gtranslator_tab_message_go_to(tab, l, TRUE, GTR_TAB_MOVE_NONE);
 			viewsaux = views;
 		}
 	}while(l != current);
-
+	
 	return FALSE;
 }
 
@@ -538,9 +544,11 @@
 		if(aux->next == NULL)
 			aux = g_list_first(aux);
 		else aux = aux->next;
-		gtranslator_tab_message_go_to(tab, aux);
+		gtranslator_tab_message_go_to(tab, aux, TRUE, GTR_TAB_MOVE_NONE);
 	}while(current_msg != aux);
 
+	gtranslator_tab_message_go_to(tab, aux, FALSE, GTR_TAB_MOVE_NONE);
+	
 	if (count > 0)
 	{
 		phrase_found (window, count);

Modified: trunk/src/actions-view.c
==============================================================================
--- trunk/src/actions-view.c	(original)
+++ trunk/src/actions-view.c	Tue Sep 16 07:58:13 2008
@@ -16,3 +16,29 @@
  */
 
 #include "actions.h"
+
+void
+gtranslator_actions_view_context (GtkAction *action,
+				  GtranslatorWindow *window)
+{
+	GtranslatorTab *tab;
+	GtkWidget *context;
+	
+	tab = gtranslator_window_get_active_tab (window);
+	context = GTK_WIDGET (gtranslator_tab_get_context_panel (tab));
+	
+	gtranslator_tab_show_lateral_panel_widget (tab, context);
+}
+
+void
+gtranslator_actions_view_translation_memory (GtkAction *action,
+					     GtranslatorWindow *window)
+{
+	GtranslatorTab *tab;
+	GtkWidget *tm_ui;
+	
+	tab = gtranslator_window_get_active_tab (window);
+	tm_ui = GTK_WIDGET (gtranslator_tab_get_translation_memory_ui (tab));
+	
+	gtranslator_tab_show_lateral_panel_widget (tab, tm_ui);
+}
\ No newline at end of file

Modified: trunk/src/actions.h
==============================================================================
--- trunk/src/actions.h	(original)
+++ trunk/src/actions.h	Tue Sep 16 07:58:13 2008
@@ -20,6 +20,7 @@
 #define __ACTIONS_H__
 
 #include <gtk/gtkaction.h>
+#include <gio/gio.h>
 #include "window.h"
 
 G_BEGIN_DECLS
@@ -34,18 +35,21 @@
 void       gtranslator_save_file_as_dialog      (GtkAction * action,
 						 GtranslatorWindow *window);
 
-gboolean   gtranslator_open                     (const gchar *filename,
+gboolean   gtranslator_open                     (GFile *location,
 						 GtranslatorWindow *window,
 						 GError **error);
 
+void       gtranslator_close_tab                (GtranslatorTab *tab,
+						 GtranslatorWindow *window);
+
 void       gtranslator_file_close               (GtkAction * widget,
 						 GtranslatorWindow *window);
 
 void       gtranslator_file_quit                (GtkAction *action,
 						 GtranslatorWindow *window);
 
-void       gtranslator_actions_load_uris        (GtranslatorWindow *window,
-						 const GSList        *uris);
+void       gtranslator_actions_load_locations   (GtranslatorWindow *window,
+						 const GSList      *locations);
 
 /*Edit*/
 void       gtranslator_actions_edit_undo        (GtkAction   *action,
@@ -80,7 +84,16 @@
 void       gtranslator_actions_edit_preferences (GtkAction *action,
 						 GtranslatorWindow *window);
 
+void       gtranslator_actions_edit_clear       (GtkAction *action,
+						 GtranslatorWindow *window);
+
 /* View */
+void       gtranslator_actions_view_context     (GtkAction *action,
+						 GtranslatorWindow *window);
+
+void       gtranslator_actions_view_translation_memory
+						(GtkAction *action,
+						 GtranslatorWindow *window);
 
 /*Go*/
 void       gtranslator_message_go_to_first      (GtkAction  * action,
@@ -109,6 +122,17 @@
                                                 (GtkAction *action,
 						 GtranslatorWindow *window);
 
+void       gtranslator_message_go_to_next_fuzzy_or_untranslated
+						(GtkAction *action,
+						 GtranslatorWindow *window);
+
+void       gtranslator_message_go_to_prev_fuzzy_or_untranslated
+						(GtkAction *action,
+						 GtranslatorWindow *window);
+
+void       gtranslator_message_jump             (GtkAction *action,
+						 GtranslatorWindow *window);
+
 /*Search*/
 void       _gtranslator_actions_search_find     (GtkAction   *action,
 						 GtranslatorWindow *window);
@@ -120,6 +144,9 @@
 void       gtranslator_window_show_home_page    (GtkAction *action,
 						 gpointer useless);
 
+void       gtranslator_cmd_help_contents        (GtkAction *action,
+                                                 GtranslatorWindow *window);
+
 void       gtranslator_about_dialog             (GtkAction *action,
 						 GtranslatorWindow *window);
 

Modified: trunk/src/application.c
==============================================================================
--- trunk/src/application.c	(original)
+++ trunk/src/application.c	Tue Sep 16 07:58:13 2008
@@ -24,6 +24,12 @@
 #include "utils.h"
 #include "window.h"
 #include "egg-toolbars-model.h"
+#include "dialogs/preferences-dialog.h"
+#include "dialogs/assistant.h"
+#include "./translation-memory/translation-memory.h"
+#include "./translation-memory/berkeley/berkeley.h"
+  
+
 
 #include <glib.h>
 #include <glib-object.h>
@@ -42,11 +48,22 @@
 {
 	GList *windows;
 	GtranslatorWindow *active_window;
+
+        GList *profiles;
+        GtranslatorProfile *active_profile;
 	
+        GtranslatorPreferencesDialog *preferences_dialog;
+
 	gchar *toolbars_file;
 	EggToolbarsModel *toolbars_model;
 	
 	GtkIconFactory *icon_factory;
+
+	gchar *last_dir;
+	
+	GtranslatorTranslationMemory *tm;
+	
+	gboolean first_run;
 };
 
 static gchar *
@@ -123,7 +140,10 @@
 	priv = application->priv;
 	
 	priv->windows = NULL;
-	
+	priv->last_dir = NULL;
+	priv->first_run = FALSE;
+	priv->profiles = NULL;
+
 	/*
 	 * Creating config folder
 	 */
@@ -160,6 +180,7 @@
 			gtranslator_application_shutdown (application);
 		}
 		
+		priv->first_run = TRUE;
 		g_object_unref (file);
 	}
 
@@ -169,7 +190,7 @@
 						"gtr-toolbar.xml",
 						NULL);
 
-	filename = g_build_filename (DATADIR,
+	filename = g_build_filename (PKGDATADIR,
 				     "gtr-toolbar.xml",
 				     NULL);
 
@@ -195,6 +216,15 @@
 	/* Create Icon factory */
 	application->priv->icon_factory = gtk_icon_factory_new ();
 	gtk_icon_factory_add_default (application->priv->icon_factory);
+	
+	/* Creating translation memory */
+	application->priv->tm = GTR_TRANSLATION_MEMORY (gtranslator_berkeley_new ());
+	gtranslator_translation_memory_set_max_omits (application->priv->tm,
+ 						      gtranslator_prefs_manager_get_missing_words ());
+ 	gtranslator_translation_memory_set_max_delta (application->priv->tm,
+						      gtranslator_prefs_manager_get_sentence_length ());
+	gtranslator_translation_memory_set_max_items (application->priv->tm,
+						      10);
 }
 
 
@@ -205,7 +235,12 @@
 	
 	if (app->priv->icon_factory)
 		g_object_unref (app->priv->icon_factory);
+
+	g_free (app->priv->last_dir);
 	
+	if (app->priv->tm)
+		g_object_unref (app->priv->tm);
+
 	G_OBJECT_CLASS (gtranslator_application_parent_class)->finalize (object);
 }
 
@@ -226,6 +261,13 @@
         gtk_main_quit ();
 }
 
+/**
+ * gtranslator_application_get_default:
+ * 
+ * Returns the default instance of the application.
+ * 
+ * Returns: the default instance of the application.
+ */
 GtranslatorApplication *
 gtranslator_application_get_default (void)
 {
@@ -242,6 +284,14 @@
 	return instance;
 }
 
+/**
+ * gtranslator_application_open_window:
+ * @app: a #GtranslatorApplication
+ *
+ * Creates a new #GtranslatorWindow and shows it.
+ * 
+ * Returns: the #GtranslatorWindow to be opened
+ */
 GtranslatorWindow *
 gtranslator_application_open_window (GtranslatorApplication *app)
 {
@@ -267,23 +317,43 @@
 	}
 	
 	g_signal_connect(window, "delete-event",
-			 G_CALLBACK(on_window_delete_event_cb), GTR_APP);
+			 G_CALLBACK(on_window_delete_event_cb), app);
 	
 	g_signal_connect(window, "destroy",
-			 G_CALLBACK(on_window_destroy_cb), GTR_APP);
+			 G_CALLBACK(on_window_destroy_cb), app);
 
 	gtk_widget_show(GTK_WIDGET(window));
 	
+	/*
+	 * If it is the first run, the default directory was created in this
+	 * run, then we show the First run Assistant
+	 */
+	if (app->priv->first_run)
+		gtranslator_show_assistant (window);
+	
 	return window;
 }
 				     
-
+/**
+ * _gtranslator_application_get_toolbars_model:
+ * @application: a #GtranslatorApplication
+ * 
+ * Returns the toolbar model.
+ * 
+ * Retuns: the toolbar model.
+ */
 GObject *
 _gtranslator_application_get_toolbars_model (GtranslatorApplication *application)
 {
 	return G_OBJECT (application->priv->toolbars_model);
 }
 
+/**
+ * _gtranslator_application_save_toolbars_model:
+ * @application: a #GtranslatorApplication
+ * 
+ * Saves the toolbar model.
+ */
 void
 _gtranslator_application_save_toolbars_model (GtranslatorApplication *application)
 {
@@ -291,6 +361,12 @@
 			 	          application->priv->toolbars_file, "1.0");
 }
 
+/**
+ * gtranslator_application_shutdown:
+ * @app: a #GtranslatorApplication
+ * 
+ * Shutdowns the application.
+ */
 void
 gtranslator_application_shutdown(GtranslatorApplication *app)
 {
@@ -361,6 +437,78 @@
 	return app->priv->windows;
 }
 
+/**
+ * gtranslator_application_get_active_profile:
+ * @app: a #GtranslatorApplication
+ * 
+ * Return value: the active #GtranslatorProfile
+ **/
+GtranslatorProfile *
+gtranslator_application_get_active_profile (GtranslatorApplication *app)
+{
+	return app->priv->active_profile;
+}
+
+/**
+ * gtranslator_application_set_profiles:
+ * @app: a #GtranslatorApplication
+ * @profiles: a #GList
+ *
+ **/
+void
+gtranslator_application_set_active_profile (GtranslatorApplication *app,
+					    GtranslatorProfile *profile) {
+  app->priv->active_profile = profile;
+}
+
+/**
+ * gtranslator_application_get_profiles:
+ * @app: a #GtranslatorApplication
+ * 
+ * Return value: a list of all profiles.
+ **/
+GList *
+gtranslator_application_get_profiles (GtranslatorApplication *app)
+{
+	g_return_val_if_fail (GTR_IS_APPLICATION (app), NULL);
+
+	return app->priv->profiles;
+}
+
+/**
+ * gtranslator_application_set_profiles:
+ * @app: a #GtranslatorApplication
+ * @profiles: a #GList
+ *
+ **/
+void
+gtranslator_application_set_profiles (GtranslatorApplication *app, 
+				      GList *profiles) {
+   app->priv->profiles = profiles;   
+}
+
+GtranslatorPreferencesDialog *
+gtranslator_application_get_preferences_dialog (GtranslatorApplication *app)
+{
+  return app->priv->preferences_dialog;
+}
+
+void
+gtranslator_application_set_preferences_dialog (GtranslatorApplication *app,
+						GtranslatorPreferencesDialog *dlg)
+{
+  app->priv->preferences_dialog = dlg;
+}
+
+
+/**
+ * gtranslator_application_register_icon:
+ * @app: a #GtranslatorApplication
+ * @icon: the name of the icon
+ * @stock_id: the stock id for the new icon
+ * 
+ * Registers a new @icon with the @stock_id.
+ */
 void
 gtranslator_application_register_icon (GtranslatorApplication *app,
 				       const gchar *icon,
@@ -385,3 +533,40 @@
 	g_free (path);
 	gtk_icon_source_free (icon_source);
 }
+
+/**
+ * gtranslator_application_get_last_dir:
+ * @app: a #GtranslatorApplication
+ *
+ * Return value: the last dir where a file was opened in the GtkFileChooser
+ */
+const gchar *
+_gtranslator_application_get_last_dir (GtranslatorApplication *app)
+{
+	g_return_val_if_fail (GTR_IS_APPLICATION (app), NULL);
+
+	return app->priv->last_dir;
+}
+
+/**
+ * gtranslator_application_set_last_dir:
+ * @app: a #GtranslatorApplication
+ * @last_dir: the path of the last directory where a file was opened in the
+ * GtkFileChooser.
+ */
+void
+_gtranslator_application_set_last_dir (GtranslatorApplication *app,
+				       const gchar *last_dir)
+{
+	g_return_if_fail (GTR_IS_APPLICATION (app));
+
+	app->priv->last_dir = g_strdup (last_dir);
+}
+
+GObject *
+gtranslator_application_get_translation_memory (GtranslatorApplication *app)
+{
+	g_return_val_if_fail (GTR_IS_APPLICATION (app), NULL);
+	
+	return G_OBJECT (app->priv->tm);
+}

Modified: trunk/src/application.h
==============================================================================
--- trunk/src/application.h	(original)
+++ trunk/src/application.h	Tue Sep 16 07:58:13 2008
@@ -23,7 +23,9 @@
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
+#include "profile.h"
 #include "window.h"
+#include "dialogs/preferences-dialog.h"
 
 G_BEGIN_DECLS
 
@@ -81,11 +83,30 @@
 
 GtranslatorWindow *gtranslator_application_get_active_window  (GtranslatorApplication * app);
 
-const GList      *gtranslator_application_get_windows (GtranslatorApplication *app);
+const GList       *gtranslator_application_get_windows (GtranslatorApplication *app);
+
+GtranslatorProfile *gtranslator_application_get_active_profile (GtranslatorApplication *app);
+
+void              gtranslator_application_set_active_profile (GtranslatorApplication *app,
+							      GtranslatorProfile *profile);
+
+GList             *gtranslator_application_get_profiles (GtranslatorApplication *app);
+
+void              gtranslator_application_set_profiles (GtranslatorApplication *app,
+							GList *profiles);
+
+GtranslatorPreferencesDialog *
+gtranslator_application_get_preferences_dialog (GtranslatorApplication *app);
+
+void
+gtranslator_application_set_preferences_dialog (GtranslatorApplication *app,
+						GtranslatorPreferencesDialog *dlg);
 
 void              gtranslator_application_register_icon (GtranslatorApplication *app,
 							 const gchar *icon,
 				       			 const gchar *stock_id);
+				       			 
+GObject          *gtranslator_application_get_translation_memory (GtranslatorApplication *app);
 
 /* Non exported funcs */
 
@@ -93,6 +114,11 @@
 
 void              _gtranslator_application_save_toolbars_model (GtranslatorApplication   *application);
 
+const gchar *     _gtranslator_application_get_last_dir        (GtranslatorApplication *app);
+
+void              _gtranslator_application_set_last_dir        (GtranslatorApplication *app,
+							        const gchar *last_dir);
+
 G_END_DECLS
 
 #endif /* __APPLICATION_H__ */

Added: trunk/src/context.c
==============================================================================
--- (empty file)
+++ trunk/src/context.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2007  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "context.h"
+#include "tab.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#define GTR_CONTEXT_PANEL_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 (object),		       \
+						 GTR_TYPE_CONTEXT_PANEL,     \
+						 GtranslatorContextPanelPrivate))
+
+G_DEFINE_TYPE(GtranslatorContextPanel, gtranslator_context_panel, GTK_TYPE_VBOX)
+
+
+struct _GtranslatorContextPanelPrivate
+{
+	GtkWidget *context;
+
+	GtranslatorTab *tab;
+};
+
+static void
+showed_message_cb (GtranslatorTab *tab,
+		   GtranslatorMsg *msg,
+		   GtranslatorContextPanel *panel)
+{
+	GtkTextBuffer *buffer;
+	GtkTextIter iter;
+	gchar *extracted;
+	gchar *context;
+	gchar *format;
+    	gchar *toset;
+
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (panel->priv->context));
+	gtk_text_buffer_set_text (buffer, "", 0);
+	gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+
+	format = g_strconcat (_("Format: "), gtranslator_msg_get_format (msg), NULL);
+    	context = g_strconcat (_("Context:"), gtranslator_msg_get_msgctxt (msg), NULL);
+    	extracted = g_strconcat (_("Extracted comments:"),
+				 gtranslator_msg_get_extracted_comments(msg), NULL);
+    
+   	toset = g_strdup_printf("%s\n%s\n%s", format, context, extracted);
+    
+    	g_free (format);
+    	g_free (context);
+    	g_free (extracted);
+
+	gtk_text_buffer_insert (buffer, &iter, toset, -1);
+    
+    	g_free (toset);
+}
+
+static void
+gtranslator_context_panel_draw (GtranslatorContextPanel *panel)
+{
+	GtranslatorContextPanelPrivate *priv = panel->priv;
+	GtkWidget *context_scrolled_window;
+	
+	/*
+	 * Set up the scrolling window for the extracted context display
+	 */	
+	context_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (context_scrolled_window),
+				        GTK_POLICY_AUTOMATIC,
+				        GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (context_scrolled_window),
+					     GTK_SHADOW_IN);
+	gtk_box_pack_start (GTK_BOX (panel), context_scrolled_window, TRUE, TRUE, 0);
+	gtk_widget_show (context_scrolled_window);
+
+	/*
+	 * Context
+	 */	
+	priv->context = gtk_text_view_new();
+	
+	gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->context), FALSE);
+	gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->context),
+				     GTK_WRAP_WORD);
+	gtk_container_add (GTK_CONTAINER (context_scrolled_window),
+			   GTK_WIDGET (priv->context));
+	gtk_widget_show (priv->context);
+}
+
+
+static void
+gtranslator_context_panel_init (GtranslatorContextPanel *panel)
+{
+	panel->priv = GTR_CONTEXT_PANEL_GET_PRIVATE (panel);
+	
+	gtranslator_context_panel_draw (panel);
+}
+
+static void
+gtranslator_context_panel_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_context_panel_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_context_panel_class_init (GtranslatorContextPanelClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorContextPanelPrivate));
+
+	object_class->finalize = gtranslator_context_panel_finalize;
+}
+
+/**
+ * gtranslator_context_panel_new:
+ * @tab: a #GtranslatorTab
+ * 
+ * Creates a new #GtranslatorContextPanel object.
+ * 
+ * Returns: a new #GtranslatorContextPanel object
+ */
+GtkWidget *
+gtranslator_context_panel_new (GtkWidget *tab)
+{
+	GtranslatorContextPanel *context;
+	context = g_object_new (GTR_TYPE_CONTEXT_PANEL, NULL);
+	
+	context->priv->tab = GTR_TAB (tab);
+	g_signal_connect (tab,
+			  "showed-message",
+			  G_CALLBACK (showed_message_cb),
+			  context);
+	
+	return GTK_WIDGET (context);
+}
+
+/**
+ * gtranslator_context_panel_get_extracted_text_view:
+ * @panel: a #GtranslatorContextPanel
+ *
+ * Returns: the context #GtkTextView
+ */
+GtkTextView *
+gtranslator_context_panel_get_context_text_view (GtranslatorContextPanel *panel)
+{
+	g_return_if_fail (GTR_IS_CONTEXT_PANEL (panel));
+	
+	return GTK_TEXT_VIEW (panel->priv->context);
+}
+							    

Added: trunk/src/context.h
==============================================================================
--- (empty file)
+++ trunk/src/context.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __CONTEXT_PANEL_H__
+#define __CONTEXT_PANEL_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_CONTEXT_PANEL		(gtranslator_context_panel_get_type ())
+#define GTR_CONTEXT_PANEL(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_CONTEXT_PANEL, GtranslatorContextPanel))
+#define GTR_CONTEXT_PANEL_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_CONTEXT_PANEL, GtranslatorContextPanelClass))
+#define GTR_IS_CONTEXT_PANEL(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_CONTEXT_PANEL))
+#define GTR_IS_CONTEXT_PANEL_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_CONTEXT_PANEL))
+#define GTR_CONTEXT_PANEL_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_CONTEXT_PANEL, GtranslatorContextPanelClass))
+
+/* Private structure type */
+typedef struct _GtranslatorContextPanelPrivate	GtranslatorContextPanelPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorContextPanel		GtranslatorContextPanel;
+
+struct _GtranslatorContextPanel
+{
+	GtkVBox parent_instance;
+	
+	/*< private > */
+	GtranslatorContextPanelPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorContextPanelClass	GtranslatorContextPanelClass;
+
+struct _GtranslatorContextPanelClass
+{
+	GtkVBoxClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_context_panel_get_type	   (void) G_GNUC_CONST;
+
+GType		 gtranslator_context_panel_register_type   (GTypeModule * module);
+
+GtkWidget	*gtranslator_context_panel_new	           (GtkWidget *tab);
+							    
+GtkTextView     *gtranslator_context_panel_get_context_text_view (GtranslatorContextPanel *panel);
+
+G_END_DECLS
+
+#endif /* __CONTEXT_PANEL_H__ */

Added: trunk/src/debug.h
==============================================================================
--- (empty file)
+++ trunk/src/debug.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:debug
+ * @title: Debugging
+ * @short_description: Debug functions
+ * @include: gtranslator/debug.h
+ */
+ 
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ * DEBUG_PRINT:
+ *
+ * Equivalent to g_message(), except it has only effect when DEBUG is
+ * defined. Used for printing debug messages.
+ */
+ 
+#ifdef DEBUG
+#  define DEBUG_PRINT g_message
+#else
+#  define DEBUG_PRINT(...)
+#endif
+
+G_END_DECLS
+
+#endif /* __DEBUG_H__ */

Modified: trunk/src/dialogs/Makefile.am
==============================================================================
--- trunk/src/dialogs/Makefile.am	(original)
+++ trunk/src/dialogs/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -4,7 +4,7 @@
         -I$(top_srcdir)/src                                     \
         -I$(top_builddir)/src                                   \
 	-I$(top_srcdir)/src/plugin-system			\
-	-DDATADIR=\""$(pkgdatadir)"\"				\
+	-DPKGDATADIR=\""$(pkgdatadir)"\"			\
 	-DPIXMAPSDIR=\""$(datadir)"/pixmaps/gtranslator\"	\
         $(GTRANSLATOR_CFLAGS)                                   \
         $(WARN_CFLAGS)                                          \
@@ -27,7 +27,11 @@
 	comment-dialog.c \
 	comment-dialog.h \
 	profile-dialog.c \
-	profile-dialog.h
+	profile-dialog.h \
+	assistant.c \
+	assistant.h \
+	jump-dialog.c \
+	jump-dialog.h
 
 gladedir = $(pkgdatadir)
 
@@ -36,7 +40,8 @@
 		search-dialog.glade \
 		header-dialog.glade \
 		comment-dialog.glade \
-		profile-dialog.glade
+		profile-dialog.glade \
+		jump-dialog.glade
 
 EXTRA_DIST = \
 		$(glade_DATA)

Added: trunk/src/dialogs/assistant.c
==============================================================================
--- (empty file)
+++ trunk/src/dialogs/assistant.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "application.h"
+#include "assistant.h"
+#include "profile.h"
+#include "../translation-memory/translation-memory.h"
+#include "utils.h"
+#include "window.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <string.h>
+#include <gio/gio.h>
+
+#define GTR_ASSISTANT_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 (object),	\
+						 GTR_TYPE_ASSISTANT,     \
+						 GtranslatorAssistantPrivate))
+
+
+G_DEFINE_TYPE(GtranslatorAssistant, gtranslator_assistant, GTK_TYPE_ASSISTANT)
+
+struct _GtranslatorAssistantPrivate
+{
+	/* Profiles Page 1 */
+	GtkWidget *profile_name;
+	GtkWidget *name;
+	GtkWidget *email;
+	GtkWidget *language;
+	GtkWidget *team_email;
+	
+	/* Profiles Page 2 */
+	GtkWidget *lang_code;
+	GtkWidget *charset;
+	GtkWidget *trans_enc;
+	GtkWidget *plural_form;
+	
+	/* Database Page */
+	GtkWidget *path;
+	GtkWidget *search_button;
+	GtkWidget *po_name;
+	
+	/* Confirmation Page */
+	GtkWidget *finish_box;
+	GtkWidget *confirm_label;
+	GtkWidget *add_db_progressbar;
+};
+
+typedef struct _IdleData
+{
+	GSList *list;
+	GtkProgressBar *progress;
+	GtranslatorTranslationMemory *tm;
+	GtkWindow *parent;
+}IdleData;
+
+static gboolean
+add_to_database (gpointer data_pointer)
+{
+	IdleData *data = (IdleData *)data_pointer;
+	static GSList *l = NULL;
+	gdouble percentage;
+	
+	if (l == NULL)
+		l = data->list;
+	else
+		l = g_slist_next (l);
+
+	if (l)
+	{
+		GList *msg_list = NULL;
+		GList *l2 = NULL;
+		GFile *location;
+		GError *error = NULL;
+		GtranslatorPo *po;
+		
+		po = gtranslator_po_new ();
+		location = (GFile *)l->data;
+		
+		gtranslator_po_parse (po, location, &error);
+		if (error)
+			return TRUE;
+		
+		msg_list = gtranslator_po_get_messages (po);
+		
+		for (l2 = msg_list; l2; l2 = g_list_next (l2))
+		{
+			GtranslatorMsg *msg;
+			
+			msg = GTR_MSG (l2->data);
+			if (gtranslator_msg_is_translated (msg))
+				gtranslator_translation_memory_store (data->tm,
+								      gtranslator_msg_get_msgid (msg),
+								      gtranslator_msg_get_msgstr (msg));
+		}
+		
+		g_object_unref (po);
+	}
+	else
+	{
+		GtkWidget *dialog;
+		
+		gtk_progress_bar_set_fraction (data->progress,
+					       1.0);
+		
+		dialog = gtk_message_dialog_new (data->parent,
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_INFO,
+						 GTK_BUTTONS_CLOSE,
+						 NULL);
+		
+		gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
+					       _("<span weight=\"bold\" size=\"large\">Strings added to database</span>"));
+		
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+		
+		return FALSE;
+	}
+	
+	percentage = (gdouble)g_slist_position (data->list, l) / (gdouble) g_slist_length (data->list);
+
+	/*
+	 * Set the progress only if the values are reasonable.
+	 */
+	if(percentage > 0.0 || percentage < 1.0)
+	{
+		/*
+		 * Set the progressbar status.
+		 */
+		gtk_progress_bar_set_fraction (data->progress,
+					       percentage);
+	}
+	
+	return TRUE;
+}
+
+static void
+destroy_idle_data (gpointer data)
+{
+	IdleData *d = (IdleData *)data;
+	
+	gtk_widget_hide (GTK_WIDGET (d->progress));
+	
+	g_slist_foreach (d->list, (GFunc)g_object_unref, NULL);
+	g_slist_free (d->list);
+	
+	gtk_widget_destroy (GTK_WIDGET (d->parent));
+	
+	g_free (d);
+}
+
+static void
+on_assistant_close (GtkAssistant *assistant) 
+{
+  gtk_widget_destroy (GTK_WIDGET (assistant));
+}
+
+static void
+on_assistant_apply (GtkAssistant *assistant)
+{
+	GFile *dir;
+	const gchar *dir_name;
+	IdleData *data;
+	GtranslatorAssistant *as = GTR_ASSISTANT (assistant);
+	const gchar *po_name;
+	GtranslatorProfile *profile;
+	GList *profiles_list;
+	gulong close_signal_id;
+
+	profile = gtranslator_profile_new ();
+
+	gtranslator_profile_set_name (profile, 
+				      gtk_entry_get_text (GTK_ENTRY (as->priv->profile_name)));
+
+	gtranslator_profile_set_author_name (profile,
+					     gtk_entry_get_text (GTK_ENTRY (as->priv->name)));
+	
+	gtranslator_profile_set_author_email (profile,
+					      gtk_entry_get_text (GTK_ENTRY (as->priv->email)));
+					      
+	gtranslator_profile_set_language_name (profile,
+					       gtk_entry_get_text (GTK_ENTRY (as->priv->language)));
+
+	gtranslator_profile_set_language_code (profile,
+					       gtk_entry_get_text (GTK_ENTRY (as->priv->lang_code)));
+
+	gtranslator_profile_set_group_email (profile,
+					     gtk_entry_get_text (GTK_ENTRY (as->priv->team_email)));
+
+	gtranslator_profile_set_charset (profile,
+					 gtk_entry_get_text (GTK_ENTRY (as->priv->charset)));
+
+	gtranslator_profile_set_encoding (profile,
+					  gtk_entry_get_text (GTK_ENTRY (as->priv->trans_enc)));
+					       
+	gtranslator_profile_set_plurals (profile,
+					 gtk_entry_get_text (GTK_ENTRY (as->priv->plural_form)));
+
+	gtranslator_application_set_active_profile (GTR_APP, profile);
+	
+	profiles_list = gtranslator_application_get_profiles (GTR_APP);
+
+	gtranslator_application_set_profiles (GTR_APP,
+					      g_list_append (profiles_list, profile));
+
+	close_signal_id = g_signal_connect (as,
+					    "close",
+					    G_CALLBACK (on_assistant_close),
+					    NULL);
+
+	dir_name = gtk_entry_get_text (GTK_ENTRY (as->priv->path));
+	if (strcmp (dir_name, "") == 0)
+	  return;
+	
+	g_signal_handler_block (as, close_signal_id);
+
+	data = g_new0 (IdleData, 1);
+	data->list = NULL;
+	
+	dir = g_file_new_for_path (dir_name);
+	
+	po_name = gtk_entry_get_text (GTK_ENTRY (as->priv->po_name));
+	
+	gtranslator_utils_scan_dir (dir, &data->list, po_name);
+	
+	data->tm = GTR_TRANSLATION_MEMORY (gtranslator_application_get_translation_memory (GTR_APP));
+	data->progress = GTK_PROGRESS_BAR (as->priv->add_db_progressbar);
+	data->parent = GTK_WINDOW (as);
+	
+	gtk_widget_show (as->priv->add_db_progressbar);
+	
+	g_idle_add_full (G_PRIORITY_HIGH_IDLE + 30,
+			 (GSourceFunc)add_to_database,
+			 data,
+			 (GDestroyNotify)destroy_idle_data);
+	
+	g_object_unref (dir); 
+}
+
+static void
+on_assistant_prepare (GtkAssistant *assistant,
+		      GtkWidget *page)
+{
+	GtranslatorAssistant *as = GTR_ASSISTANT (assistant);
+	gchar *string;
+	const gchar *database_path;
+
+	if (page != as->priv->finish_box)
+		return;
+	
+	database_path = gtk_entry_get_text (GTK_ENTRY (as->priv->path));
+	
+	string = g_strdup_printf (_("Profile name: %s\n"
+				    "Translator name: %s\n"
+				    "Translator email: %s\n"
+				    "Language name: %s\n"
+				    "Team email: %s\n"
+				    "Language code: %s\n"
+				    "Character set: %s\n"
+				    "Transfer encoding: %s\n"
+				    "Plural form: %s\n"
+				    "Database path: %s"),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->profile_name)),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->name)),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->email)),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->language)),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->team_email)),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->lang_code)),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->charset)),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->trans_enc)),
+				  gtk_entry_get_text (GTK_ENTRY (as->priv->plural_form)),
+				  (strcmp (database_path, "") != 0) ? database_path : _("None"));
+
+	gtk_label_set_text (GTK_LABEL (as->priv->confirm_label), string);
+	g_free (string);
+}
+
+static void
+on_assistant_cancel (GtkAssistant* assistant)
+{
+	gtk_widget_destroy (GTK_WIDGET (assistant));
+}
+
+static void
+create_start_page (GtranslatorAssistant *as)
+{
+	GtkWidget *box, *label;
+
+	box = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (box);
+	gtk_container_set_border_width (GTK_CONTAINER (box), 12);
+
+	label = gtk_label_new (_("This assistant will help you to create the main profile\n"
+			       "and generate your translation memory database."));
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
+
+	gtk_assistant_append_page (GTK_ASSISTANT (as), box);
+	gtk_assistant_set_page_title (GTK_ASSISTANT (as), box, _("Assistant"));
+	gtk_assistant_set_page_complete (GTK_ASSISTANT (as), box, TRUE);
+	gtk_assistant_set_page_type (GTK_ASSISTANT (as), box, GTK_ASSISTANT_PAGE_INTRO);
+}
+
+static void
+on_profile1_entry_changed (GtkWidget *widget,
+			   GtranslatorAssistant *as)
+{
+	const gchar *text;
+	GtkWidget *current_page;
+	gint page_number;
+	
+	page_number = gtk_assistant_get_current_page (GTK_ASSISTANT (as));
+	current_page = gtk_assistant_get_nth_page (GTK_ASSISTANT (as), page_number);
+	
+	/* Profile name */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->profile_name));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+	{
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+		return;
+	}
+	
+	/* Translator name */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->name));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+	{
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+		return;
+	}
+	
+	/* Translator email */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->email));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+	{
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+		return;
+	}
+	
+	/* Language */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->language));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+	{
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+		return;
+	}
+	
+	/* Team email */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->team_email));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+}
+
+static void
+create_profiles_page1 (GtranslatorAssistant *as)
+{
+	GtkWidget *box, *hbox;
+	GtkWidget *label;
+	GtranslatorAssistantPrivate *priv = as->priv;
+
+	box = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (box);
+	gtk_container_set_border_width (GTK_CONTAINER (box), 5);
+
+	/*
+	 * Profile name:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Profile name:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->profile_name = gtk_entry_new ();
+	gtk_widget_show (priv->profile_name);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->profile_name, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->profile_name), "changed",
+			  G_CALLBACK (on_profile1_entry_changed), as);
+	
+	/*
+	 * Translator name:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Translator name:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->name = gtk_entry_new ();
+	gtk_widget_show (priv->name);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->name, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->name), "changed",
+			  G_CALLBACK (on_profile1_entry_changed), as);
+	
+	/*
+	 * Translator email:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Translator email:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->email = gtk_entry_new ();
+	gtk_widget_show (priv->email);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->email, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->email), "changed",
+			  G_CALLBACK (on_profile1_entry_changed), as);
+	
+	/*
+	 * Translator language:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Language:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->language = gtk_entry_new ();
+	gtk_widget_show (priv->language);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->language, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->language), "changed",
+			  G_CALLBACK (on_profile1_entry_changed), as);
+	
+	/*
+	 * Translator team email:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Team email:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->team_email = gtk_entry_new ();
+	gtk_widget_show (priv->team_email);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->team_email, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->team_email), "changed",
+			  G_CALLBACK (on_profile1_entry_changed), as);
+
+	gtk_assistant_append_page (GTK_ASSISTANT (as), box);
+	gtk_assistant_set_page_title (GTK_ASSISTANT (as), box, _("Profile"));
+}
+
+static void
+on_profile2_entry_changed (GtkWidget *widget,
+			   GtranslatorAssistant *as)
+{
+	const gchar *text;
+	GtkWidget *current_page;
+	gint page_number;
+	
+	page_number = gtk_assistant_get_current_page (GTK_ASSISTANT (as));
+	current_page = gtk_assistant_get_nth_page (GTK_ASSISTANT (as), page_number);
+	
+	/* Lang code */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->lang_code));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+	{
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+		return;
+	}
+	
+	/* Charset */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->charset));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+	{
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+		return;
+	}
+	
+	/* Trans encoding */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->trans_enc));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+	{
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+		return;
+	}
+	
+	/* Plural form */
+	text = gtk_entry_get_text (GTK_ENTRY (as->priv->plural_form));
+	
+	if (text && *text)
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, TRUE);
+	else
+		gtk_assistant_set_page_complete (GTK_ASSISTANT (as), current_page, FALSE);
+}
+
+static void
+create_profiles_page2 (GtranslatorAssistant *as)
+{
+	GtkWidget *box, *hbox;
+	GtkWidget *label;
+	GtranslatorAssistantPrivate *priv = as->priv;
+
+	box = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (box);
+	gtk_container_set_border_width (GTK_CONTAINER (box), 5);
+
+	/*
+	 * Language code:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Language code:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->lang_code = gtk_entry_new ();
+	gtk_widget_show (priv->lang_code);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->lang_code, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->lang_code), "changed",
+			  G_CALLBACK (on_profile2_entry_changed), as);
+	
+	/*
+	 * Charset:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Character set:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->charset = gtk_entry_new ();
+	gtk_widget_show (priv->charset);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->charset, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->charset), "changed",
+			  G_CALLBACK (on_profile2_entry_changed), as);
+	
+	/*
+	 * Transfer enconding:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Transfer encoding:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->trans_enc = gtk_entry_new ();
+	gtk_widget_show (priv->trans_enc);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->trans_enc, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->trans_enc), "changed",
+			  G_CALLBACK (on_profile2_entry_changed), as);
+	
+	/*
+	 * Plural form:
+	 */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Plural forms:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	
+	priv->plural_form = gtk_entry_new ();
+	gtk_widget_show (priv->plural_form);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->plural_form, FALSE, FALSE, 0);
+	g_signal_connect (G_OBJECT (priv->plural_form), "changed",
+			  G_CALLBACK (on_profile2_entry_changed), as);
+
+	gtk_assistant_append_page (GTK_ASSISTANT (as), box);
+	gtk_assistant_set_page_title (GTK_ASSISTANT (as), box, _("Profile"));
+}
+
+static void
+on_dir_find_button_clicked (GtkButton *button,
+			    GtranslatorAssistant *as)
+{
+	GtkWidget *dialog;
+	gint res;
+	
+	dialog = gtk_file_chooser_dialog_new (_("Checkout directory"),
+					      GTK_WINDOW (as),
+					      GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
+					      GTK_STOCK_CANCEL,
+					      GTK_RESPONSE_CANCEL,
+					      GTK_STOCK_OK,
+					      GTK_RESPONSE_OK,
+					      NULL);
+	res = gtk_dialog_run (GTK_DIALOG (dialog));
+	switch (res)
+	{
+		case GTK_RESPONSE_OK: 
+		{
+			gchar *filename;
+			
+			filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+			gtk_entry_set_text (GTK_ENTRY (as->priv->path),
+					    filename);
+			g_free (filename);
+			break;
+		}
+		default:
+			break;
+	}
+	gtk_widget_destroy (dialog);
+}
+
+static void
+create_database_page (GtranslatorAssistant *as)
+{
+	GtkWidget *box, *hbox;
+	GtkWidget *label;
+	GtranslatorAssistantPrivate *priv = as->priv;
+
+	box = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (box);
+	gtk_container_set_border_width (GTK_CONTAINER (box), 5);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Select the path to generate the database:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+	
+	/* hbox */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	/* Path entry */
+	priv->path = gtk_entry_new ();
+	gtk_widget_show (priv->path);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->path, TRUE, TRUE, 0);
+	
+	/* Search button */
+	priv->search_button = gtk_button_new_from_stock (GTK_STOCK_FIND);
+	gtk_widget_show (priv->search_button);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->search_button,
+			    FALSE, FALSE, 0);
+	g_signal_connect (priv->search_button, "clicked",
+			  G_CALLBACK (on_dir_find_button_clicked), as);
+	
+	/* Po name label */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+	
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      _("<b>Look for a specific PO filename:</b>"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	
+	/* Po name entry */
+	priv->po_name = gtk_entry_new ();
+	gtk_widget_show (priv->po_name);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->po_name, TRUE, TRUE, 0);
+	gtk_widget_set_tooltip_text (priv->po_name, _("E.g.: gl.po"));
+	
+	gtk_assistant_append_page (GTK_ASSISTANT (as), box);
+	gtk_assistant_set_page_title (GTK_ASSISTANT (as), box, _("Generate Database"));
+	gtk_assistant_set_page_complete (GTK_ASSISTANT (as), box, TRUE);
+}
+
+static void
+create_finish_page (GtranslatorAssistant *as)
+{
+	as->priv->finish_box = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (as->priv->finish_box);
+	
+	as->priv->confirm_label = gtk_label_new (NULL);
+	gtk_widget_show (as->priv->confirm_label);
+	gtk_box_pack_start (GTK_BOX (as->priv->finish_box), as->priv->confirm_label,
+			    TRUE, TRUE, 0);
+	
+	as->priv->add_db_progressbar = gtk_progress_bar_new ();
+	gtk_widget_show (as->priv->add_db_progressbar);
+	gtk_box_pack_start (GTK_BOX (as->priv->finish_box), as->priv->add_db_progressbar,
+			    FALSE, FALSE, 0);
+	
+	gtk_assistant_append_page (GTK_ASSISTANT (as), as->priv->finish_box);
+	gtk_assistant_set_page_type (GTK_ASSISTANT (as), as->priv->finish_box,
+				     GTK_ASSISTANT_PAGE_CONFIRM);
+	gtk_assistant_set_page_complete (GTK_ASSISTANT (as), as->priv->finish_box, TRUE);
+	gtk_assistant_set_page_title (GTK_ASSISTANT (as), as->priv->finish_box, _("Confirmation"));
+}
+
+static void
+gtranslator_assistant_init (GtranslatorAssistant *as)
+{	
+	as->priv = GTR_ASSISTANT_GET_PRIVATE (as);
+	
+	//gtk_window_set_default_size (GTK_WINDOW (as), 300, 200);
+	gtk_window_set_resizable (GTK_WINDOW (as), TRUE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (as), TRUE);
+	
+	create_start_page (as);
+	create_profiles_page1 (as);
+	create_profiles_page2 (as);
+	create_database_page (as);
+	create_finish_page (as);
+}
+
+static void
+gtranslator_assistant_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_assistant_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_assistant_class_init (GtranslatorAssistantClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtkAssistantClass *assistant_class = GTK_ASSISTANT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorAssistantPrivate));
+
+	object_class->finalize = gtranslator_assistant_finalize;
+	assistant_class->prepare = on_assistant_prepare;
+	assistant_class->apply = on_assistant_apply;
+	assistant_class->cancel = on_assistant_cancel;
+	//assistant_class->close = on_assistant_close;
+}
+
+void
+gtranslator_show_assistant (GtranslatorWindow *window)
+{
+	static GtranslatorAssistant *assist = NULL;
+	
+	g_return_if_fail(GTR_IS_WINDOW(window));
+	
+	if(assist == NULL)
+	{
+		assist = g_object_new (GTR_TYPE_ASSISTANT, NULL);
+		g_signal_connect (assist,
+				  "destroy",
+				  G_CALLBACK (gtk_widget_destroyed),
+				  &assist);
+
+		gtk_widget_show (GTK_WIDGET(assist));
+	}
+	
+	if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (assist)))
+	{
+		gtk_window_set_transient_for (GTK_WINDOW (assist),
+					      GTK_WINDOW (window));
+	}
+
+	gtk_window_present (GTK_WINDOW (assist));
+}

Added: trunk/src/dialogs/assistant.h
==============================================================================
--- (empty file)
+++ trunk/src/dialogs/assistant.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __ASSISTANT_H__
+#define __ASSISTANT_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "window.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_ASSISTANT		(gtranslator_assistant_get_type ())
+#define GTR_ASSISTANT(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_ASSISTANT, GtranslatorAssistant))
+#define GTR_ASSISTANT_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_ASSISTANT, GtranslatorAssistantClass))
+#define GTR_IS_ASSISTANT(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_ASSISTANT))
+#define GTR_IS_ASSISTANT_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_ASSISTANT))
+#define GTR_ASSISTANT_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_ASSISTANT, GtranslatorAssistantClass))
+
+/* Private structure type */
+typedef struct _GtranslatorAssistantPrivate	GtranslatorAssistantPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorAssistant		GtranslatorAssistant;
+
+struct _GtranslatorAssistant
+{
+	GtkAssistant parent_instance;
+	
+	/*< private > */
+	GtranslatorAssistantPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorAssistantClass	GtranslatorAssistantClass;
+
+struct _GtranslatorAssistantClass
+{
+	GtkAssistantClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_assistant_get_type               (void) G_GNUC_CONST;
+
+GType		 gtranslator_assistant_register_type          (GTypeModule * module);
+
+void	         gtranslator_show_assistant                   (GtranslatorWindow *window);
+
+G_END_DECLS
+
+#endif /* __ASSISTANT_H__ */

Modified: trunk/src/dialogs/close-confirmation-dialog.c
==============================================================================
--- trunk/src/dialogs/close-confirmation-dialog.c	(original)
+++ trunk/src/dialogs/close-confirmation-dialog.c	Tue Sep 16 07:58:13 2008
@@ -356,7 +356,8 @@
 	GtkWidget     *primary_label;
 	GtkWidget     *image;
 	GtranslatorPo *doc;
-	const gchar   *doc_name;
+	GFile         *location;
+	gchar         *doc_name;
 	gchar         *str;
 	gchar         *markup_str;
 
@@ -375,10 +376,13 @@
 	gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5);
 	gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
 
-	doc_name = gtranslator_po_get_filename (doc);
+	location = gtranslator_po_get_location (doc);
+	doc_name = g_file_get_path (location);
+	g_object_unref (location);
 
 	str = g_markup_printf_escaped (_("Save the changes to document \"%s\" before closing?"),
 				       doc_name);
+	g_free (doc_name);
 
 	markup_str = g_strconcat ("<span weight=\"bold\" size=\"larger\">", str, "</span>", NULL);
 	g_free (str);
@@ -415,11 +419,14 @@
 	while (docs != NULL)
 	{
 		GtranslatorPo *po;
-		const gchar *name;
+		GFile *location;
+		gchar *name;
 
 		po = GTR_PO (docs->data);
 
-		name = gtranslator_po_get_filename (po);
+		location = gtranslator_po_get_location (po);
+		name = g_file_get_path (location);
+		g_object_unref (location);
 
 		gtk_list_store_append (GTK_LIST_STORE (store), &iter);
 		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
@@ -428,6 +435,7 @@
 				    DOC_COLUMN, po,
 			            -1);
 
+		g_free (name);
 		docs = g_list_next (docs);
 	}
 }

Modified: trunk/src/dialogs/comment-dialog.c
==============================================================================
--- trunk/src/dialogs/comment-dialog.c	(original)
+++ trunk/src/dialogs/comment-dialog.c	Tue Sep 16 07:58:13 2008
@@ -21,7 +21,6 @@
 #endif
 
 #include "comment-dialog.h"
-#include "comment.h"
 #include "tab.h"
 #include "utils.h"
 #include "window.h"
@@ -45,7 +44,7 @@
 	GtkWidget *main_box;
 	GtkWidget *comment;
 };
-
+		    
 static void
 comment_changed_cb (GtkTextBuffer *buffer,
 		    GtranslatorWindow *window)
@@ -53,23 +52,18 @@
 	gchar *text;
 	GtkTextIter start, end;
 	GtranslatorTab *tab;
-	GtranslatorCommentPanel *comment;
 	GtranslatorPo *po;
 	GList *msg;
 	
 	tab = gtranslator_window_get_active_tab(window);
 	po = gtranslator_tab_get_po(tab);
-	comment = gtranslator_tab_get_comment_panel(tab);
 	msg = gtranslator_po_get_current_message(po);
 	
 	gtk_text_buffer_get_bounds(buffer, &start, &end);
 	text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE);
 	
 	gtranslator_msg_set_comment(msg->data, text);
-
-	gtranslator_comment_panel_set_comments(comment, text);
 }
-		    
 
 static void
 dialog_response_handler (GtkDialog *dlg, 
@@ -113,7 +107,7 @@
 			  NULL);
 	
 	/*Glade*/
-	ret = gtranslator_utils_get_glade_widgets(DATADIR "/comment-dialog.glade",
+	ret = gtranslator_utils_get_glade_widgets(PKGDATADIR "/comment-dialog.glade",
 		"main_box",
 		&error_widget,
 		
@@ -173,11 +167,12 @@
 				  "destroy",
 				  G_CALLBACK (gtk_widget_destroyed),
 				  &dlg);
-		g_signal_connect(buf,
-				 "changed",
-				 G_CALLBACK (comment_changed_cb),
-				 window);
-		gtk_widget_show_all(GTK_WIDGET(dlg));
+		g_signal_connect (buf,
+				  "changed",
+				  G_CALLBACK (comment_changed_cb),
+				  window);
+
+		gtk_widget_show (GTK_WIDGET(dlg));
 	}
 	
 	gtk_text_buffer_set_text(buf, gtranslator_msg_get_comment(msg->data), -1); 

Modified: trunk/src/dialogs/file-dialogs.c
==============================================================================
--- trunk/src/dialogs/file-dialogs.c	(original)
+++ trunk/src/dialogs/file-dialogs.c	Tue Sep 16 07:58:13 2008
@@ -31,7 +31,8 @@
 GtkWidget *
 gtranslator_file_chooser_new (GtkWindow *parent,
 			      FileselMode mode,
-			      gchar *title)
+			      const gchar *title,
+			      const gchar *dir)
 {
 	GtkWidget *dialog;
 	GtkFileFilter *filter;
@@ -43,6 +44,11 @@
 					     (mode == FILESEL_SAVE) ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
 					     NULL);
 	gtk_dialog_set_default_response(GTK_DIALOG(dialog),GTK_RESPONSE_ACCEPT);
+
+	if (dir)
+		gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), 
+							 dir);
+
 	if (mode != FILESEL_SAVE)
 	{
 		/* We set a multi selection dialog */
@@ -57,7 +63,7 @@
 	
 		filter = gtk_file_filter_new();
 		gtk_file_filter_set_name(filter,_("Gettext translation template"));
-		gtk_file_filter_add_mime_type(filter,"text/x-gettext-translation-template");
+		gtk_file_filter_add_pattern(filter,"*.pot");
 		gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter);
 		
 		filter = gtk_file_filter_new();

Modified: trunk/src/dialogs/file-dialogs.h
==============================================================================
--- trunk/src/dialogs/file-dialogs.h	(original)
+++ trunk/src/dialogs/file-dialogs.h	Tue Sep 16 07:58:13 2008
@@ -29,6 +29,7 @@
 
 GtkWidget	*gtranslator_file_chooser_new			(GtkWindow *parent,
 								 FileselMode mode,
-								 gchar *title);
+								 const gchar *title,
+								 const gchar *dir);
 
 #endif

Modified: trunk/src/dialogs/header-dialog.c
==============================================================================
--- trunk/src/dialogs/header-dialog.c	(original)
+++ trunk/src/dialogs/header-dialog.c	Tue Sep 16 07:58:13 2008
@@ -78,7 +78,7 @@
 
 static void
 take_my_options_checkbutton_toggled(GtkToggleButton *button,
-				  GtranslatorHeaderDialog *dlg)
+				    GtranslatorHeaderDialog *dlg)
 {
 	g_return_if_fail(button == GTK_TOGGLE_BUTTON(dlg->priv->take_my_options));
 	
@@ -98,6 +98,8 @@
 {
 	const gchar *text;
 
+	gtranslator_header_set_header_changed (header, TRUE);
+
 	text = gtk_entry_get_text(GTK_ENTRY(gobject));
 
 	if (text)
@@ -111,6 +113,8 @@
 {
 	const gchar *text;
 
+	gtranslator_header_set_header_changed (header, TRUE);
+
 	text = gtk_entry_get_text(GTK_ENTRY(gobject));
 
 	if (text)
@@ -124,6 +128,8 @@
 {
 	const gchar *text;
 
+	gtranslator_header_set_header_changed (header, TRUE);
+
 	text = gtk_entry_get_text(GTK_ENTRY(gobject));
 
 	if (text)
@@ -137,6 +143,8 @@
 {
 	const gchar *text;
 
+	gtranslator_header_set_header_changed (header, TRUE);
+
 	text = gtk_entry_get_text(GTK_ENTRY(gobject));
 
 	if (text)
@@ -150,6 +158,8 @@
 {
 	const gchar *text;
 
+	gtranslator_header_set_header_changed (header, TRUE);
+
 	text = gtk_entry_get_text(GTK_ENTRY(gobject));
 
 	if (text)
@@ -163,6 +173,8 @@
 {
 	const gchar *text;
 
+	gtranslator_header_set_header_changed (header, TRUE);
+
 	text = gtk_entry_get_text(GTK_ENTRY(gobject));
 	
 	if (text)
@@ -200,8 +212,12 @@
 
 static void save_header(GtranslatorPo *po)
 {
-	gtranslator_po_save_header_in_msg (po);
-	gtranslator_po_set_state (po, GTR_PO_STATE_MODIFIED);
+        GtranslatorHeader *header;
+
+	header = gtranslator_po_get_header (po);
+
+        if (gtranslator_header_get_header_changed (header))
+	  gtranslator_po_set_state (po, GTR_PO_STATE_MODIFIED);
 } 
 
 static void gtranslator_header_dialog_init (GtranslatorHeaderDialog *dlg)
@@ -231,12 +247,12 @@
 			  G_CALLBACK (gtk_widget_destroy),
 			  NULL);
 	
-	ret = gtranslator_utils_get_glade_widgets(DATADIR"/header-dialog.glade",
+	ret = gtranslator_utils_get_glade_widgets(PKGDATADIR"/header-dialog.glade",
 		"main_box",
 		&error_widget,
 		"main_box", &dlg->priv->main_box,
 		"notebook", &dlg->priv->notebook,
-		"vbox1", &dlg->priv->lang_vbox,
+		"lang_vbox", &dlg->priv->lang_vbox,
 		"prj_id_version", &dlg->priv->prj_id_version,
 		"rmbt", &dlg->priv->rmbt,
 		"prj_comment", &dlg->priv->prj_comment,
@@ -272,6 +288,15 @@
 	gtk_widget_set_sensitive(dlg->priv->po_date, FALSE);
 	gtk_widget_set_sensitive(dlg->priv->charset, FALSE);
 
+	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (dlg->priv->take_my_options))) {
+	  
+	  gtk_widget_set_sensitive(dlg->priv->translator, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (dlg->priv->take_my_options)));
+	  gtk_widget_set_sensitive(dlg->priv->tr_email, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (dlg->priv->take_my_options)));
+	  gtk_widget_set_sensitive(dlg->priv->language, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (dlg->priv->take_my_options)));
+	  gtk_widget_set_sensitive(dlg->priv->lg_email, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (dlg->priv->take_my_options)));
+	  gtk_widget_set_sensitive(dlg->priv->encoding, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (dlg->priv->take_my_options)));
+	}
+
 	/*Connect signals*/
 	g_signal_connect(dlg->priv->take_my_options, "toggled",
 			 G_CALLBACK(take_my_options_checkbutton_toggled),

Modified: trunk/src/dialogs/header-dialog.glade
==============================================================================
--- trunk/src/dialogs/header-dialog.glade	(original)
+++ trunk/src/dialogs/header-dialog.glade	Tue Sep 16 07:58:13 2008
@@ -2,342 +2,66 @@
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
 <!--*- mode: xml -*-->
 <glade-interface>
-  <widget class="GtkDialog" id="e_header">
-    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+  <widget class="GtkDialog" id="header_dialog">
     <property name="border_width">5</property>
-    <property name="title" translatable="yes">Edit Header</property>
-    <property name="modal">True</property>
     <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
-    <property name="destroy_with_parent">True</property>
     <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
     <property name="has_separator">False</property>
     <child internal-child="vbox">
-      <widget class="GtkVBox" id="main_box">
+      <widget class="GtkVBox" id="dialog-vbox2">
         <property name="visible">True</property>
         <property name="spacing">2</property>
         <child>
-          <widget class="GtkNotebook" id="notebook">
+          <widget class="GtkVBox" id="main_box">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
             <child>
-              <widget class="GtkScrolledWindow" id="scrolledwindow1">
+              <widget class="GtkNotebook" id="notebook">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="border_width">6</property>
-                <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-                <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
                 <child>
-                  <widget class="GtkTextView" id="prj_comment">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="editable">False</property>
-                  </widget>
-                </child>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="label3">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Comment</property>
-              </widget>
-              <packing>
-                <property name="type">tab</property>
-                <property name="position">2</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkTable" id="table1">
-                <property name="visible">True</property>
-                <property name="border_width">6</property>
-                <property name="n_rows">5</property>
-                <property name="n_columns">3</property>
-                <property name="row_spacing">6</property>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label15">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                  </widget>
-                  <packing>
-                    <property name="x_options"></property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label16">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
-                    <property name="x_options"></property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label17">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">2</property>
-                    <property name="bottom_attach">3</property>
-                    <property name="x_options"></property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label18">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">3</property>
-                    <property name="bottom_attach">4</property>
-                    <property name="x_options"></property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label19">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">4</property>
-                    <property name="bottom_attach">5</property>
-                    <property name="x_options"></property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label23">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">12</property>
-                    <property name="label" translatable="yes">Project Id _version:</property>
-                    <property name="use_underline">True</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkEntry" id="prj_id_version">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">2</property>
-                    <property name="right_attach">3</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label24">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">12</property>
-                    <property name="label" translatable="yes">Pot _file creation date:</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">pot_date</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkEntry" id="pot_date">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="editable">False</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">2</property>
-                    <property name="right_attach">3</property>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label25">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">12</property>
-                    <property name="label" translatable="yes">Po file _revision date:</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">po_date</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">2</property>
-                    <property name="bottom_attach">3</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkEntry" id="po_date">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="editable">False</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">2</property>
-                    <property name="right_attach">3</property>
-                    <property name="top_attach">2</property>
-                    <property name="bottom_attach">3</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label26">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">12</property>
-                    <property name="label" translatable="yes">Report message _bugs to:</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">rmbt</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">3</property>
-                    <property name="bottom_attach">4</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkEntry" id="rmbt">
+                  <widget class="GtkScrolledWindow" id="scrolledwindow1">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <property name="border_width">6</property>
+                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="shadow_type">GTK_SHADOW_IN</property>
+                    <child>
+                      <widget class="GtkTextView" id="prj_comment">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="editable">False</property>
+                      </widget>
+                    </child>
                   </widget>
-                  <packing>
-                    <property name="left_attach">2</property>
-                    <property name="right_attach">3</property>
-                    <property name="top_attach">3</property>
-                    <property name="bottom_attach">4</property>
-                    <property name="y_options"></property>
-                  </packing>
                 </child>
-              </widget>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="label1">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Project</property>
-              </widget>
-              <packing>
-                <property name="type">tab</property>
-                <property name="position">1</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox1">
-                <property name="visible">True</property>
-                <property name="border_width">6</property>
                 <child>
-                  <widget class="GtkCheckButton" id="take_my_options">
+                  <widget class="GtkLabel" id="label3">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="label" translatable="yes">Use my options to complete the following entries:</property>
-                    <property name="use_underline">True</property>
-                    <property name="response_id">0</property>
-                    <property name="draw_indicator">True</property>
+                    <property name="label" translatable="yes">Comment</property>
                   </widget>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="padding">6</property>
+                    <property name="type">tab</property>
+                    <property name="position">2</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
                 <child>
-                  <widget class="GtkTable" id="lang_page">
+                  <widget class="GtkTable" id="table1">
                     <property name="visible">True</property>
-                    <property name="n_rows">6</property>
+                    <property name="border_width">6</property>
+                    <property name="n_rows">5</property>
                     <property name="n_columns">3</property>
                     <property name="row_spacing">6</property>
                     <child>
-                      <widget class="GtkEntry" id="encoding_entry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">5</property>
-                        <property name="bottom_attach">6</property>
-                        <property name="y_options"></property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkEntry" id="charset_entry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="editable">False</property>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">4</property>
-                        <property name="bottom_attach">5</property>
-                        <property name="y_options"></property>
-                      </packing>
+                      <placeholder/>
                     </child>
                     <child>
-                      <widget class="GtkEntry" id="lg_email_entry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
-                        <property name="y_options"></property>
-                      </packing>
+                      <placeholder/>
                     </child>
                     <child>
-                      <widget class="GtkEntry" id="language_entry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                        <property name="y_options"></property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkLabel" id="label27">
+                      <widget class="GtkLabel" id="label15">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                       </widget>
@@ -347,7 +71,7 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label28">
+                      <widget class="GtkLabel" id="label16">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                       </widget>
@@ -359,7 +83,7 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label29">
+                      <widget class="GtkLabel" id="label17">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                       </widget>
@@ -371,7 +95,7 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label30">
+                      <widget class="GtkLabel" id="label18">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                       </widget>
@@ -383,7 +107,7 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label31">
+                      <widget class="GtkLabel" id="label19">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                       </widget>
@@ -395,41 +119,39 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label32">
+                      <widget class="GtkLabel" id="label23">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
+                        <property name="xpad">12</property>
+                        <property name="label" translatable="yes">Project Id _version:</property>
+                        <property name="use_underline">True</property>
                       </widget>
                       <packing>
-                        <property name="top_attach">5</property>
-                        <property name="bottom_attach">6</property>
-                        <property name="x_options"></property>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label33">
+                      <widget class="GtkEntry" id="prj_id_version">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="xpad">12</property>
-                        <property name="label" translatable="yes">Translator's _name:</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">tr_name</property>
+                        <property name="can_focus">True</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="x_options">GTK_FILL</property>
+                        <property name="left_attach">2</property>
+                        <property name="right_attach">3</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label34">
+                      <widget class="GtkLabel" id="label24">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                         <property name="xpad">12</property>
-                        <property name="label" translatable="yes">Translator's _email:</property>
+                        <property name="label" translatable="yes">Pot _file creation date:</property>
                         <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">tr_email</property>
+                        <property name="mnemonic_widget">pot_date</property>
                       </widget>
                       <packing>
                         <property name="left_attach">1</property>
@@ -441,117 +163,397 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label35">
+                      <widget class="GtkEntry" id="pot_date">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="xpad">12</property>
-                        <property name="label" translatable="yes">_Language:</property>
-                        <property name="use_underline">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="editable">False</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                        <property name="x_options">GTK_FILL</property>
+                        <property name="left_attach">2</property>
+                        <property name="right_attach">3</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label36">
+                      <widget class="GtkLabel" id="label25">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                         <property name="xpad">12</property>
-                        <property name="label" translatable="yes">Language gro_up email:</property>
+                        <property name="label" translatable="yes">Po file _revision date:</property>
                         <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">po_date</property>
                       </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label37">
+                      <widget class="GtkEntry" id="po_date">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="xpad">12</property>
-                        <property name="label" translatable="yes">Char_set:</property>
-                        <property name="use_underline">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="editable">False</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">4</property>
-                        <property name="bottom_attach">5</property>
-                        <property name="x_options">GTK_FILL</property>
+                        <property name="left_attach">2</property>
+                        <property name="right_attach">3</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label38">
+                      <widget class="GtkLabel" id="label26">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                         <property name="xpad">12</property>
-                        <property name="label" translatable="yes">Enc_oding:</property>
+                        <property name="label" translatable="yes">Report message _bugs to:</property>
                         <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">rmbt</property>
                       </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">5</property>
-                        <property name="bottom_attach">6</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkEntry" id="tr_name">
+                      <widget class="GtkEntry" id="rmbt">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                       </widget>
                       <packing>
                         <property name="left_attach">2</property>
                         <property name="right_attach">3</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Project</property>
+                  </widget>
+                  <packing>
+                    <property name="type">tab</property>
+                    <property name="position">1</property>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="lang_vbox">
+                    <property name="visible">True</property>
+                    <property name="border_width">6</property>
                     <child>
-                      <widget class="GtkEntry" id="tr_email">
+                      <widget class="GtkCheckButton" id="take_my_options">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
+                        <property name="label" translatable="yes">Use my options to complete the following entries:</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                        <property name="y_options"></property>
+                        <property name="expand">False</property>
+                        <property name="padding">6</property>
                       </packing>
                     </child>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
+                    <child>
+                      <widget class="GtkTable" id="lang_page">
+                        <property name="visible">True</property>
+                        <property name="n_rows">6</property>
+                        <property name="n_columns">3</property>
+                        <property name="row_spacing">6</property>
+                        <child>
+                          <widget class="GtkEntry" id="encoding_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">2</property>
+                            <property name="right_attach">3</property>
+                            <property name="top_attach">5</property>
+                            <property name="bottom_attach">6</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="charset_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="editable">False</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">2</property>
+                            <property name="right_attach">3</property>
+                            <property name="top_attach">4</property>
+                            <property name="bottom_attach">5</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="lg_email_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">2</property>
+                            <property name="right_attach">3</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="language_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">2</property>
+                            <property name="right_attach">3</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label27">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </widget>
+                          <packing>
+                            <property name="x_options"></property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label28">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options"></property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label29">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                            <property name="x_options"></property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label30">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                            <property name="x_options"></property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label31">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">4</property>
+                            <property name="bottom_attach">5</property>
+                            <property name="x_options"></property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label32">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">5</property>
+                            <property name="bottom_attach">6</property>
+                            <property name="x_options"></property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label33">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xpad">12</property>
+                            <property name="label" translatable="yes">Translator's _name:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">tr_name</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label34">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xpad">12</property>
+                            <property name="label" translatable="yes">Translator's _email:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">tr_email</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label35">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xpad">12</property>
+                            <property name="label" translatable="yes">_Language:</property>
+                            <property name="use_underline">True</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label36">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xpad">12</property>
+                            <property name="label" translatable="yes">Language gro_up email:</property>
+                            <property name="use_underline">True</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label37">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xpad">12</property>
+                            <property name="label" translatable="yes">Char_set:</property>
+                            <property name="use_underline">True</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">4</property>
+                            <property name="bottom_attach">5</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label38">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xpad">12</property>
+                            <property name="label" translatable="yes">Enc_oding:</property>
+                            <property name="use_underline">True</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">5</property>
+                            <property name="bottom_attach">6</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="tr_name">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">2</property>
+                            <property name="right_attach">3</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="tr_email">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">2</property>
+                            <property name="right_attach">3</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Translator and Language</property>
+                  </widget>
+                  <packing>
+                    <property name="type">tab</property>
+                    <property name="position">2</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
               </widget>
-              <packing>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="label2">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Translator and Language</property>
-              </widget>
-              <packing>
-                <property name="type">tab</property>
-                <property name="position">2</property>
-                <property name="tab_fill">False</property>
-              </packing>
             </child>
           </widget>
           <packing>
@@ -559,14 +561,15 @@
           </packing>
         </child>
         <child internal-child="action_area">
-          <widget class="GtkHButtonBox" id="dialog-action_area1">
+          <widget class="GtkHButtonBox" id="dialog-action_area2">
             <property name="visible">True</property>
             <property name="layout_style">GTK_BUTTONBOX_END</property>
             <child>
               <widget class="GtkButton" id="button1">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="label">gtk-close</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="no">gtk-close</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">0</property>
               </widget>

Added: trunk/src/dialogs/jump-dialog.c
==============================================================================
--- (empty file)
+++ trunk/src/dialogs/jump-dialog.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "jump-dialog.h"
+#include "tab.h"
+#include "utils.h"
+#include "window.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+
+#define GTR_JUMP_DIALOG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 	(object),	\
+						 	GTR_TYPE_JUMP_DIALOG,     \
+						 	GtranslatorJumpDialogPrivate))
+
+
+G_DEFINE_TYPE(GtranslatorJumpDialog, gtranslator_jump_dialog, GTK_TYPE_DIALOG)
+
+struct _GtranslatorJumpDialogPrivate
+{
+	GtkWidget *main_box;
+	GtkWidget *jump;
+	
+	GtranslatorWindow *window;
+};
+
+static void
+dialog_response_handler (GtkDialog *dlg, 
+			 gint       res_id)
+{
+	GtranslatorJumpDialog *dialog = GTR_JUMP_DIALOG (dlg);
+	GtranslatorTab *tab;
+	gint number;
+
+	switch (res_id)
+	{
+		case GTK_RESPONSE_OK:
+			number = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (dialog->priv->jump));
+			tab = gtranslator_window_get_active_tab (dialog->priv->window);
+			gtranslator_tab_go_to_number (tab, number - 1);
+			gtk_widget_destroy (GTK_WIDGET (dlg));
+			break;
+	
+		default:
+			gtk_widget_destroy (GTK_WIDGET (dlg));
+	}
+}
+
+static void
+gtranslator_jump_dialog_init (GtranslatorJumpDialog *dlg)
+{
+	gboolean ret;
+	GtkWidget *error_widget;
+	
+	dlg->priv = GTR_JUMP_DIALOG_GET_PRIVATE (dlg);
+	
+	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
+				GTK_STOCK_OK,
+				GTK_RESPONSE_OK,
+				GTK_STOCK_CANCEL,
+				GTK_RESPONSE_CANCEL,
+				NULL);
+	
+	gtk_window_set_title (GTK_WINDOW (dlg), _("Jump To"));
+	gtk_window_set_default_size(GTK_WINDOW(dlg), 300, 100);
+	gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
+	
+	/* HIG defaults */
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 2); /* 2 * 5 + 2 = 12 */
+	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 4);
+	
+	gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
+	
+	g_signal_connect (dlg,
+			  "response",
+			  G_CALLBACK (dialog_response_handler),
+			  NULL);
+	
+	/*Glade*/
+	ret = gtranslator_utils_get_glade_widgets(PKGDATADIR "/jump-dialog.glade",
+		"main_box",
+		&error_widget,
+		
+		"main_box", &dlg->priv->main_box,
+		"jump", &dlg->priv->jump,
+		
+		NULL);
+	
+	if(!ret)
+	{
+		gtk_widget_show(error_widget);
+		gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+					     error_widget);
+		
+		return;
+	}
+	
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+			    dlg->priv->main_box, TRUE, TRUE, 0);
+	
+	gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->main_box), 5);
+	
+	
+}
+
+static void
+gtranslator_jump_dialog_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_jump_dialog_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_jump_dialog_class_init (GtranslatorJumpDialogClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorJumpDialogPrivate));
+
+	object_class->finalize = gtranslator_jump_dialog_finalize;
+}
+
+void
+gtranslator_show_jump_dialog (GtranslatorWindow *window)
+{
+	static GtranslatorJumpDialog *dlg = NULL;
+	
+	g_return_if_fail (GTR_IS_WINDOW (window));
+	
+	if(dlg == NULL)
+	{
+		GtranslatorTab *tab;
+		GtranslatorPo *po;
+		gint messages;
+		
+		dlg = g_object_new (GTR_TYPE_JUMP_DIALOG, NULL);
+
+		g_signal_connect (dlg,
+				  "destroy",
+				  G_CALLBACK (gtk_widget_destroyed),
+				  &dlg);
+		
+		dlg->priv->window = window;
+		
+		/* Set the maximum number of the spin button */
+		tab = gtranslator_window_get_active_tab (window);
+		po = gtranslator_tab_get_po (tab);
+		messages = gtranslator_po_get_messages_count (po);
+		gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->jump),
+					   1.0,
+					   (gdouble)messages);
+
+		gtk_widget_show (GTK_WIDGET(dlg));
+	}
+	
+	if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (dlg)))
+	{
+		gtk_window_set_transient_for (GTK_WINDOW (dlg),
+					      GTK_WINDOW (window));
+	}
+
+	gtk_window_present (GTK_WINDOW (dlg));
+}

Added: trunk/src/dialogs/jump-dialog.glade
==============================================================================
--- (empty file)
+++ trunk/src/dialogs/jump-dialog.glade	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Tue Sep  2 11:07:43 2008 -->
+<glade-interface>
+  <widget class="GtkDialog" id="dialog1">
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="main_box">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Enter message number:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkSpinButton" id="jump">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="activates_default">True</property>
+                <property name="adjustment">0 0 100 1 10 10</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

Added: trunk/src/dialogs/jump-dialog.h
==============================================================================
--- (empty file)
+++ trunk/src/dialogs/jump-dialog.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __JUMP_DIALOG_H__
+#define __JUMP_DIALOG_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "window.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_JUMP_DIALOG		(gtranslator_jump_dialog_get_type ())
+#define GTR_JUMP_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_JUMP_DIALOG, GtranslatorJumpDialog))
+#define GTR_JUMP_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_JUMP_DIALOG, GtranslatorJumpDialogClass))
+#define GTR_IS_JUMP_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_JUMP_DIALOG))
+#define GTR_IS_JUMP_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_JUMP_DIALOG))
+#define GTR_JUMP_DIALOG_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_JUMP_DIALOG, GtranslatorJumpDialogClass))
+
+/* Private structure type */
+typedef struct _GtranslatorJumpDialogPrivate	GtranslatorJumpDialogPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorJumpDialog		GtranslatorJumpDialog;
+
+struct _GtranslatorJumpDialog
+{
+	GtkDialog parent_instance;
+	
+	/*< private > */
+	GtranslatorJumpDialogPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorJumpDialogClass	GtranslatorJumpDialogClass;
+
+struct _GtranslatorJumpDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_jump_dialog_get_type               (void) G_GNUC_CONST;
+
+GType		 gtranslator_jump_dialog_register_type          (GTypeModule * module);
+
+void	         gtranslator_show_jump_dialog                   (GtranslatorWindow *window);
+
+G_END_DECLS
+
+#endif /* __JUMP_DIALOG_H__ */

Modified: trunk/src/dialogs/preferences-dialog.c
==============================================================================
--- trunk/src/dialogs/preferences-dialog.c	(original)
+++ trunk/src/dialogs/preferences-dialog.c	Tue Sep 16 07:58:13 2008
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *               2008  Pablo Sanxiao <psanxiao gmail com>
  * 
  *     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
@@ -20,16 +21,24 @@
 #include <config.h>
 #endif
 
+#include "application.h"
 #include "preferences-dialog.h"
 #include "prefs-manager.h"
+#include "profile.h"
 #include "utils.h"
 #include "plugin-manager.h"
+#include "profile-dialog.h"
+#include "po.h"
+#include "utils.h"
+#include "../translation-memory/translation-memory.h"
 
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib-object.h>
+#include <gio/gio.h>
 #include <gtk/gtk.h>
-
+#include <string.h>
+#include <gtksourceview/gtksourcestyleschememanager.h>
 
 #define GTR_PREFERENCES_DIALOG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
 						 	(object),	\
@@ -51,9 +60,7 @@
 	GtkWidget *autosave_checkbutton;
 	GtkWidget *autosave_interval_spinbutton;
 	GtkWidget *autosave_hbox;
-	GtkWidget *append_suffix_checkbutton;
-	GtkWidget *autosave_suffix_entry;
-	GtkWidget *autosave_suffix_hbox;
+	GtkWidget *create_backup_checkbutton;
 	
 	/* Editor->Text display */
 	GtkWidget *highlight_checkbutton;
@@ -64,7 +71,6 @@
 	
 	/* Editor->Contents */
 	GtkWidget *unmark_fuzzy_checkbutton;
-	GtkWidget *keep_obsolete_checkbutton;
 	GtkWidget *spellcheck_checkbutton;
 
 	/*Profiles*/
@@ -72,7 +78,19 @@
 	GtkWidget *add_button;
 	GtkWidget *edit_button;
 	GtkWidget *delete_button;
-	
+
+        /*Translation Memory*/
+        GtkWidget *directory_entry;
+        GtkWidget *search_button;
+        GtkWidget *add_database_button;
+	GtkWidget *add_database_progressbar;
+
+        GtkWidget *use_lang_profile_in_tm;
+        GtkWidget *tm_lang_entry;
+        GtkWidget *show_tm_options_checkbutton;
+        GtkWidget *missing_words_spinbutton;
+        GtkWidget *sentence_length_spinbutton;
+
 	/*PO header->Personal information*/
 	GtkWidget *name_entry;
 	GtkWidget *email_entry;
@@ -88,11 +106,19 @@
 	
 	/*Inteface*/
 	GtkWidget *gdl_combobox;
+	GtkWidget *scheme_color_combobox;
 	
 	/*Plugins*/
 	GtkWidget *plugins_box;
 };
 
+static void setup_profile_pages (GtranslatorPreferencesDialog *dlg);
+
+GtkWidget *gtranslator_preferences_dialog_get_treeview (GtranslatorPreferencesDialog *dlg) 
+{
+  return dlg->priv->profile_treeview;
+}
+
 /***************Files pages****************/
 
 static void
@@ -141,22 +167,21 @@
 	
 	autosave = gtk_toggle_button_get_active(button);
 	
-	gtk_widget_set_sensitive(dlg->priv->autosave_hbox, autosave);
+	gtk_widget_set_sensitive(dlg->priv->autosave_interval_spinbutton, autosave);
 	gtranslator_prefs_manager_set_autosave(autosave);
 }
 
 static void
-append_suffix_checkbutton_toggled(GtkToggleButton *button,
-					 GtranslatorPreferencesDialog *dlg)
+create_backup_checkbutton_toggled (GtkToggleButton *button,
+				   GtranslatorPreferencesDialog *dlg)
 {
-	gboolean append_suffix;
+	gboolean create_backup;
 	
-	g_return_if_fail(button == GTK_TOGGLE_BUTTON(dlg->priv->append_suffix_checkbutton));
+	g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->create_backup_checkbutton));
 	
-	append_suffix = gtk_toggle_button_get_active(button);
+	create_backup = gtk_toggle_button_get_active (button);
 	
-	gtk_widget_set_sensitive(dlg->priv->autosave_suffix_hbox, append_suffix);
-	gtranslator_prefs_manager_set_append_suffix(append_suffix);
+	gtranslator_prefs_manager_set_create_backup (create_backup);
 }
 
 static void
@@ -169,31 +194,18 @@
 }
 
 static void
-autosave_suffix_entry_changed(GObject    *gobject,
-			      GParamSpec *arg1,
-			      GtranslatorPreferencesDialog *dlg)
-{
-	const gchar *text;
-	
-	text = gtk_entry_get_text(GTK_ENTRY(gobject));
-	
-	gtranslator_prefs_manager_set_autosave_suffix(text);
-}
-
-static void
 setup_files_autosave_page(GtranslatorPreferencesDialog *dlg)
 {
-	gboolean autosave, suffix;
+	gboolean autosave, backup;
 	gint autosave_interval;
-	const gchar *autosave_suffix;
 
 	/*Set initial value*/
 	autosave = gtranslator_prefs_manager_get_autosave();
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dlg->priv->autosave_checkbutton),
 				     autosave);
-	suffix = gtranslator_prefs_manager_get_append_suffix();
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dlg->priv->append_suffix_checkbutton),
-				     suffix);
+	backup = gtranslator_prefs_manager_get_create_backup ();
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->create_backup_checkbutton),
+				      backup);
 	
 	autosave_interval = gtranslator_prefs_manager_get_autosave_interval();
 	
@@ -203,32 +215,20 @@
 	gtk_spin_button_set_value(GTK_SPIN_BUTTON(dlg->priv->autosave_interval_spinbutton),
 				  autosave_interval);
 	
-	autosave_suffix = gtranslator_prefs_manager_get_autosave_suffix();
-	if(!autosave_suffix)
-		autosave_suffix = GPM_DEFAULT_AUTOSAVE_SUFFIX;
-	gtk_entry_set_text(GTK_ENTRY(dlg->priv->autosave_suffix_entry),
-			   autosave_suffix);
-	
-	
 	/*Set sensitive*/
-	gtk_widget_set_sensitive(dlg->priv->autosave_hbox,
+	gtk_widget_set_sensitive(dlg->priv->autosave_interval_spinbutton,
 				 autosave);
-	gtk_widget_set_sensitive(dlg->priv->autosave_suffix_hbox,
-				 suffix);
 	
 	/*Connect signals*/
 	g_signal_connect(dlg->priv->autosave_checkbutton, "toggled",
 			 G_CALLBACK(autosave_checkbutton_toggled),
 			 dlg);
-	g_signal_connect(dlg->priv->append_suffix_checkbutton, "toggled",
-			 G_CALLBACK(append_suffix_checkbutton_toggled),
+	g_signal_connect(dlg->priv->create_backup_checkbutton, "toggled",
+			 G_CALLBACK(create_backup_checkbutton_toggled),
 			 dlg);
 	g_signal_connect(dlg->priv->autosave_interval_spinbutton, "value-changed",
 			 G_CALLBACK(autosave_interval_spinbutton_value_changed),
 			 dlg);
-	g_signal_connect(dlg->priv->autosave_suffix_entry, "notify::text",
-			 G_CALLBACK(autosave_suffix_entry_changed),
-			 dlg);
 }
 
 static void
@@ -342,15 +342,6 @@
 }
 
 static void
-keep_obsolete_checkbutton_toggled(GtkToggleButton *button,
-				  GtranslatorPreferencesDialog *dlg)
-{
-	g_return_if_fail(button == GTK_TOGGLE_BUTTON(dlg->priv->keep_obsolete_checkbutton));
-
-	gtranslator_prefs_manager_set_keep_obsolete(gtk_toggle_button_get_active(button));
-}
-
-static void
 spellcheck_checkbutton_toggled(GtkToggleButton *button,
 					   GtranslatorPreferencesDialog *dlg)
 {
@@ -365,8 +356,6 @@
 	/*Set initial values*/
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dlg->priv->unmark_fuzzy_checkbutton),
 				     gtranslator_prefs_manager_get_unmark_fuzzy());
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dlg->priv->keep_obsolete_checkbutton),
-				     gtranslator_prefs_manager_get_keep_obsolete());
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dlg->priv->spellcheck_checkbutton),
 				     gtranslator_prefs_manager_get_spellcheck());
 	
@@ -374,9 +363,6 @@
 	g_signal_connect(dlg->priv->unmark_fuzzy_checkbutton, "toggled",
 			 G_CALLBACK(unmark_fuzzy_checkbutton_toggled),
 			 dlg);
-	g_signal_connect(dlg->priv->keep_obsolete_checkbutton, "toggled",
-			 G_CALLBACK(keep_obsolete_checkbutton_toggled),
-			 dlg);
 	g_signal_connect(dlg->priv->spellcheck_checkbutton, "toggled",
 			 G_CALLBACK(spellcheck_checkbutton_toggled),
 			 dlg);
@@ -390,112 +376,550 @@
 	setup_editor_contents(dlg);
 }
 
-/***************PO header pages****************/
+/***************Profile pages****************/
 static void
-name_entry_changed(GObject    *gobject,
-		   GParamSpec *arg1,
+active_toggled_cb (GtkCellRendererToggle *cell_renderer,
+		   gchar *path_str,
 		   GtranslatorPreferencesDialog *dlg)
 {
-	const gchar *text;
-	
-	g_return_if_fail(GTK_ENTRY(gobject) == GTK_ENTRY(dlg->priv->name_entry));
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  GtkTreeModel *model;
+  gboolean active;
+  gchar *profile_row;
+  GtranslatorProfile *old_profile_active;
+  GList *l = NULL, *profiles_list = NULL;
+  gchar *filename;
+  gchar *config_folder;
+  GFile *file;
+
+
+  config_folder = gtranslator_utils_get_user_config_dir ();
+  filename = g_build_filename (config_folder,
+			       "profiles.xml",
+			       NULL);
+  file = g_file_new_for_path (filename);
+
+  path = gtk_tree_path_new_from_string (path_str);
+  
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (dlg->priv->profile_treeview));
+  g_return_if_fail (model != NULL);
+  
+  gtk_tree_model_get_iter (model, &iter, path);
+
+  gtk_tree_model_get (model, &iter, TOGGLE_COL, &active, -1);
+    
+  if (!active) {
+    
+    old_profile_active = gtranslator_application_get_active_profile (GTR_APP);
+    
+    gtk_list_store_set (GTK_LIST_STORE (model),
+			&iter,
+			TRUE,
+			TOGGLE_COL,
+			-1);
+
+    gtk_tree_model_get (model, &iter, PROFILE_NAME_COL, &profile_row, -1);
+    profiles_list = gtranslator_application_get_profiles (GTR_APP);
+
+    for (l = profiles_list; l; l = l->next) {
+      GtranslatorProfile *profile;
+      profile = (GtranslatorProfile *)l->data;
+      if (!strcmp (gtranslator_profile_get_name (profile), profile_row)) {
+	gtranslator_application_set_active_profile (GTR_APP, profile);
+      }
+    }
+  }
+  gtk_list_store_clear (GTK_LIST_STORE(model));
+  gtranslator_preferences_fill_profile_treeview (dlg, model);
+  gtk_tree_path_free (path);
+}
+
+void gtranslator_preferences_fill_profile_treeview (GtranslatorPreferencesDialog *dlg,
+						    GtkTreeModel *model)
+{
+  GtkTreeIter iter;
+  GtranslatorProfile *active_profile;
+  GList *l = NULL, *profiles_list = NULL;
+
+  gtk_list_store_clear (GTK_LIST_STORE (model));
+  
+  profiles_list = gtranslator_application_get_profiles (GTR_APP);
+
+  
+  active_profile = gtranslator_application_get_active_profile (GTR_APP);
+  
+  for (l = profiles_list; l; l = l->next) {
+    
+    GtranslatorProfile *profile;
+    gchar *profile_name;
+    
+    profile = (GtranslatorProfile *)l->data;
+
+    profile_name = gtranslator_profile_get_name (profile);
+    gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+   
+    if (!strcmp (gtranslator_profile_get_name (active_profile), profile_name)) {
+      gtk_list_store_set (GTK_LIST_STORE (model),
+			  &iter,
+			  PROFILE_NAME_COL,
+			  profile_name,
+			  TOGGLE_COL,
+			  TRUE,
+			  -1);
+    } else {
+      gtk_list_store_set (GTK_LIST_STORE (model),
+			  &iter,
+			  PROFILE_NAME_COL,
+			  profile_name,
+			  -1);
+    }
+  }
+}
+
+static void
+setup_profile_pages (GtranslatorPreferencesDialog *dlg)
+{
+  
+  GtkTreeViewColumn *name_column, *toggle_column;
+  GtkCellRenderer *text_renderer, *toggle_renderer;
+  GtkListStore *model;
+  
+  model = gtk_list_store_new (N_COLUMNS_PROFILES, G_TYPE_STRING, G_TYPE_BOOLEAN);
+
+  gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->profile_treeview),
+			   GTK_TREE_MODEL (model)); 
+
+  g_object_unref (model);
+  
+  text_renderer = gtk_cell_renderer_text_new ();
+  toggle_renderer = gtk_cell_renderer_toggle_new ();
+
+  g_signal_connect (toggle_renderer,
+		    "toggled",
+		    G_CALLBACK (active_toggled_cb),
+		    dlg);
+
+  g_object_set (toggle_renderer,
+		"mode",
+		GTK_CELL_RENDERER_MODE_ACTIVATABLE,
+		NULL);
 
-	text = gtk_entry_get_text(GTK_ENTRY(gobject));
+  name_column = gtk_tree_view_column_new_with_attributes ("Profile",
+						     text_renderer,
+						     "text",
+						     PROFILE_NAME_COL,
+						     NULL);
+  
+  toggle_column = gtk_tree_view_column_new_with_attributes ("Active",
+							    toggle_renderer,
+							    "active",
+							    TOGGLE_COL,
+							    NULL);
+
+  gtk_tree_view_column_set_resizable (toggle_column, TRUE);
+  gtk_tree_view_column_set_resizable (name_column, TRUE);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->profile_treeview), name_column);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->profile_treeview), toggle_column);
+
+  g_object_set (name_column, 
+		"expand", 
+		TRUE,
+		NULL);
 	
-	if(text)
-		gtranslator_prefs_manager_set_name(text);
+  gtranslator_preferences_fill_profile_treeview (dlg,GTK_TREE_MODEL(model));
 }
 
+/***************Interface pages****************/
 static void
-email_entry_changed(GObject    *gobject,
-		    GParamSpec *arg1,
-		    GtranslatorPreferencesDialog *dlg)
+style_changed_cb (GtkComboBox *combobox,
+		  GtranslatorPreferencesDialog *dlg)
 {
-	const gchar *text;
+	g_return_if_fail(combobox == GTK_COMBO_BOX(dlg->priv->gdl_combobox));
 	
-	g_return_if_fail(GTK_ENTRY(gobject) == GTK_ENTRY(dlg->priv->email_entry));
+	gtranslator_prefs_manager_set_gdl_style (gtk_combo_box_get_active (combobox));
+}
 
-	text = gtk_entry_get_text(GTK_ENTRY(gobject));
+static void
+scheme_color_changed_cb (GtkComboBox *combobox,
+			 GtranslatorPreferencesDialog *dlg)
+{
+	g_return_if_fail (combobox == GTK_COMBO_BOX (dlg->priv->scheme_color_combobox));
 	
-	if(text)
-		gtranslator_prefs_manager_set_email(text);
+	gtranslator_prefs_manager_set_scheme_color (gtk_combo_box_get_active_text (combobox));
 }
 
 static void
-setup_po_header_personal_information_page(GtranslatorPreferencesDialog *dlg)
+setup_interface_pages(GtranslatorPreferencesDialog *dlg)
 {
-	const gchar *value;
+	gint gdl_style;
+	GtkSourceStyleSchemeManager *manager;
+	const gchar * const *scheme_ids;
+	const gchar * scheme_active;
+	gint i = 0;
 	
 	/*Set initial value*/
-	value = gtranslator_prefs_manager_get_name();
-	if(value)
-		gtk_entry_set_text(GTK_ENTRY(dlg->priv->name_entry),
-				   value);
-	value = gtranslator_prefs_manager_get_email();
-	if(value)
-		gtk_entry_set_text(GTK_ENTRY(dlg->priv->email_entry),
-				   value);
+	gdl_style = gtranslator_prefs_manager_get_gdl_style ();
+	if (gdl_style)
+		gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->priv->gdl_combobox),
+					  gdl_style);
 	
+	/*
+	 * Scheme color
+	 */
+	manager = gtk_source_style_scheme_manager_get_default ();
+	scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
+	scheme_active = gtranslator_prefs_manager_get_scheme_color ();
+	while (scheme_ids [i] != NULL)
+	{
+		gtk_combo_box_append_text (GTK_COMBO_BOX (dlg->priv->scheme_color_combobox),
+					   scheme_ids[i]);
+		if (strcmp (scheme_ids[i], scheme_active) == 0)
+			gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->priv->scheme_color_combobox),
+						  i);
+		i++;
+	}
+		
 	/*Connect signals*/
-	g_signal_connect(dlg->priv->name_entry, "notify::text",
-			 G_CALLBACK(name_entry_changed),
-			 dlg);
-	g_signal_connect(dlg->priv->email_entry, "notify::text",
-			 G_CALLBACK(email_entry_changed),
-			 dlg);
+	g_signal_connect (dlg->priv->gdl_combobox, "changed",
+			  G_CALLBACK (style_changed_cb),
+			  dlg);
+	g_signal_connect (dlg->priv->scheme_color_combobox, "changed",
+			  G_CALLBACK (scheme_color_changed_cb),
+			  dlg);
 }
 
+/***************Translation Memory pages****************/
 static void
-setup_po_header_language_settings_page(GtranslatorPreferencesDialog *dlg)
+response_filechooser_cb (GtkDialog *dialog,
+			 gint       response_id,
+			 gpointer   user_data)  
 {
+  GtranslatorPreferencesDialog *dlg;
+
+  dlg = (GtranslatorPreferencesDialog *)user_data;
+  
+
+  if (response_id == GTK_RESPONSE_YES) {
+    gtk_entry_set_text (GTK_ENTRY (dlg->priv->directory_entry),
+			gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)));
+    gtranslator_prefs_manager_set_tm_dir (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)));
+    gtk_widget_destroy (GTK_WIDGET (dialog));
+  } else {
+    gtk_widget_destroy (GTK_WIDGET (dialog));
+  }
 }
 
 static void
-setup_po_header_pages(GtranslatorPreferencesDialog *dlg)
+on_search_button_pulsed (GtkButton *button,
+			 gpointer data)
 {
-	/*Children*/
-	setup_po_header_personal_information_page(dlg);
-	setup_po_header_language_settings_page(dlg);
+  GtkWidget *filechooser;
+  GtranslatorPreferencesDialog *dlg;
+
+  dlg = (GtranslatorPreferencesDialog *)data;
+  
+  filechooser = gtk_file_chooser_dialog_new ("Select PO directory",
+					     GTK_WINDOW (dlg),
+					     GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+					     GTK_STOCK_CANCEL,
+					     GTK_RESPONSE_CANCEL,
+					     GTK_STOCK_OK,
+					     GTK_RESPONSE_YES,
+					     NULL);
+ 
+  g_signal_connect (GTK_DIALOG (filechooser), "response",
+		    G_CALLBACK (response_filechooser_cb),
+		    dlg);
+
+  gtk_dialog_run (GTK_DIALOG (filechooser));
 }
 
+typedef struct _IdleData
+{
+	GSList *list;
+	GtkProgressBar *progress;
+	GtranslatorTranslationMemory *tm;
+	GtkWindow *parent;
+}IdleData;
+
+static gboolean
+add_to_database (gpointer data_pointer)
+{
+	IdleData *data = (IdleData *)data_pointer;
+	static GSList *l = NULL;
+	gdouble percentage;
+	
+	if (l == NULL)
+		l = data->list;
+	else
+		l = g_slist_next (l);
+
+	if (l)
+	{
+		GList *msg_list = NULL;
+		GList *l2 = NULL;
+		GFile *location;
+		GError *error = NULL;
+		GtranslatorPo *po;
+		
+		po = gtranslator_po_new ();
+		location = (GFile *)l->data;
+		
+		gtranslator_po_parse (po, location, &error);
+		if (error)
+			return TRUE;
+		
+		msg_list = gtranslator_po_get_messages (po);
+		
+		for (l2 = msg_list; l2; l2 = l2->next) {
+			GtranslatorMsg *msg;
+			msg = GTR_MSG (l2->data);
+			if (gtranslator_msg_is_translated (msg))
+				gtranslator_translation_memory_store (data->tm,
+								      gtranslator_msg_get_msgid (msg),
+								      gtranslator_msg_get_msgstr (msg));
+		}
+		
+		g_object_unref (po);
+	}
+	else
+	{
+		GtkWidget *dialog;
+		
+		gtk_progress_bar_set_fraction (data->progress,
+					       1.0);
+		
+		dialog = gtk_message_dialog_new (data->parent,
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_INFO,
+						 GTK_BUTTONS_CLOSE,
+						 NULL);
+		
+		gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
+					       _("<span weight=\"bold\" size=\"large\">Strings added to database</span>"));
+		
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+		
+		return FALSE;
+	}
+	
+	percentage = (gdouble)g_slist_position (data->list, l) / (gdouble) g_slist_length (data->list);
+
+	/*
+	 * Set the progress only if the values are reasonable.
+	 */
+	if(percentage > 0.0 || percentage < 1.0)
+	{
+		/*
+		 * Set the progressbar status.
+		 */
+		gtk_progress_bar_set_fraction (data->progress,
+					       percentage);
+	}
+	
+	return TRUE;
+}
 
-/***************Interface pages****************/
 static void
-style_changed_cb (GtkComboBox *combobox,
-		  GtranslatorPreferencesDialog *dlg)
+destroy_idle_data (gpointer data)
 {
-	g_return_if_fail(combobox == GTK_COMBO_BOX(dlg->priv->gdl_combobox));
+	IdleData *d = (IdleData *)data;
 	
-	gtranslator_prefs_manager_set_gdl_style (gtk_combo_box_get_active (combobox));
+	gtk_widget_hide (GTK_WIDGET (d->progress));
+	g_slist_foreach (d->list, (GFunc)g_object_unref, NULL);
+	g_slist_free (d->list);
+	
+	g_free (d);
 }
 
 static void
-setup_interface_pages(GtranslatorPreferencesDialog *dlg)
+on_add_database_button_pulsed (GtkButton *button,
+			       GtranslatorPreferencesDialog *dlg)
 {
-	gint gdl_style;
+  GFile *dir;
+  const gchar *dir_name;
+  IdleData *data;
 	
-	/*Set initial value*/
-	gdl_style = gtranslator_prefs_manager_get_gdl_style ();
-	if (gdl_style)
-		gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->priv->gdl_combobox),
-					  gdl_style);
-		
-	/*Connect signals*/
-	g_signal_connect(dlg->priv->gdl_combobox, "changed",
-			 G_CALLBACK (style_changed_cb),
+  data = g_new0 (IdleData, 1);
+  data->list = NULL;
+
+  dir_name = gtranslator_prefs_manager_get_tm_dir ();
+
+  dir = g_file_new_for_path (dir_name);
+
+  if (gtranslator_prefs_manager_get_use_lang_profile ())
+    gtranslator_utils_scan_dir (dir, &data->list, gtranslator_prefs_manager_get_tm_lang_entry());
+  else
+    gtranslator_utils_scan_dir (dir, &data->list, NULL);
+  
+  data->tm = GTR_TRANSLATION_MEMORY (gtranslator_application_get_translation_memory (GTR_APP));
+  data->progress = GTK_PROGRESS_BAR (dlg->priv->add_database_progressbar);
+  data->parent = GTK_WINDOW (dlg);
+
+  gtk_widget_show (dlg->priv->add_database_progressbar);
+  g_idle_add_full (G_PRIORITY_HIGH_IDLE + 30,
+		   (GSourceFunc)add_to_database,
+		   data,
+		   (GDestroyNotify)destroy_idle_data);
+  
+  g_object_unref (dir); 
+}
+
+static void
+on_use_lang_profile_checkbutton_changed (GtkToggleButton *button,
+					 gpointer user_data)
+{ 
+  gtranslator_prefs_manager_set_use_lang_profile (gtk_toggle_button_get_active(button));
+}
+
+
+static void
+on_show_tm_options_checkbutton_changed (GtkToggleButton *button,
+					gpointer user_data)
+{ 
+  gtranslator_prefs_manager_set_show_tm_options (gtk_toggle_button_get_active(button));
+}
+
+static void
+tm_lang_entry_changed (GObject    *gobject,
+		       GParamSpec *arg1,
+		       GtranslatorPreferencesDialog *dlg)
+{
+	const gchar *text;
+	
+	g_return_if_fail(GTK_ENTRY(gobject) == GTK_ENTRY(dlg->priv->tm_lang_entry));
+
+	text = gtk_entry_get_text(GTK_ENTRY(gobject));
+	
+	if(text)
+	  gtranslator_prefs_manager_set_tm_lang_entry (text);
+}
+
+
+static void
+on_missing_words_spinbutton_changed (GtkSpinButton *spinbutton,
+				      gpointer data)
+{
+  gint value;
+
+  value = gtk_spin_button_get_value_as_int (spinbutton);
+
+  gtranslator_prefs_manager_set_missing_words (value);
+}
+
+static void
+on_sentence_length_spinbutton_changed (GtkSpinButton *spinbutton,
+				      gpointer data)
+{
+  gint value;
+
+  value = gtk_spin_button_get_value_as_int (spinbutton);
+
+  gtranslator_prefs_manager_set_sentence_length (value);
+}
+
+static void
+directory_entry_changed(GObject    *gobject,
+			GParamSpec *arg1,
+			GtranslatorPreferencesDialog *dlg)
+{
+	const gchar *text;
+	
+	g_return_if_fail(GTK_ENTRY(gobject) == GTK_ENTRY(dlg->priv->directory_entry));
+
+	text = gtk_entry_get_text(GTK_ENTRY(gobject));
+	
+	if(text)
+	  gtranslator_prefs_manager_set_tm_dir (text);
+}
+
+
+static void
+setup_tm_pages(GtranslatorPreferencesDialog *dlg)
+{
+  GtranslatorProfile *profile;
+  gchar *language_code;
+  const gchar *filename = NULL;
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->show_tm_options_checkbutton),
+				gtranslator_prefs_manager_get_show_tm_options ());
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->use_lang_profile_in_tm),
+				gtranslator_prefs_manager_get_use_lang_profile ());
+  
+  profile = gtranslator_application_get_active_profile (GTR_APP);
+  
+  if (profile != NULL) {
+    language_code = gtranslator_profile_get_language_code (profile);
+    filename = (const gchar*)g_strconcat (language_code, ".po", NULL);
+    
+    gtk_entry_set_text (GTK_ENTRY (dlg->priv->tm_lang_entry),
+			filename);
+  }
+  
+  if (filename != NULL)
+    gtranslator_prefs_manager_set_tm_lang_entry (filename);
+  
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (dlg->priv->missing_words_spinbutton),
+			     (gdouble) gtranslator_prefs_manager_get_missing_words ());
+  
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (dlg->priv->sentence_length_spinbutton),
+			     (gdouble) gtranslator_prefs_manager_get_sentence_length ());
+  
+  g_signal_connect (GTK_BUTTON (dlg->priv->search_button), "clicked",
+		    G_CALLBACK (on_search_button_pulsed),
+		    dlg);
+
+  g_signal_connect(dlg->priv->directory_entry, "notify::text",
+			 G_CALLBACK(directory_entry_changed),
+			 dlg);
+  
+  g_signal_connect(dlg->priv->tm_lang_entry, "notify::text",
+			 G_CALLBACK(tm_lang_entry_changed),
 			 dlg);
+  
+  g_signal_connect (GTK_BUTTON (dlg->priv->add_database_button), "clicked",
+		    G_CALLBACK (on_add_database_button_pulsed),
+		    dlg);
+
+  g_signal_connect (GTK_TOGGLE_BUTTON (dlg->priv->show_tm_options_checkbutton), "toggled",
+		    G_CALLBACK (on_show_tm_options_checkbutton_changed),
+		    dlg);
+
+  g_signal_connect (GTK_TOGGLE_BUTTON (dlg->priv->use_lang_profile_in_tm), "toggled",
+		    G_CALLBACK (on_use_lang_profile_checkbutton_changed),
+		    dlg);
+
+  g_signal_connect (GTK_SPIN_BUTTON (dlg->priv->missing_words_spinbutton), "value-changed",
+		    G_CALLBACK (on_missing_words_spinbutton_changed),
+		    dlg);
+  
+  g_signal_connect (GTK_SPIN_BUTTON (dlg->priv->sentence_length_spinbutton), "value-changed",
+		    G_CALLBACK (on_sentence_length_spinbutton_changed),
+		    dlg);
+
+  g_free ((gpointer)filename);
 }
 
+/***************Plugins pages****************/
 static void
 setup_plugin_pages(GtranslatorPreferencesDialog *dlg)
 {
+        GtkWidget *alignment;
 	GtkWidget *page_content;
 
+	alignment = gtk_alignment_new (0., 0., 1., 1.);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12);
+	
 	page_content = gtranslator_plugin_manager_new ();
 	g_return_if_fail (page_content != NULL);
 
+	gtk_container_add (GTK_CONTAINER (alignment), page_content);
+
 	gtk_box_pack_start (GTK_BOX (dlg->priv->plugins_box),
-			    page_content,
+			    alignment,
 			    TRUE,
 			    TRUE,
 			    0);
@@ -516,9 +940,153 @@
 }
 
 static void
-add_button_pulsed (GtkWidget *button, GtranslatorPreferencesDialog *dlg)
+add_button_pulsed (GtkWidget *button,
+		   GtranslatorPreferencesDialog *dlg)
 {
-	gtranslator_show_profile_dialog(dlg);
+  GtranslatorProfile *profile;
+  profile = gtranslator_profile_new ();
+  gtranslator_show_profile_dialog(dlg, profile, NEW_PROFILE);
+}
+
+static void
+edit_button_pulsed (GtkWidget *button,
+		    GtranslatorPreferencesDialog *dlg)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeSelection *selection;
+  gchar *profile_row, *old_profile_name;
+  GtranslatorProfile *edited_profile;
+  GtranslatorProfile *active_profile;
+  GList *profiles_list = NULL, *l = NULL;
+  
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (dlg->priv->profile_treeview));
+  g_return_if_fail (model != NULL);
+  
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->profile_treeview));
+  
+  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+    
+    gtk_tree_model_get (model, &iter, PROFILE_NAME_COL, &profile_row, -1);
+    
+    profiles_list = gtranslator_application_get_profiles (GTR_APP);
+    active_profile = gtranslator_application_get_active_profile (GTR_APP);
+    
+    for (l = profiles_list; l; l = l->next) {
+      GtranslatorProfile *profile;
+      profile = (GtranslatorProfile *)l->data;
+      if (!strcmp (gtranslator_profile_get_name (profile), profile_row)) {
+	old_profile_name = gtranslator_profile_get_name (profile);
+	edited_profile = profile;
+      }
+    }
+    gtranslator_show_profile_dialog (dlg, edited_profile, EDIT_PROFILE);
+  }
+}
+
+static void
+delete_confirm_dialog_cb (GtkWidget *dialog,
+			  gint response_id,
+			  GtranslatorPreferencesDialog *dlg)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeSelection *selection;
+  gchar *profile_row;
+  GList *profiles_list = NULL, *l = NULL;
+  GList *new_list = NULL;
+
+  if (response_id == GTK_RESPONSE_YES) {
+    model = gtk_tree_view_get_model (GTK_TREE_VIEW (dlg->priv->profile_treeview));
+    g_return_if_fail (model != NULL);
+    
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->profile_treeview));
+    
+    if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+      
+      gtk_tree_model_get (model, &iter, PROFILE_NAME_COL, &profile_row, -1);
+      
+      profiles_list = gtranslator_application_get_profiles (GTR_APP);
+      
+      for (l = profiles_list; l; l = l->next) {
+	GtranslatorProfile *profile;
+	profile = (GtranslatorProfile *)l->data;
+	if (!strcmp (gtranslator_profile_get_name (profile), profile_row)) {
+	  new_list = g_list_remove (profiles_list, profile);
+	  gtranslator_application_set_profiles (GTR_APP, new_list);
+	}
+      }
+      gtranslator_preferences_fill_profile_treeview (dlg, model);
+    }
+    gtk_widget_destroy (dialog);
+  } else {
+    gtk_widget_destroy (dialog);
+  }
+}
+
+static void
+delete_button_pulsed (GtkWidget *button,
+		      GtranslatorPreferencesDialog *dlg)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeSelection *selection;
+  gchar *profile_row;
+  GtranslatorProfile *active_profile;
+  GtkWidget *dialog;
+
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (dlg->priv->profile_treeview));
+  g_return_if_fail (model != NULL);
+    
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->profile_treeview));
+  
+  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+    
+    gtk_tree_model_get (model, &iter, PROFILE_NAME_COL, &profile_row, -1);
+    
+    active_profile = gtranslator_application_get_active_profile (GTR_APP);
+
+    if (!strcmp (gtranslator_profile_get_name (active_profile), profile_row)) {
+    
+      dialog = gtk_message_dialog_new (GTK_WINDOW (dlg),
+					     GTK_DIALOG_MODAL,
+					     GTK_MESSAGE_ERROR,
+					     GTK_BUTTONS_CLOSE,
+					     NULL);
+
+      gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
+				 _("<span weight=\"bold\" size=\"large\">Impossible to remove the active profile</span>"));
+      
+      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+						_("Another profile should be selected as active before"));
+      
+      gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_widget_destroy (dialog);
+    } else {
+      dialog = gtk_message_dialog_new (GTK_WINDOW (dlg),
+				       GTK_DIALOG_MODAL,
+				       GTK_MESSAGE_QUESTION,
+				       GTK_BUTTONS_NONE,
+				       NULL);
+      
+      gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
+				     _("<span weight=\"bold\" size=\"large\">Are you sure you want to delete this profile?</span>"));
+      
+      gtk_dialog_add_button (GTK_DIALOG (dialog),
+			     GTK_STOCK_CANCEL,
+			     GTK_RESPONSE_CANCEL);
+      
+      gtk_dialog_add_button (GTK_DIALOG (dialog),
+			     GTK_STOCK_DELETE,
+			     GTK_RESPONSE_YES);
+      
+      gtk_dialog_run (GTK_DIALOG (dialog));
+      
+      g_signal_connect (GTK_DIALOG (dialog), "response",
+			G_CALLBACK (delete_confirm_dialog_cb),
+			dlg);
+    }
+  } 
 }
 
 static void
@@ -554,7 +1122,7 @@
 	
 	/*Glade*/
 	
-	ret = gtranslator_utils_get_glade_widgets(DATADIR "/preferences-dialog.glade",
+	ret = gtranslator_utils_get_glade_widgets(PKGDATADIR "/preferences-dialog.glade",
 		"notebook",
 		&error_widget,
 		
@@ -566,9 +1134,7 @@
 		"autosave_checkbutton", &dlg->priv->autosave_checkbutton,
 		"autosave_interval_spinbutton", &dlg->priv->autosave_interval_spinbutton,
 		"autosave_hbox", &dlg->priv->autosave_hbox,
-		"append_suffix_checkbutton", &dlg->priv->append_suffix_checkbutton,
-		"autosave_suffix_entry", &dlg->priv->autosave_suffix_entry,
-		"autosave_suffix_hbox", &dlg->priv->autosave_suffix_hbox,
+		"create_backup_checkbutton", &dlg->priv->create_backup_checkbutton,
 
 		"highlight_checkbutton", &dlg->priv->highlight_checkbutton,
 		"visible_whitespace_checkbutton", &dlg->priv->visible_whitespace_checkbutton,
@@ -577,7 +1143,6 @@
 		"editor_font_hbox", &dlg->priv->editor_font_hbox,
 
 		"unmark_fuzzy_checkbutton", &dlg->priv->unmark_fuzzy_checkbutton,
-		"keep_obsolete_checkbutton", &dlg->priv->keep_obsolete_checkbutton,
 		"spellcheck_checkbutton", &dlg->priv->spellcheck_checkbutton,
 
 		"profile_treeview", &dlg->priv->profile_treeview,
@@ -585,18 +1150,19 @@
 		"edit_button", &dlg->priv->edit_button,
 		"delete_button", &dlg->priv->delete_button,
 
-		/*"name_entry", &dlg->priv->name_entry,
-		"email_entry", &dlg->priv->email_entry,
-
-		"language_comboentry", &dlg->priv->language_comboentry,
-		"langcode_comboentry", &dlg->priv->langcode_comboentry,
-		"charset_comboentry", &dlg->priv->charset_comboentry,
-		"encoding_comboentry", &dlg->priv->encoding_comboentry,
-		"team_email_comboentry", &dlg->priv->team_email_comboentry,
-		"number_plurals_spinbutton", &dlg->priv->number_plurals_spinbutton,
-		"plurals_entry", &dlg->priv->plurals_entry,
-		*/				  
+		"directory_entry", &dlg->priv->directory_entry,
+ 		"search_button", &dlg->priv->search_button,
+ 		"add_database_button", &dlg->priv->add_database_button,
+		"add_database_progressbar", &dlg->priv->add_database_progressbar,
+
+		"use_lang_profile_in_tm", &dlg->priv->use_lang_profile_in_tm,
+		"tm_lang_entry", &dlg->priv->tm_lang_entry,		  
+ 		"show_tm_options_checkbutton", &dlg->priv->show_tm_options_checkbutton,				  
+ 		"missing_words_spinbutton", &dlg->priv->missing_words_spinbutton,
+ 		"sentence_length_spinbutton", &dlg->priv->sentence_length_spinbutton,
+ 		
 		"gdl_combobox", &dlg->priv->gdl_combobox,
+		"scheme_color_combobox", &dlg->priv->scheme_color_combobox,
 		
 		"plugins_box", &dlg->priv->plugins_box,
 		NULL);
@@ -618,14 +1184,25 @@
 	gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->notebook), 5);
 	
 	g_signal_connect (dlg->priv->add_button,
-				"clicked",
-				G_CALLBACK (add_button_pulsed),
-				dlg);
+			  "clicked",
+			  G_CALLBACK (add_button_pulsed),
+			  dlg);
+
+	g_signal_connect (dlg->priv->delete_button,
+			  "clicked",
+			  G_CALLBACK (delete_button_pulsed),
+			  dlg);
+
+	g_signal_connect (dlg->priv->edit_button,
+			  "clicked",
+			  G_CALLBACK (edit_button_pulsed),
+			  dlg);
 
 	setup_files_pages(dlg);
 	setup_editor_pages(dlg);
-	setup_po_header_pages(dlg);
+	setup_profile_pages(dlg);
 	setup_interface_pages(dlg);
+	setup_tm_pages (dlg);
 	setup_plugin_pages(dlg);
 }
 
@@ -668,5 +1245,7 @@
 					      GTK_WINDOW (window));
 	}
 
+	gtranslator_application_set_preferences_dialog (GTR_APP, GTR_PREFERENCES_DIALOG(dlg));
+
 	gtk_window_present (GTK_WINDOW (dlg));
 }

Modified: trunk/src/dialogs/preferences-dialog.glade
==============================================================================
--- trunk/src/dialogs/preferences-dialog.glade	(original)
+++ trunk/src/dialogs/preferences-dialog.glade	Tue Sep 16 07:58:13 2008
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.1 on Sun Mar  9 23:45:30 2008 -->
+<!--Generated with glade3 3.4.5 on Mon Aug 11 10:18:25 2008 -->
 <glade-interface>
   <widget class="GtkDialog" id="preferences_dialog">
     <property name="border_width">5</property>
@@ -185,10 +185,10 @@
                               </widget>
                             </child>
                             <child>
-                              <widget class="GtkCheckButton" id="append_suffix_checkbutton">
+                              <widget class="GtkCheckButton" id="create_backup_checkbutton">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
-                                <property name="label" translatable="yes">Append a suffix to autosaved _files</property>
+                                <property name="label" translatable="yes">Create a _backup copy of files before saving</property>
                                 <property name="use_underline">True</property>
                                 <property name="response_id">0</property>
                                 <property name="draw_indicator">True</property>
@@ -199,39 +199,6 @@
                                 <property name="position">1</property>
                               </packing>
                             </child>
-                            <child>
-                              <widget class="GtkHBox" id="autosave_suffix_hbox">
-                                <property name="visible">True</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <widget class="GtkLabel" id="autosave_suffix_label">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">_Suffix to append:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">autosave_suffix_entry</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkEntry" id="autosave_suffix_entry">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="text" translatable="yes">autosave</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
                           </widget>
                           <packing>
                             <property name="position">1</property>
@@ -432,21 +399,6 @@
                               </widget>
                             </child>
                             <child>
-                              <widget class="GtkCheckButton" id="keep_obsolete_checkbutton">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="label" translatable="yes">_Keep obsolete messages</property>
-                                <property name="use_underline">True</property>
-                                <property name="response_id">0</property>
-                                <property name="draw_indicator">True</property>
-                              </widget>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                            <child>
                               <widget class="GtkCheckButton" id="spellcheck_checkbutton">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
@@ -456,7 +408,7 @@
                                 <property name="draw_indicator">True</property>
                               </widget>
                               <packing>
-                                <property name="position">2</property>
+                                <property name="position">1</property>
                               </packing>
                             </child>
                           </widget>
@@ -493,192 +445,496 @@
               </packing>
             </child>
             <child>
-              <widget class="GtkVBox" id="vbox8">
+              <widget class="GtkAlignment" id="alignment1">
                 <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="top_padding">12</property>
+                <property name="bottom_padding">12</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">12</property>
                 <child>
-                  <widget class="GtkHBox" id="hbox5">
+                  <widget class="GtkVBox" id="vbox8">
                     <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkLabel" id="label15">
+                      <widget class="GtkScrolledWindow" id="scrolledwindow1">
                         <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="can_focus">True</property>
+                        <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <child>
+                          <widget class="GtkViewport" id="viewport1">
+                            <property name="visible">True</property>
+                            <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+                            <child>
+                              <widget class="GtkTreeView" id="profile_treeview">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="headers_clickable">True</property>
+                              </widget>
+                            </child>
+                          </widget>
+                        </child>
                       </widget>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="padding">6</property>
-                      </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label13">
+                      <widget class="GtkHButtonBox" id="hbuttonbox1">
                         <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="xalign">0</property>
-                        <property name="ypad">4</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Name&lt;/b&gt;</property>
-                        <property name="use_markup">True</property>
+                        <property name="spacing">6</property>
+                        <property name="layout_style">GTK_BUTTONBOX_END</property>
+                        <child>
+                          <widget class="GtkButton" id="add_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="label" translatable="no">gtk-add</property>
+                            <property name="use_stock">True</property>
+                            <property name="response_id">0</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkButton" id="edit_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="label" translatable="no">gtk-edit</property>
+                            <property name="use_stock">True</property>
+                            <property name="response_id">0</property>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkButton" id="delete_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="label" translatable="no">gtk-delete</property>
+                            <property name="use_stock">True</property>
+                            <property name="response_id">0</property>
+                          </widget>
+                          <packing>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
                       </widget>
                       <packing>
+                        <property name="expand">False</property>
+                        <property name="pack_type">GTK_PACK_END</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label3">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Profiles</property>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">2</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox4">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="border_width">12</property>
+                <property name="spacing">18</property>
+                <child>
+                  <widget class="GtkVBox" id="vbox5">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkVSeparator" id="vseparator1">
+                      <widget class="GtkLabel" id="label10">
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Anchor style:&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
                       </widget>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="position">2</property>
-                      </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label14">
+                      <widget class="GtkHBox" id="hbox4">
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="xpad">12</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Active&lt;/b&gt;</property>
-                        <property name="use_markup">True</property>
-                        <property name="justify">GTK_JUSTIFY_RIGHT</property>
+                        <child>
+                          <widget class="GtkLabel" id="label11">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">    </property>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkComboBox" id="gdl_combobox">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="items" translatable="yes">Text
+Icons
+Text + Icons
+Gnome toolbar setting
+Tabs</property>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </widget>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="position">3</property>
+                        <property name="position">1</property>
                       </packing>
                     </child>
                   </widget>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">False</property>
                   </packing>
                 </child>
                 <child>
-                  <widget class="GtkTreeView" id="profile_treeview">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="headers_clickable">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkHBox" id="hbox6">
+                  <widget class="GtkVBox" id="vbox12">
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkButton" id="add_button">
+                      <widget class="GtkLabel" id="label13">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="label" translatable="yes">gtk-add</property>
-                        <property name="use_stock">True</property>
-                        <property name="response_id">0</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Scheme color:&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
                       </widget>
                     </child>
                     <child>
-                      <widget class="GtkButton" id="edit_button">
+                      <widget class="GtkHBox" id="hbox5">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="label" translatable="yes">gtk-edit</property>
-                        <property name="use_stock">True</property>
-                        <property name="response_id">0</property>
+                        <child>
+                          <widget class="GtkLabel" id="label14">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">    </property>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkComboBox" id="scheme_color_combobox">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="items" translatable="yes"></property>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </widget>
                       <packing>
                         <property name="position">1</property>
                       </packing>
                     </child>
-                    <child>
-                      <widget class="GtkButton" id="delete_button">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="label" translatable="yes">gtk-delete</property>
-                        <property name="use_stock">True</property>
-                        <property name="response_id">0</property>
-                      </widget>
-                      <packing>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
                   </widget>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="position">2</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
               </widget>
               <packing>
-                <property name="position">2</property>
+                <property name="position">3</property>
               </packing>
             </child>
             <child>
-              <widget class="GtkLabel" id="label3">
+              <widget class="GtkLabel" id="label7">
                 <property name="visible">True</property>
-                <property name="label" translatable="yes">Profiles</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">Interface</property>
               </widget>
               <packing>
                 <property name="type">tab</property>
-                <property name="position">2</property>
+                <property name="position">3</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
             <child>
-              <widget class="GtkVBox" id="vbox4">
+              <widget class="GtkVBox" id="memories_vbox">
                 <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                 <property name="border_width">12</property>
                 <property name="spacing">18</property>
                 <child>
-                  <widget class="GtkVBox" id="vbox5">
+                  <widget class="GtkVBox" id="vbox9">
                     <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkLabel" id="label10">
+                      <widget class="GtkLabel" id="label20">
                         <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                         <property name="xalign">0</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Anchor style:&lt;/b&gt;</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Database:&lt;/b&gt;</property>
                         <property name="use_markup">True</property>
                       </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
                     </child>
                     <child>
-                      <widget class="GtkHBox" id="hbox4">
+                      <widget class="GtkAlignment" id="alignment2">
                         <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="right_padding">12</property>
                         <child>
-                          <widget class="GtkLabel" id="label11">
+                          <widget class="GtkHBox" id="hbox8">
                             <property name="visible">True</property>
-                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="spacing">18</property>
+                            <child>
+                              <widget class="GtkLabel" id="label25">
+                                <property name="visible">True</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkVBox" id="vbox11">
+                                <property name="visible">True</property>
+                                <property name="spacing">6</property>
+                                <child>
+                                  <widget class="GtkLabel" id="label26">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Select directory contains PO files:</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkHBox" id="hbox9">
+                                    <property name="visible">True</property>
+                                    <property name="spacing">6</property>
+                                    <child>
+                                      <widget class="GtkEntry" id="directory_entry">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="xalign">0.0099999997764825821</property>
+                                      </widget>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkButton" id="search_button">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">True</property>
+                                        <property name="label" translatable="no">gtk-find</property>
+                                        <property name="use_stock">True</property>
+                                        <property name="response_id">0</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkButton" id="add_database_button">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <property name="label" translatable="yes">Add to Database</property>
+                                    <property name="response_id">0</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="position">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkProgressBar" id="add_database_progressbar">
+                                    <property name="no_show_all">True</property>
+                                    <property name="text" translatable="yes"></property>
+                                  </widget>
+                                  <packing>
+                                    <property name="position">3</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
                           </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                          </packing>
                         </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox10">
+                    <property name="visible">True</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <widget class="GtkLabel" id="label21">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Configuration:&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment3">
+                        <property name="visible">True</property>
+                        <property name="right_padding">12</property>
                         <child>
-                          <widget class="GtkComboBox" id="gdl_combobox">
+                          <widget class="GtkHBox" id="hbox7">
                             <property name="visible">True</property>
-                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                            <property name="items" translatable="yes">Text
-Icons
-Text + Icons
-Gnome toolbar setting
-Tabs</property>
+                            <property name="spacing">18</property>
+                            <child>
+                              <widget class="GtkLabel" id="label22">
+                                <property name="visible">True</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkTable" id="table1">
+                                <property name="visible">True</property>
+                                <property name="n_rows">4</property>
+                                <property name="n_columns">2</property>
+                                <property name="column_spacing">12</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <widget class="GtkEntry" id="tm_lang_entry">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="top_attach">1</property>
+                                    <property name="bottom_attach">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkCheckButton" id="use_lang_profile_in_tm">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="label" translatable="yes">Use only files with this name:</property>
+                                    <property name="response_id">0</property>
+                                    <property name="draw_indicator">True</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="top_attach">1</property>
+                                    <property name="bottom_attach">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkCheckButton" id="show_tm_options_checkbutton">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="label" translatable="yes">Show options in translated messages</property>
+                                    <property name="response_id">0</property>
+                                    <property name="draw_indicator">True</property>
+                                  </widget>
+                                </child>
+                                <child>
+                                  <widget class="GtkSpinButton" id="missing_words_spinbutton">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="adjustment">2 0 100 1 10 10</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="top_attach">2</property>
+                                    <property name="bottom_attach">3</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkLabel" id="label23">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Max. # of missing words:</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="top_attach">2</property>
+                                    <property name="bottom_attach">3</property>
+                                    <property name="x_options">GTK_FILL</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkSpinButton" id="sentence_length_spinbutton">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="adjustment">2 0 100 1 10 10</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="top_attach">3</property>
+                                    <property name="bottom_attach">4</property>
+                                    <property name="x_options">GTK_FILL</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkLabel" id="label24">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Max. difference in sentence length:</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="top_attach">3</property>
+                                    <property name="bottom_attach">4</property>
+                                    <property name="x_options">GTK_FILL</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
                           </widget>
-                          <packing>
-                            <property name="position">1</property>
-                          </packing>
                         </child>
                       </widget>
                       <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
@@ -686,22 +942,22 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
               </widget>
               <packing>
-                <property name="position">3</property>
+                <property name="position">4</property>
               </packing>
             </child>
             <child>
-              <widget class="GtkLabel" id="label7">
+              <widget class="GtkLabel" id="memory_page_label">
                 <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">Interface</property>
+                <property name="label" translatable="yes">Translation Memory</property>
               </widget>
               <packing>
                 <property name="type">tab</property>
-                <property name="position">3</property>
+                <property name="position">4</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
@@ -714,7 +970,7 @@
                 </child>
               </widget>
               <packing>
-                <property name="position">4</property>
+                <property name="position">5</property>
               </packing>
             </child>
             <child>
@@ -724,7 +980,7 @@
               </widget>
               <packing>
                 <property name="type">tab</property>
-                <property name="position">4</property>
+                <property name="position">5</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>

Modified: trunk/src/dialogs/preferences-dialog.h
==============================================================================
--- trunk/src/dialogs/preferences-dialog.h	(original)
+++ trunk/src/dialogs/preferences-dialog.h	Tue Sep 16 07:58:13 2008
@@ -19,11 +19,18 @@
 #ifndef __PREFERENCES_DIALOG_H__
 #define __PREFERENCES_DIALOG_H__
 
+#include "application.h"
 #include <glib.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
 #include "window.h"
 
+enum {
+    PROFILE_NAME_COL,
+    TOGGLE_COL,
+    N_COLUMNS_PROFILES
+  };
+
 G_BEGIN_DECLS
 
 /*
@@ -71,6 +78,11 @@
 
 void	         gtranslator_show_preferences_dialog                   (GtranslatorWindow *window);
 
+GtkWidget        *gtranslator_preferences_dialog_get_treeview          (GtranslatorPreferencesDialog *dlg);
+
+void             gtranslator_preferences_fill_profile_treeview         (GtranslatorPreferencesDialog *dlg,
+									GtkTreeModel *model);
+
 G_END_DECLS
 
 #endif /* __PREFERENCES_DIALOG_H__ */

Modified: trunk/src/dialogs/profile-dialog.c
==============================================================================
--- trunk/src/dialogs/profile-dialog.c	(original)
+++ trunk/src/dialogs/profile-dialog.c	Tue Sep 16 07:58:13 2008
@@ -20,14 +20,18 @@
 #include <config.h>
 #endif
 
+#include "application.h"
 #include "profile-dialog.h"
 #include "preferences-dialog.h"
+#include "profile.h"
 #include "utils.h"
 
+#include <string.h>
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
+#include <libxml/tree.h>
 
 
 #define GTR_PROFILE_DIALOG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
@@ -55,6 +59,11 @@
 	GtkWidget *plurals_forms_entry;
 };
 
+struct data {
+  GtranslatorProfile *old_profile;
+  GtranslatorProfile *new_profile;
+};
+
 static void gtranslator_profile_dialog_finalize (GObject *object)
 {
 	G_OBJECT_CLASS (gtranslator_profile_dialog_parent_class)->finalize (object);
@@ -69,25 +78,248 @@
 	object_class->finalize = gtranslator_profile_dialog_finalize;
 }
 
+/***************PROFILES****************/
+static void
+profile_name_entry_changed (GObject    *gobject,
+			    GParamSpec *arg1,
+			    GtranslatorProfile *profile)
+{
+	const gchar *text;
+	
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->profile_name_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_name (profile, (gchar *)text);
+}	
+
+static void
+author_name_entry_changed (GObject    *gobject,
+			   GParamSpec *arg1,
+			   GtranslatorProfile *profile)
+{
+	const gchar *text;
+	
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->author_name_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_author_name (profile, (gchar *)text);
+}		
+
+static void
+author_email_entry_changed (GObject    *gobject,
+			    GParamSpec *arg1,
+			    GtranslatorProfile *profile)
+{
+	const gchar *text;
+	
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->author_email_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_author_email (profile, (gchar *)text);
+}
+
+static void
+language_name_entry_changed (GObject    *gobject,
+			     GParamSpec *arg1,
+			     GtranslatorProfile *profile)
+{
+	const gchar *text;
+	
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->profile_name_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_language_name (profile, (gchar *)text);
+}
+
+static void
+language_code_entry_changed (GObject    *gobject,
+			     GParamSpec *arg1,
+			     GtranslatorProfile *profile)
+{
+	const gchar *text;
+	
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->profile_name_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_language_code (profile, (gchar *)text);
+}
+
+static void
+charset_entry_changed (GObject    *gobject,
+		       GParamSpec *arg1,
+		       GtranslatorProfile *profile)
+{
+	const gchar *text;
+
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->profile_name_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_charset (profile, (gchar *)text);
+}
+
+static void
+encoding_entry_changed (GObject    *gobject,
+			GParamSpec *arg1,
+			GtranslatorProfile *profile)
+{
+	const gchar *text;
+	
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->profile_name_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_encoding (profile, (gchar *)text);
+}
+
+static void
+group_email_entry_changed (GObject    *gobject,
+			   GParamSpec *arg1,
+			   GtranslatorProfile *profile)
+{
+	const gchar *text;
+	
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->profile_name_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_group_email (profile, (gchar *)text);
+}
+
+static void
+plurals_entry_changed (GObject    *gobject,
+		       GParamSpec *arg1,
+		       GtranslatorProfile *profile)
+{
+	const gchar *text;
+	
+	/*g_return_if_fail (GTK_ENTRY (gobject) == GTK_ENTRY (dlg->priv->profile_name_entry));*/
+
+	text = gtk_entry_get_text (GTK_ENTRY (gobject));
+	
+	if (text)
+	  gtranslator_profile_set_plurals (profile, (gchar *)text);
+}
+
+static void save_new_profile (GtkWidget *widget, GtranslatorProfile *profile)
+{
+  GList *profiles_list = NULL, *l = NULL;
+  GtranslatorPreferencesDialog *dlg;
+  gboolean profile_exists;
+  GtkWidget *treeview;
+  GtkTreeModel *model;
+  profile_exists = FALSE;
+  
+  profiles_list = gtranslator_application_get_profiles (GTR_APP);
+  
+  for (l = profiles_list; l; l = l->next) {
+    GtranslatorProfile *profile_in_list;
+    profile_in_list = (GtranslatorProfile *)l->data;
+    if (!strcmp (gtranslator_profile_get_name (profile_in_list),
+		 gtranslator_profile_get_name (profile)))
+      profile_exists = TRUE;
+  }
+      
+  if (profile_exists) {
+    GtkWidget *dialog;
+    dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_ancestor (widget, GTK_TYPE_DIALOG)),
+				     GTK_DIALOG_MODAL,
+				     GTK_MESSAGE_ERROR,
+				     GTK_BUTTONS_CLOSE,
+				     NULL);
+
+    gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
+				   _("<span weight=\"bold\" size=\"large\">The profile name already exists</span>"));
+
+    gtk_dialog_run (GTK_DIALOG (dialog));
+    gtk_widget_destroy (dialog);
+  } else { 
+    /*
+     * Add new profile to profiles list in memory
+     */
+    if (profiles_list == NULL) {
+      GList *initial_list = NULL;
+      initial_list = g_list_append (profiles_list, profile);
+      gtranslator_application_set_active_profile (GTR_APP, profile);
+      gtranslator_application_set_profiles (GTR_APP, initial_list); 
+    } else {
+      g_list_append (profiles_list, profile);
+    }   
+  }
+  
+  /*
+   *Reload the preferences dialog
+   */
+  dlg = gtranslator_application_get_preferences_dialog (GTR_APP);
+
+  treeview = gtranslator_preferences_dialog_get_treeview (dlg);
+   
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
+  g_return_if_fail (GTK_IS_LIST_STORE (model));
+  
+  gtk_widget_destroy (gtk_widget_get_ancestor (widget, GTK_TYPE_DIALOG));
+    
+  gtranslator_preferences_fill_profile_treeview (dlg, model);
+}
+
+static void save_modified_profile (GtkWidget *widget,
+				   GtranslatorProfile *profile)
+{
+  GtkWidget *treeview;
+  GtkTreeModel *model;
+  GtranslatorPreferencesDialog *dlg;
+
+  dlg = gtranslator_application_get_preferences_dialog (GTR_APP);
+
+  treeview = gtranslator_preferences_dialog_get_treeview (dlg);
+   
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
+  g_return_if_fail (GTK_IS_LIST_STORE (model));
+  
+  gtk_widget_destroy (gtk_widget_get_ancestor (widget, GTK_TYPE_DIALOG));
+    
+  gtranslator_preferences_fill_profile_treeview (dlg, model);
+}
+
+static void destroy_without_changes (GtkWidget *widget,
+				     gpointer data)
+{
+  struct data* sdata;
+
+  sdata = (struct data*) data;
+
+  gtranslator_profile_set_name (sdata->new_profile, gtranslator_profile_get_name (sdata->old_profile)); 
+  gtranslator_profile_set_author_name (sdata->new_profile, gtranslator_profile_get_author_name (sdata->old_profile));
+  gtranslator_profile_set_author_email (sdata->new_profile, gtranslator_profile_get_author_email (sdata->old_profile));
+  gtranslator_profile_set_language_name (sdata->new_profile, gtranslator_profile_get_language_name (sdata->old_profile));
+  gtranslator_profile_set_language_code (sdata->new_profile, gtranslator_profile_get_language_code (sdata->old_profile));
+  gtranslator_profile_set_charset (sdata->new_profile, gtranslator_profile_get_charset (sdata->old_profile));
+  gtranslator_profile_set_encoding (sdata->new_profile, gtranslator_profile_get_encoding (sdata->old_profile));
+  gtranslator_profile_set_group_email (sdata->new_profile, gtranslator_profile_get_group_email (sdata->old_profile));
+  gtranslator_profile_set_plurals (sdata->new_profile, gtranslator_profile_get_plurals (sdata->old_profile));
+
+  gtk_widget_destroy (gtk_widget_get_ancestor (widget, GTK_TYPE_DIALOG));
+}
+
 static void gtranslator_profile_dialog_init (GtranslatorProfileDialog *dlg)
 {
 	gboolean ret;
 	GtkWidget *error_widget;
-	GtkTooltips *tips;
-	
-	tips = g_object_new(GTK_TYPE_TOOLTIPS, NULL);
 	
 	dlg->priv = GTR_PROFILE_DIALOG_GET_PRIVATE (dlg);
-
-	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
-				GTK_STOCK_OK,
-				GTK_RESPONSE_OK,
-				NULL);
-
-	gtk_dialog_add_buttons (GTK_DIALOG (dlg),
-				GTK_STOCK_CANCEL,
-				GTK_RESPONSE_CANCEL,
-				NULL);
 	
 	gtk_window_set_title (GTK_WINDOW (dlg), _("gtranslator Profile"));
 	gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
@@ -97,12 +329,7 @@
 	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
 	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 2);
 
-	g_signal_connect (dlg,
-			  "response",
-			  G_CALLBACK (gtk_widget_destroy),
-			  NULL);
-	
-	ret = gtranslator_utils_get_glade_widgets(DATADIR"/profile-dialog.glade",
+	ret = gtranslator_utils_get_glade_widgets(PKGDATADIR"/profile-dialog.glade",
 		"profiles_dialog",
 		&error_widget,
 		"profiles_dialog", &dlg->priv->main_box,
@@ -126,29 +353,45 @@
 		return;
 	}
 	
-	gtk_tooltips_set_tip(tips, GTK_WIDGET(dlg->priv->plurals_forms_entry),
-				"Example: nplurals=2; plural=(n != 1);", "");
+	gtk_widget_set_tooltip_text (dlg->priv->plurals_forms_entry,
+				     _("Example: nplurals=2; plural=(n != 1);"));
 
 	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
 			    dlg->priv->main_box, FALSE, FALSE, 0);
 	gtk_window_set_modal (GTK_WINDOW (dlg), TRUE);
+	
 }
 
-void gtranslator_show_profile_dialog (GtranslatorPreferencesDialog *dialog)
+void gtranslator_show_profile_dialog (GtranslatorPreferencesDialog *dialog,
+				      GtranslatorProfile *profile,
+				      gint action)
 {
-	
+        struct data *data;
+	data = (struct data *) malloc(sizeof(struct data));
+
 	static GtkWidget *dlg = NULL;
+	GtkButton *ok_button, *cancel_button;
+	GtranslatorProfile *old_profile;
+
+	old_profile = gtranslator_profile_new ();
+	
+	cancel_button = GTK_BUTTON (gtk_button_new_from_stock (GTK_STOCK_CANCEL));
+	ok_button = GTK_BUTTON (gtk_button_new_from_stock (GTK_STOCK_OK));
 
 	g_return_if_fail(GTR_IS_PREFERENCES_DIALOG(dialog));
 	
 	if(dlg == NULL)
 	{
-		dlg = GTK_WIDGET (g_object_new (GTR_TYPE_PROFILE_DIALOG, NULL));
-		g_signal_connect (dlg,
-				  "destroy",
-				  G_CALLBACK (gtk_widget_destroyed),
-				  &dlg);
-		gtk_widget_show_all(dlg);
+	  dlg = GTK_WIDGET (g_object_new (GTR_TYPE_PROFILE_DIALOG, NULL));
+	  g_signal_connect (dlg,
+			    "destroy",
+			    G_CALLBACK (gtk_widget_destroyed),
+			    &dlg);
+	  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), GTK_WIDGET (cancel_button));
+	  
+	  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), GTK_WIDGET (ok_button));
+	  
+	  gtk_widget_show_all(dlg);
 	}
 	
 	if (GTK_WINDOW (dialog) != gtk_window_get_transient_for (GTK_WINDOW (dlg)))
@@ -156,7 +399,115 @@
 		gtk_window_set_transient_for (GTK_WINDOW (dlg),
 					      GTK_WINDOW (dialog));
 	}
+
+	if (gtranslator_profile_get_name (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->profile_name_entry),
+			      gtranslator_profile_get_name (profile));
+	  gtranslator_profile_set_name (old_profile, gtranslator_profile_get_name (profile));
+	}
 	
-	gtk_window_present (GTK_WINDOW (dlg));	
+	if (gtranslator_profile_get_author_name (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->author_name_entry),
+			      gtranslator_profile_get_author_name (profile));
+	  gtranslator_profile_set_author_name (old_profile, gtranslator_profile_get_author_name (profile));
+	}
+	
+	if (gtranslator_profile_get_author_email (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->author_email_entry),
+			      gtranslator_profile_get_author_email (profile));
+	  gtranslator_profile_set_author_email (old_profile, gtranslator_profile_get_author_email (profile));
+	}
+
+        if (gtranslator_profile_get_language_name (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->language_name_entry),
+			      gtranslator_profile_get_language_name (profile));
+	  gtranslator_profile_set_language_name (old_profile, gtranslator_profile_get_language_name (profile));
+	}
+
+        if (gtranslator_profile_get_language_code (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->language_code_entry),
+			      gtranslator_profile_get_language_code (profile));
+	  gtranslator_profile_set_language_code (old_profile, gtranslator_profile_get_language_code (profile));
+	}
+
+        if (gtranslator_profile_get_charset (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->charset_entry),
+			      gtranslator_profile_get_charset (profile));
+	  gtranslator_profile_set_charset (old_profile, gtranslator_profile_get_charset (profile));
+	}
+
+        if (gtranslator_profile_get_encoding (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->encoding_entry),
+			      gtranslator_profile_get_encoding (profile));
+	  gtranslator_profile_set_encoding (old_profile, gtranslator_profile_get_encoding (profile));
+	}
+ 
+        if (gtranslator_profile_get_group_email (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->language_email_entry),
+			      gtranslator_profile_get_group_email (profile));
+	  gtranslator_profile_set_group_email (old_profile, gtranslator_profile_get_group_email (profile));
+ }
+
+        if (gtranslator_profile_get_plurals (profile) != NULL) {
+	  gtk_entry_set_text (GTK_ENTRY (GTR_PROFILE_DIALOG (dlg)->priv->plurals_forms_entry),
+			      gtranslator_profile_get_plurals (profile));
+	  gtranslator_profile_set_plurals (old_profile, gtranslator_profile_get_plurals (profile));
+}
+
+	data->old_profile = old_profile;
+	data->new_profile = profile;
+
+	/* Connect entry signals */
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->profile_name_entry, "notify::text",
+			  G_CALLBACK (profile_name_entry_changed),
+			  profile);
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->author_name_entry, "notify::text",
+			  G_CALLBACK (author_name_entry_changed),
+			  profile);
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->author_email_entry, "notify::text",
+			  G_CALLBACK (author_email_entry_changed),
+			  profile);
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->language_name_entry, "notify::text",
+			  G_CALLBACK (language_name_entry_changed),
+			  profile);
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->language_code_entry, "notify::text",
+			  G_CALLBACK (language_code_entry_changed),
+			  profile);
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->charset_entry, "notify::text",
+			  G_CALLBACK (charset_entry_changed),
+			  profile);
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->encoding_entry, "notify::text",
+			  G_CALLBACK (encoding_entry_changed),
+			  profile);
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->language_email_entry, "notify::text",
+			  G_CALLBACK (group_email_entry_changed),
+			  profile);
+	g_signal_connect (GTR_PROFILE_DIALOG (dlg)->priv->plurals_forms_entry, "notify::text",
+			  G_CALLBACK (plurals_entry_changed),
+			  profile);
+
+	/*
+	 * Connect signals to dialog buttons.
+	 */
+
+	g_signal_connect (cancel_button,
+			  "clicked",
+			  G_CALLBACK (destroy_without_changes),
+			  data);
+
+	if (action == NEW_PROFILE) {
+	  g_signal_connect (ok_button,
+			    "clicked",
+			    G_CALLBACK (save_new_profile),
+			    profile);
+	} else {
+	  if (action == EDIT_PROFILE) {
+	    g_signal_connect (ok_button,
+			      "clicked",
+			      G_CALLBACK (save_modified_profile),
+			      profile);
+	  }
+	}
+
 }
 

Modified: trunk/src/dialogs/profile-dialog.glade
==============================================================================
--- trunk/src/dialogs/profile-dialog.glade	(original)
+++ trunk/src/dialogs/profile-dialog.glade	Tue Sep 16 07:58:13 2008
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.0 on Mon Mar 17 17:20:26 2008 -->
+<!--Generated with glade3 3.4.5 on Wed Aug  6 11:28:41 2008 -->
 <glade-interface>
   <widget class="GtkDialog" id="dialog1">
     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -9,12 +9,12 @@
     <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
     <property name="has_separator">False</property>
     <child internal-child="vbox">
-      <widget class="GtkVBox" id="profiles_dialog">
+      <widget class="GtkVBox" id="vbox1">
         <property name="visible">True</property>
         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
         <property name="spacing">2</property>
         <child>
-          <widget class="GtkVBox" id="vbox1">
+          <widget class="GtkVBox" id="profiles_dialog">
             <property name="visible">True</property>
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
             <property name="spacing">18</property>
@@ -60,27 +60,27 @@
                         <property name="column_spacing">6</property>
                         <property name="row_spacing">6</property>
                         <child>
-                          <widget class="GtkLabel" id="label3">
+                          <widget class="GtkEntry" id="profile_entry">
                             <property name="visible">True</property>
+                            <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">_Name:</property>
-                            <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">profile_entry</property>
                           </widget>
                           <packing>
-                            <property name="x_options">GTK_FILL</property>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkEntry" id="profile_entry">
+                          <widget class="GtkLabel" id="label3">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">_Name:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">profile_entry</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                       </widget>
@@ -141,7 +141,7 @@
                         <property name="column_spacing">6</property>
                         <property name="row_spacing">6</property>
                         <child>
-                          <widget class="GtkEntry" id="name_entry">
+                          <widget class="GtkEntry" id="email_entry">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -149,38 +149,40 @@
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label6">
+                          <widget class="GtkLabel" id="label7">
                             <property name="visible">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                             <property name="xalign">0</property>
-                            <property name="label" translatable="yes">N_ame:</property>
+                            <property name="label" translatable="yes">_Email:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">name_entry</property>
+                            <property name="mnemonic_widget">email_entry</property>
                           </widget>
                           <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
                             <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label7">
+                          <widget class="GtkLabel" id="label6">
                             <property name="visible">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                             <property name="xalign">0</property>
-                            <property name="label" translatable="yes">_Email:</property>
+                            <property name="label" translatable="yes">N_ame:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">email_entry</property>
+                            <property name="mnemonic_widget">name_entry</property>
                           </widget>
                           <packing>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
                             <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkEntry" id="email_entry">
+                          <widget class="GtkEntry" id="name_entry">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -188,8 +190,6 @@
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
                           </packing>
                         </child>
                       </widget>
@@ -256,134 +256,134 @@
                             <property name="column_spacing">6</property>
                             <property name="row_spacing">6</property>
                             <child>
-                              <widget class="GtkLabel" id="label11">
+                              <widget class="GtkEntry" id="team_email_entry">
                                 <property name="visible">True</property>
+                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Language:</property>
-                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="x_options">GTK_FILL</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">4</property>
+                                <property name="bottom_attach">5</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkLabel" id="label12">
+                              <widget class="GtkEntry" id="encoding_entry">
                                 <property name="visible">True</property>
+                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">Language _code:</property>
-                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
-                                <property name="x_options">GTK_FILL</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkLabel" id="label13">
+                              <widget class="GtkEntry" id="charset_entry">
                                 <property name="visible">True</property>
+                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">Character _set</property>
-                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
                                 <property name="top_attach">2</property>
                                 <property name="bottom_attach">3</property>
-                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkLabel" id="label14">
+                              <widget class="GtkEntry" id="langcode_entry">
                                 <property name="visible">True</property>
+                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">Transfer en_coding:</property>
-                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="top_attach">3</property>
-                                <property name="bottom_attach">4</property>
-                                <property name="x_options">GTK_FILL</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkLabel" id="label15">
+                              <widget class="GtkEntry" id="language_entry">
                                 <property name="visible">True</property>
+                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Team email:</property>
-                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="top_attach">4</property>
-                                <property name="bottom_attach">5</property>
-                                <property name="x_options">GTK_FILL</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkEntry" id="language_entry">
+                              <widget class="GtkLabel" id="label15">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">_Team email:</property>
+                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
+                                <property name="top_attach">4</property>
+                                <property name="bottom_attach">5</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkEntry" id="langcode_entry">
+                              <widget class="GtkLabel" id="label14">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Transfer en_coding:</property>
+                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkEntry" id="charset_entry">
+                              <widget class="GtkLabel" id="label13">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Character _set</property>
+                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
                                 <property name="top_attach">2</property>
                                 <property name="bottom_attach">3</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkEntry" id="encoding_entry">
+                              <widget class="GtkLabel" id="label12">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Language _code:</property>
+                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">3</property>
-                                <property name="bottom_attach">4</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkEntry" id="team_email_entry">
+                              <widget class="GtkLabel" id="label11">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">_Language:</property>
+                                <property name="use_underline">True</property>
                               </widget>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">4</property>
-                                <property name="bottom_attach">5</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                           </widget>

Modified: trunk/src/dialogs/profile-dialog.h
==============================================================================
--- trunk/src/dialogs/profile-dialog.h	(original)
+++ trunk/src/dialogs/profile-dialog.h	Tue Sep 16 07:58:13 2008
@@ -23,9 +23,15 @@
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
+#include "profile.h"
 #include "window.h"
 #include "preferences-dialog.h"
 
+enum {
+    NEW_PROFILE,
+    EDIT_PROFILE
+  };
+
 /*
  * Type checking and casting macros
  */
@@ -69,6 +75,8 @@
 
 GType		 gtranslator_profile_dialog_register_type          (GTypeModule * module);
 
-void	         gtranslator_show_profile_dialog                   (GtranslatorPreferencesDialog *dialog);
+void	         gtranslator_show_profile_dialog                   (GtranslatorPreferencesDialog *dialog,
+								    GtranslatorProfile *profile,
+								    gint action);
 
 #endif

Modified: trunk/src/dialogs/search-dialog.c
==============================================================================
--- trunk/src/dialogs/search-dialog.c	(original)
+++ trunk/src/dialogs/search-dialog.c	Tue Sep 16 07:58:13 2008
@@ -369,7 +369,7 @@
 	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 5);
 	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 6);
 
-	ret = gtranslator_utils_get_glade_widgets (DATADIR"/search-dialog.glade",
+	ret = gtranslator_utils_get_glade_widgets (PKGDATADIR"/search-dialog.glade",
 					     "search_dialog_content",
 					     &error_widget,
 					     "search_dialog_content", &content,

Modified: trunk/src/dialogs/search-dialog.glade
==============================================================================
--- trunk/src/dialogs/search-dialog.glade	(original)
+++ trunk/src/dialogs/search-dialog.glade	Tue Sep 16 07:58:13 2008
@@ -30,27 +30,27 @@
                   <placeholder/>
                 </child>
                 <child>
-                  <widget class="GtkLabel" id="search_label">
+                  <widget class="GtkLabel" id="replace_with_label">
                     <property name="visible">True</property>
                     <property name="xalign">0</property>
-                    <property name="label" translatable="yes">_Search for: </property>
+                    <property name="label" translatable="yes">Replace _with: </property>
                     <property name="use_underline">True</property>
                   </widget>
                   <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
                     <property name="x_options">GTK_FILL</property>
                     <property name="y_options"></property>
                   </packing>
                 </child>
                 <child>
-                  <widget class="GtkLabel" id="replace_with_label">
+                  <widget class="GtkLabel" id="search_label">
                     <property name="visible">True</property>
                     <property name="xalign">0</property>
-                    <property name="label" translatable="yes">Replace _with: </property>
+                    <property name="label" translatable="yes">_Search for: </property>
                     <property name="use_underline">True</property>
                   </widget>
                   <packing>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
                     <property name="x_options">GTK_FILL</property>
                     <property name="y_options"></property>
                   </packing>
@@ -88,19 +88,6 @@
                         <property name="position">1</property>
                       </packing>
                     </child>
-                    <child>
-                      <widget class="GtkCheckButton" id="fuzzy_checkbutton">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="label" translatable="yes">Fuzzy</property>
-                        <property name="response_id">0</property>
-                        <property name="draw_indicator">True</property>
-                      </widget>
-                      <packing>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
                   </widget>
                   <packing>
                     <property name="expand">False</property>
@@ -119,6 +106,20 @@
                   </packing>
                 </child>
                 <child>
+                  <widget class="GtkCheckButton" id="fuzzy_checkbutton">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="label" translatable="yes">Include fuzzy strings</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
                   <widget class="GtkCheckButton" id="match_case_checkbutton">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
@@ -130,7 +131,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">2</property>
+                    <property name="position">3</property>
                   </packing>
                 </child>
                 <child>
@@ -145,7 +146,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">3</property>
+                    <property name="position">4</property>
                   </packing>
                 </child>
               </widget>

Modified: trunk/src/draw-spaces.c
==============================================================================
--- trunk/src/draw-spaces.c	(original)
+++ trunk/src/draw-spaces.c	Tue Sep 16 07:58:13 2008
@@ -87,15 +87,30 @@
 	gtk_text_view_get_iter_location(view, iter, &rect);
 	gtk_text_view_buffer_to_window_coords(view, GTK_TEXT_WINDOW_TEXT,
 					      rect.x,
-					      rect.y + rect.height / 2, &x, &y);	
+					      rect.y + rect.height / 2, &x, &y);
+
+	
 	cairo_save(cr);
-	cairo_move_to(cr, x+2, y-2);
-	cairo_rel_line_to(cr, +7, 0);
-	cairo_rel_line_to(cr, 0, 4);
-	cairo_rel_move_to(cr, -3, 0);
-	cairo_rel_line_to(cr, 5, 0);
-	cairo_rel_line_to(cr, -2.5, 4);
-	cairo_rel_line_to(cr, -2.5, -4);
+	
+	if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR)
+	{
+		cairo_move_to(cr, x+2, y-2);
+		cairo_rel_line_to(cr, +7, 0);
+		cairo_rel_line_to(cr, 0, 4);
+		cairo_rel_move_to(cr, -3, 0);
+		cairo_rel_line_to(cr, 6, 0);
+		cairo_rel_line_to(cr, -3, 4);
+		cairo_rel_line_to(cr, -3, -4);
+	}else
+	{
+		cairo_move_to (cr, x-2, y-2);
+		cairo_rel_line_to(cr, -7, 0);
+		cairo_rel_line_to(cr, 0, 4);
+		cairo_rel_move_to(cr, 3, 0);
+		cairo_rel_line_to(cr, -6, 0);
+		cairo_rel_line_to(cr, 3, 4);
+		cairo_rel_line_to(cr, 3, -4);
+	}
 	cairo_restore(cr);
 	cairo_fill(cr);
 	
@@ -148,4 +163,6 @@
 		if(!gtk_text_iter_forward_char(&iter))
 			break;
 	}
+	
+	cairo_destroy (cr);
 }

Modified: trunk/src/header.c
==============================================================================
--- trunk/src/header.c	(original)
+++ trunk/src/header.c	Tue Sep 16 07:58:13 2008
@@ -96,6 +96,11 @@
 	 */
 	gchar *plural_forms;
 	gint nplurals;
+
+        /*
+         * Check if header has changed
+         */
+        gboolean header_changed;
 };
 
 /*
@@ -368,6 +373,35 @@
 }
 
 /**
+ * gtranslator_header_get_header_changed:
+ * @header: a #GtranslatorHeader.
+ *
+ * Return value: TRUE if the header has changed, FALSE if not.
+ */
+
+gboolean
+gtranslator_header_get_header_changed (GtranslatorHeader *header)
+{
+  g_return_val_if_fail (GTR_IS_HEADER (header), NULL);
+
+  return header->priv->header_changed;
+}
+
+/**
+ * gtranslator_header_set_header_changed:
+ * @header: a #GtranslatorHeader
+ * @gboolean: Indicate if the header has changed or not.
+ *
+ * Sets the state of the header, TRUE if has changed, FALSE if not.
+ */
+
+void
+gtranslator_header_set_header_changed (GtranslatorHeader *header, gboolean change)
+{
+  header->priv->header_changed = change;
+}
+
+/**
  * gtranslator_header_get_plural:
  * @header: a #GtranslatorHeader
  *

Modified: trunk/src/header.h
==============================================================================
--- trunk/src/header.h	(original)
+++ trunk/src/header.h	Tue Sep 16 07:58:13 2008
@@ -110,6 +110,10 @@
 const gchar	*gtranslator_header_get_plural_forms	(GtranslatorHeader *header);
 void             gtranslator_header_set_plural_forms    (GtranslatorHeader *header,
 							 const gchar *plural_forms);
+
+gboolean         gtranslator_header_get_header_changed  (GtranslatorHeader *header);
+void             gtranslator_header_set_header_changed  (GtranslatorHeader *header,
+							 gboolean change);
 							 
 gint             gtranslator_header_get_nplurals        (GtranslatorHeader *header);
 

Modified: trunk/src/history-entry.c
==============================================================================
--- trunk/src/history-entry.c	(original)
+++ trunk/src/history-entry.c	Tue Sep 16 07:58:13 2008
@@ -25,7 +25,7 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: history-entry.c 5931 2007-09-25 20:05:40Z pborelli $
+ * $Id: history-entry.c 6377 2008-08-10 14:45:44Z pborelli $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -158,7 +158,8 @@
 							      "History ID",
 							      "History ID",
 							      NULL,
-							      G_PARAM_READWRITE));
+							      G_PARAM_READWRITE |
+							      G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property (object_class,
 					 PROP_HISTORY_LENGTH,
@@ -168,7 +169,8 @@
 							    0,
 							    G_MAXUINT,
 							    GTR_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT,
-							    G_PARAM_READWRITE));
+							    G_PARAM_READWRITE |
+							    G_PARAM_STATIC_STRINGS));
 
 	/* TODO: Add enable-completion property */
 
@@ -258,6 +260,7 @@
 			      gconf_items,
 			      NULL);
 
+	g_slist_foreach (gconf_items, (GFunc) g_free, NULL);
 	g_slist_free (gconf_items);
 	g_free (key);
 }
@@ -287,9 +290,12 @@
 		    strcmp (item_text, text) == 0)
 		{
 			gtk_list_store_remove (store, &iter);
+			g_free (item_text);
 			return TRUE;
 		}
 
+		g_free (item_text);
+
 	} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
 
 	return FALSE;
@@ -406,8 +412,9 @@
 				    -1);
 	}
 
-	g_free (key);
+	g_slist_foreach (gconf_items, (GFunc) g_free, NULL);
 	g_slist_free (gconf_items);
+	g_free (key);
 }
 
 void

Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	(original)
+++ trunk/src/main.c	Tue Sep 16 07:58:13 2008
@@ -60,16 +60,12 @@
 		for (i = 0; file_arguments[i]; i++) 
 		{			
 			GFile  *file;
-			gchar *uri;
 
 			file = g_file_new_for_commandline_arg (file_arguments[i]);
-			uri = g_file_get_uri (file);
-			g_object_unref (file);
-
 			
-			if (uri != NULL){
+			if (file != NULL){
 				file_list = g_slist_prepend (file_list, 
-							     uri);
+							     file);
 				
 			}
 			else
@@ -87,15 +83,19 @@
  * The ubiquitous main function...
  */
 gint
-main(gint argc,
-     gchar *argv[])
+main (gint argc,
+      gchar *argv[])
 {
 	GError *error = NULL;
 	GtranslatorPluginsEngine *engine;
 	GtranslatorWindow *window;
 	GSList *file_list = NULL;
 	GOptionContext *context;
-	
+	gchar *filename;
+	gchar *config_folder;
+	GList *profiles_list = NULL;
+	GFile *file;
+
 	/*
 	 * Initialize gettext.
 	 */ 
@@ -125,6 +125,7 @@
 		g_clear_error(&error);
 	}
 
+	if (!g_thread_supported()) g_thread_init(NULL);
 	gtk_init(&argc, &argv);
 	
 	g_option_context_parse(context, &argc, &argv, NULL);
@@ -157,7 +158,23 @@
 	engine = gtranslator_plugins_engine_get_default ();
 	
 	gtk_about_dialog_set_url_hook (gtranslator_utils_activate_url, NULL, NULL);
+	gtk_about_dialog_set_email_hook (gtranslator_utils_activate_email, NULL, NULL);
 
+	/*
+	 * Load profiles list
+	 */
+	 config_folder = gtranslator_utils_get_user_config_dir ();
+	 filename = g_build_filename (config_folder,
+				      "profiles.xml",
+				      NULL);
+	 file = g_file_new_for_path (filename);
+  
+	 if (g_file_query_exists (file, NULL)) {
+	   profiles_list = gtranslator_profile_get_profiles_from_xml_file (filename);
+	 }
+
+	 gtranslator_application_set_profiles (GTR_APP, profiles_list);
+		
 	/* 
 	 * Create the main app-window. 
 	 */
@@ -169,11 +186,13 @@
 	file_list = get_command_line_data ();
 	if (file_list)
 	{
-		gtranslator_actions_load_uris (window, (const GSList *)file_list);
-		g_slist_foreach (file_list, (GFunc) g_free, NULL);
+		gtranslator_actions_load_locations (window, (const GSList *)file_list);
+		g_slist_foreach (file_list, (GFunc) g_object_unref, NULL);
 		g_slist_free (file_list);
 	}
 	
+	g_option_context_free (context);
+	
 	/*
 	 * Enter main GTK loop
 	 */

Modified: trunk/src/message-area.c
==============================================================================
--- trunk/src/message-area.c	(original)
+++ trunk/src/message-area.c	Tue Sep 16 07:58:13 2008
@@ -25,7 +25,7 @@
  * list of people on the gtranslator Team.
  * See the ChangeLog files for a list of changes.
  *
- * $Id: message-area.c 5887 2007-09-07 07:20:19Z pborelli $
+ * $Id: message-area.c 6468 2008-08-28 08:23:00Z icq $
  */
 
 /* TODO: Style properties */
@@ -335,6 +335,13 @@
 				    0);
 }
 
+/**
+ * gtranslator_message_area_set_contents:
+ * @message_area: a #GtranslatorMessageArea
+ * @contents: widget you want to add to the contents area
+ *
+ * Adds the @contents widget to the contents area of #GtranslatorMessageArea.
+ */
 void
 gtranslator_message_area_set_contents	(GtranslatorMessageArea *message_area,
 				 GtkWidget        *contents)
@@ -350,6 +357,19 @@
 			    0);
 }
 
+/**
+ * gtranslator_message_area_add_button:
+ * @message_area: a #GtranslatorMessageArea
+ * @button_text: text of button, or stock ID
+ * @response_id: response ID for the button
+ * 
+ * Adds a button with the given text (or a stock button, if button_text is a stock ID)
+ * and sets things up so that clicking the button will emit the "response" signal
+ * with the given response_id. The button is appended to the end of the message area's
+ * action area. The button widget is returned, but usually you don't need it.
+ *
+ * Returns: the button widget that was added
+ */
 GtkWidget*
 gtranslator_message_area_add_button (GtranslatorMessageArea *message_area,
 			       const gchar      *button_text,
@@ -403,6 +423,16 @@
 	}
 }
 
+/**
+ * gtranslator_message_area_add_buttons:
+ * @message_area: a #GtranslatorMessageArea
+ * @first_button_text: button text or stock ID
+ * @...: response ID for first button, then more text-response_id pairs
+ *
+ * Adds more buttons, same as calling gtranslator_message_area_add_button() repeatedly.
+ * The variable argument list should be NULL-terminated as with
+ * gtranslator_message_area_new_with_buttons(). Each button must have both text and response ID.
+ */
 void
 gtranslator_message_area_add_buttons (GtranslatorMessageArea *message_area,
 				const gchar      *first_button_text,
@@ -419,12 +449,33 @@
 	va_end (args);
 }
 
+/**
+ * gtranslator_message_area_new:
+ * 
+ * Creates a new #GtranslatorMessageArea object.
+ * 
+ * Returns: a new #GtranslatorMessageArea object
+ */
 GtkWidget *
 gtranslator_message_area_new (void)
 {
 	return g_object_new (GTR_TYPE_MESSAGE_AREA, NULL);
 }
 
+/**
+ * gtranslator_message_area_new_with_buttons:
+ * @first_button_text: stock ID or text to go in first button, or NULL
+ * @...: response ID for first button, then additional buttons, ending with NULL
+ * 
+ * Creates a new #GtranslatorMessageArea with buttons. Button text/response ID pairs 
+ * should be listed, with a NULL pointer ending the list. Button text can be either
+ * a stock ID such as GTK_STOCK_OK, or some arbitrary text. A response ID can be any
+ * positive number, or one of the values in the GtkResponseType enumeration. If 
+ * the user clicks one of these dialog buttons, GtranslatorMessageArea will emit the "response"
+ * signal with the corresponding response ID.
+ *
+ * Returns: a new #GtranslatorMessageArea
+ */
 GtkWidget *
 gtranslator_message_area_new_with_buttons (const gchar *first_button_text,
                                      ...)
@@ -445,6 +496,16 @@
 	return GTK_WIDGET (message_area);
 }
 
+/**
+ * gtranslator_message_area_set_response_sensitive:
+ * @message_area: a #GtranslatorMessageArea
+ * @response_id: a response ID
+ * @setting: TRUE for sensitive
+ *
+ * Calls gtk_widget_set_sensitive (widget, setting) for each widget in the dialog's
+ * action area with the given response_id. A convenient way to sensitize/desensitize
+ * dialog buttons.
+ */
 void
 gtranslator_message_area_set_response_sensitive (GtranslatorMessageArea *message_area,
 					   gint              response_id,
@@ -472,6 +533,15 @@
 	g_list_free (children);
 }
 
+/**
+ * gtranslator_message_area_set_default_response:
+ * @message_area: a #GtranslatorMessageArea
+ * @response_id: a response ID
+ *
+ * Sets the last widget in the message area's action area with the given response_id
+ * as the default widget for the dialog. Pressing "Enter" normally activates the
+ * default widget.
+ */
 void
 gtranslator_message_area_set_default_response (GtranslatorMessageArea *message_area,
 					 gint              response_id)
@@ -498,6 +568,13 @@
 	g_list_free (children);
 }
 
+/**
+ * gtranslator_message_area_set_default_response:
+ * @message_area: a #GtranslatorMessageArea
+ * @response_id: a response ID
+ *
+ * Emits the 'response' signal with the given @response_id.
+ */
 void
 gtranslator_message_area_response (GtranslatorMessageArea *message_area,
 			     gint              response_id)
@@ -510,6 +587,15 @@
 		       response_id);
 }
 
+/**
+ * gtranslator_message_area_add_stock_button_with_text:
+ * @message_area: a #GtranslatorMessageArea
+ * @text: the text to visualize in the button
+ * @stock_id: the stock ID of the button
+ * @response_id: a response ID
+ *
+ * Same as gtranslator_message_area_add_button() but with a specific text.
+ */
 GtkWidget *
 gtranslator_message_area_add_stock_button_with_text (GtranslatorMessageArea *message_area,
 				    	       const gchar      *text,

Modified: trunk/src/message-area.h
==============================================================================
--- trunk/src/message-area.h	(original)
+++ trunk/src/message-area.h	Tue Sep 16 07:58:13 2008
@@ -25,7 +25,7 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: message-area.h 5666 2007-06-29 19:52:25Z sfre $
+ * $Id: message-area.h 6138 2008-02-01 14:32:22Z icq $
  */
 
 #ifndef __GTR_MESSAGE_AREA_H__

Modified: trunk/src/message-table.c
==============================================================================
--- trunk/src/message-table.c	(original)
+++ trunk/src/message-table.c	Tue Sep 16 07:58:13 2008
@@ -76,7 +76,8 @@
 		if (msg != NULL && g_utf8_collate (gtranslator_msg_get_msgid (msg->data),
 						   gtranslator_msg_get_msgid (current_msg->data)))
 		{
-			gtranslator_tab_message_go_to (table->priv->tab, msg);
+			gtranslator_tab_message_go_to (table->priv->tab, msg,
+						       FALSE, GTR_TAB_MOVE_NONE);
 		}
 	}
 }
@@ -245,7 +246,8 @@
 	gtranslator_po_set_messages (po, messages);
 
 	gtranslator_tab_message_go_to (table->priv->tab,
-				       g_list_first (messages));
+				       g_list_first (messages),
+				       FALSE, GTR_TAB_MOVE_NONE);
 }
 
 static void
@@ -383,6 +385,14 @@
 	object_class->finalize = gtranslator_message_table_finalize;
 }
 
+/**
+ * gtranslator_message_table_new:
+ * @tab: a #GtranslatorTab
+ *
+ * Creates a new #GtranslatorMessageTable object.
+ *
+ * Returns: the newly created #GtranslatorMessageTable
+ */
 GtkWidget *
 gtranslator_message_table_new (GtkWidget *tab)
 {
@@ -400,6 +410,14 @@
 	return GTK_WIDGET(obj);
 }
 
+/**
+ * gtranslator_message_table_populate:
+ * @table: a #GtranslatorMessageTable
+ * @messages: a list of #GtranslatorMsg
+ *
+ * Populates the #GtranslatorMessageTable with the list of #GtranslatorMsg and
+ * sort them.
+ */
 void 
 gtranslator_message_table_populate(GtranslatorMessageTable *table, 
 				   GList *messages)

Modified: trunk/src/msg.c
==============================================================================
--- trunk/src/msg.c	(original)
+++ trunk/src/msg.c	Tue Sep 16 07:58:13 2008
@@ -49,9 +49,64 @@
 	gint po_position;
 };
 
+enum
+{
+	PROP_0,
+	PROP_GETTEXT_ITER,
+	PROP_GETTEXT_MSG
+};
+
 static gchar *message_error = NULL;
 
 static void
+gtranslator_msg_set_property (GObject      *object,
+			      guint         prop_id,
+			      const GValue *value,
+			      GParamSpec   *pspec)
+{
+	GtranslatorMsg *msg = GTR_MSG (object);
+
+	switch (prop_id)
+	{
+		case PROP_GETTEXT_ITER:
+			gtranslator_msg_set_iterator (msg,
+						      g_value_get_pointer (value));
+			break;
+		case PROP_GETTEXT_MSG:
+			gtranslator_msg_set_message (msg,
+						     g_value_get_pointer (value));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;			
+	}
+}
+
+static void
+gtranslator_msg_get_property (GObject    *object,
+			      guint       prop_id,
+			      GValue     *value,
+			      GParamSpec *pspec)
+{
+	GtranslatorMsg *msg = GTR_MSG (object);
+
+	switch (prop_id)
+	{
+		case PROP_GETTEXT_ITER:
+			g_value_set_pointer (value,
+					     gtranslator_msg_get_iterator (msg));
+			break;
+		case PROP_GETTEXT_MSG:
+			g_value_set_pointer (value,
+					     gtranslator_msg_get_message (msg));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
 gtranslator_msg_init (GtranslatorMsg *msg)
 {
 	msg->priv = GTR_MSG_GET_PRIVATE (msg);
@@ -59,8 +114,7 @@
 
 static void
 gtranslator_msg_finalize (GObject *object)
-{
-	g_free(message_error);
+{	
 	G_OBJECT_CLASS (gtranslator_msg_parent_class)->finalize (object);
 }
 
@@ -72,6 +126,22 @@
 	g_type_class_add_private (klass, sizeof (GtranslatorMsgPrivate));
 
 	object_class->finalize = gtranslator_msg_finalize;
+	object_class->set_property = gtranslator_msg_set_property;
+	object_class->get_property = gtranslator_msg_get_property;	
+	
+	g_object_class_install_property (object_class,
+					 PROP_GETTEXT_MSG,
+					 g_param_spec_pointer ("gettext-iter",
+							       "Gettext iterator",
+							       "The po_message_iterator_t pointer",
+							       G_PARAM_READWRITE));
+	
+	g_object_class_install_property (object_class,
+					 PROP_GETTEXT_MSG,
+					 g_param_spec_pointer ("gettext-msg",
+							       "Gettext msg",
+							       "The po_message_t pointer",
+							       G_PARAM_READWRITE));	
 }
 
 /***************************** Public funcs ***********************************/
@@ -79,28 +149,74 @@
 /**
  * gtranslator_msg_new:
  * 
+ * Creates a new #GtranslatorMsg.
+ * 
  * Return value: a new #GtranslatorMsg object
  **/
 GtranslatorMsg *
-gtranslator_msg_new(po_message_iterator_t iter)
+gtranslator_msg_new (po_message_iterator_t iter,
+		     po_message_t message)
 {
 	GtranslatorMsg *msg;
 	
 	msg = g_object_new (GTR_TYPE_MSG, NULL);
-	msg->priv->iterator = iter;
+	
+	gtranslator_msg_set_iterator (msg, iter);
+	gtranslator_msg_set_message (msg, message);
+	
+	/* Set the status */
+	if (gtranslator_msg_is_fuzzy (msg))
+		gtranslator_msg_set_status (msg, GTR_MSG_STATUS_FUZZY);
+	else if (gtranslator_msg_is_translated (msg))
+		gtranslator_msg_set_status (msg, GTR_MSG_STATUS_TRANSLATED);
+	else gtranslator_msg_set_status (msg, GTR_MSG_STATUS_UNTRANSLATED);
 	
 	return msg;
 }
 
 /**
+ * gtranslator_msg_get_iterator:
+ * @msg: a #GtranslatorMsg
+ *
+ * Return value: the message iterator in gettext format
+ **/
+po_message_iterator_t
+gtranslator_msg_get_iterator (GtranslatorMsg *msg)
+{
+	g_return_val_if_fail (GTR_IS_MSG (msg), NULL);
+	
+	return msg->priv->iterator;
+}
+
+/**
+ * gtranslator_msg_set_iterator:
+ * @msg: a #GtranslatorMsg
+ * @message: the po_message_iterator_t to set into the @msg
+ *
+ * Sets the iterator into the #GtranslatorMsg class.
+ **/
+void
+gtranslator_msg_set_iterator (GtranslatorMsg *msg,
+			      po_message_iterator_t iter)
+{
+	g_return_if_fail (GTR_IS_MSG (msg));
+	
+	msg->priv->iterator = iter;
+	
+	g_object_notify (G_OBJECT (msg), "gettext-iter");
+}
+
+/**
  * gtranslator_msg_get_message:
  * @msg: a #GtranslatorMsg
  *
  * Return value: the message in gettext format
  **/
 po_message_t
-gtranslator_msg_get_message(GtranslatorMsg *msg)
+gtranslator_msg_get_message (GtranslatorMsg *msg)
 {
+	g_return_val_if_fail (GTR_IS_MSG (msg), NULL);
+	
 	return msg->priv->message;
 }
 
@@ -116,14 +232,17 @@
 			    po_message_t message)
 {
 	msg->priv->message = message;
+	
+	g_object_notify (G_OBJECT (msg), "gettext-msg");
 }
 
 /**
  * gtranslator_msg_get_row_reference:
  * @msg: a #GtranslatorMsg
  *
- * Return value: the GtkTreeRowReference corresponding to the message's place in the message table
- **/
+ * Returns: the #GtkTreeRowReference corresponding to the message's place
+ * in the message table
+ */
 GtkTreeRowReference *
 gtranslator_msg_get_row_reference(GtranslatorMsg *msg)
 {
@@ -484,7 +603,9 @@
 		     const gchar *filename, size_t lineno, size_t column,
 		     gint multiline_p, const gchar *message_text)
 {
-	message_error = g_strdup(message_text);
+	if (message_text)
+		message_error = g_strdup (message_text);
+	else message_error = NULL;
 }
 
 static void
@@ -504,31 +625,35 @@
  * gtranslator_msg_check:
  * @msg: a #GtranslatorMsg
  * 
- * Return value: the message error or NULL if there is not any error.
+ * Return value: the message error or NULL if there is not any error. Must be
+ * freed with g_free.
  *
  * Test whether the message translation is a valid format string if the message
  * is marked as being a format string.  
  **/
-const gchar *
+gchar *
 gtranslator_msg_check(GtranslatorMsg *msg)
 {
 	struct po_xerror_handler handler;
 	
 	g_return_val_if_fail(msg != NULL, NULL);
+	
+	/* We are not freeing the message_error so at start should be NULL
+	 * always for us
+	 */
+	message_error = NULL;
 
 	handler.xerror = &on_gettext_po_xerror;
 	handler.xerror2 = &on_gettext_po_xerror2;
 	
-	if(message_error != NULL)
-	{
-		g_free(message_error);
-		message_error = NULL;
-	}
-	
 	po_message_check_all(msg->priv->message, msg->priv->iterator, &handler);
 	
 	if(gtranslator_msg_is_fuzzy(msg) || !gtranslator_msg_is_translated(msg))
+	{
+		if (message_error)
+			g_free (message_error);
 		message_error = NULL;
+	}
 
 	/*Are there any other way to do this?*/
 	return message_error;

Modified: trunk/src/msg.h
==============================================================================
--- trunk/src/msg.h	(original)
+++ trunk/src/msg.h	Tue Sep 16 07:58:13 2008
@@ -76,7 +76,14 @@
 
 GType		  gtranslator_msg_register_type	       (GTypeModule * module);
 
-GtranslatorMsg   *gtranslator_msg_new                  (po_message_iterator_t iter);
+GtranslatorMsg   *gtranslator_msg_new                  (po_message_iterator_t iter,
+							po_message_t message);
+
+po_message_iterator_t
+                  gtranslator_msg_get_iterator         (GtranslatorMsg *msg);
+
+void              gtranslator_msg_set_iterator         (GtranslatorMsg *msg,
+							po_message_iterator_t iter);
 
 po_message_t      gtranslator_msg_get_message          (GtranslatorMsg *msg);
 
@@ -139,7 +146,7 @@
 
 const gchar      *gtranslator_msg_get_format           (GtranslatorMsg *msg);
 
-const gchar      *gtranslator_msg_check                (GtranslatorMsg *msg);
+gchar            *gtranslator_msg_check                (GtranslatorMsg *msg);
 
 G_END_DECLS
 

Modified: trunk/src/notebook.c
==============================================================================
--- trunk/src/notebook.c	(original)
+++ trunk/src/notebook.c	Tue Sep 16 07:58:13 2008
@@ -75,6 +75,8 @@
 	GtkWidget *ebox;
 	gchar *tooltip;
 	GtranslatorTab *tab;
+	GFile *location;
+	gchar *path;
 	
 	label = GTK_WIDGET (g_object_get_data (G_OBJECT (hbox), "label"));
 	ebox = GTK_WIDGET (g_object_get_data (G_OBJECT (hbox), "label-ebox"));
@@ -84,11 +86,17 @@
 	g_return_if_fail (str != NULL);
 	
 	gtk_label_set_text (GTK_LABEL (label), str);
-	
+
+	location = gtranslator_po_get_location (po);
+	path = g_file_get_path (location);
+	g_object_unref (location);
+
 	tooltip = g_strdup_printf (_("<b>Path:</b> %s"),
-				   gtranslator_po_get_filename (po));
+				   path);
+	
 	gtk_widget_set_tooltip_markup (ebox, tooltip);
 	
+	g_free (path);
 	g_free (tooltip);
 	g_free (str);
 }
@@ -195,6 +203,11 @@
 static void
 gtranslator_notebook_finalize (GObject *object)
 {
+	GtranslatorNotebook *notebook = GTR_NOTEBOOK (object);
+	
+	if (notebook->priv->pages)
+		g_list_free (notebook->priv->pages);
+	
 	G_OBJECT_CLASS (gtranslator_notebook_parent_class)->finalize (object);
 }
 
@@ -221,12 +234,26 @@
 
 /***************************** Public funcs ***********************************/
 
+/**
+ * gtranslator_notebook_new:
+ * 
+ * Creates a new #GtranslatorNotebook.
+ * 
+ * Returns: a new #GtranslatorNotebook object
+ */
 GtkWidget *
 gtranslator_notebook_new()
 {
 	return GTK_WIDGET(g_object_new(GTR_TYPE_NOTEBOOK, NULL));
 }
 
+/**
+ * gtranslator_notebook_add_page:
+ * @notebook: a #GtranslatorNotebook
+ * @tab: a #GtranslatorTab
+ * 
+ * Adds a new #GtranslatorTab to @notebook.
+ */
 void
 gtranslator_notebook_add_page (GtranslatorNotebook *notebook,
 			       GtranslatorTab *tab)
@@ -239,7 +266,7 @@
 	g_return_if_fail (GTR_IS_TAB (tab));
 	
 	po = gtranslator_tab_get_po (tab);
-	
+
 	label = build_tab_label (notebook, tab);
 
 	sync_name (po, NULL, label);
@@ -253,8 +280,48 @@
 	gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
 				  GTK_WIDGET (tab), label);
 	priv->pages = g_list_append (priv->pages, tab);
+	
+	if (g_list_length (notebook->priv->pages) == 1)
+		gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+	else
+		gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), TRUE);
 }
 
+/**
+ * gtranslator_notebook_remove_page:
+ * @notebook: a #GtranslatorNotebook
+ * @page_num: the index of a notebook page, starting from 0.
+ *
+ * Removes a page from the notebook given its index in the notebook.
+ */
+void
+gtranslator_notebook_remove_page (GtranslatorNotebook *notebook,
+				  gint page_num)
+{
+	GtkWidget *tab;
+	
+	g_return_if_fail (GTR_IS_NOTEBOOK (notebook));
+	
+	tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page_num);
+	
+	if (page_num != -1)
+		gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), page_num);
+	
+	notebook->priv->pages = g_list_remove (notebook->priv->pages,
+					       tab);
+	
+	if (g_list_length (notebook->priv->pages) == 1)
+		gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+}
+
+/**
+ * gtranslator_notebook_get_page:
+ * @notebook: a #GtranslatorNotebook
+ * 
+ * Gets the selected page in the #GtranslatorNotebook.
+ * 
+ * Returns: the selected page in the @notebook
+ */
 GtranslatorTab *
 gtranslator_notebook_get_page(GtranslatorNotebook *notebook)
 {
@@ -264,5 +331,3 @@
 	
 	return GTR_TAB(gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num));
 }
-
-

Modified: trunk/src/notebook.h
==============================================================================
--- trunk/src/notebook.h	(original)
+++ trunk/src/notebook.h	Tue Sep 16 07:58:13 2008
@@ -79,6 +79,9 @@
 void             gtranslator_notebook_add_page             (GtranslatorNotebook *notebook,
 							    GtranslatorTab *pax);
 
+void             gtranslator_notebook_remove_page          (GtranslatorNotebook *notebook,
+							    gint i);
+
 GtranslatorTab  *gtranslator_notebook_get_page             (GtranslatorNotebook *notebook);
 
 G_END_DECLS

Modified: trunk/src/plugin-system/module.c
==============================================================================
--- trunk/src/plugin-system/module.c	(original)
+++ trunk/src/plugin-system/module.c	Tue Sep 16 07:58:13 2008
@@ -33,77 +33,40 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: module.c 5367 2006-12-17 14:29:49Z pborelli $
+ * $Id: module.c 6314 2008-06-05 12:57:53Z pborelli $
  */
 
 #include "config.h"
 
 #include "module.h"
-//#include "gtranslator-debug.h"
-
-#include <gmodule.h>
-
-typedef struct _GtranslatorModuleClass GtranslatorModuleClass;
-
-struct _GtranslatorModuleClass
-{
-	GTypeModuleClass parent_class;
-};
-
-struct _GtranslatorModule
-{
-	GTypeModule parent_instance;
-
-	GModule *library;
-
-	gchar *path;
-	GType type;
-};
+#include "debug.h"
 
 typedef GType (*GtranslatorModuleRegisterFunc) (GTypeModule *);
 
-static void gtranslator_module_init		(GtranslatorModule *action);
-static void gtranslator_module_class_init	(GtranslatorModuleClass *class);
-
-static GObjectClass *parent_class = NULL;
-
-GType
-gtranslator_module_get_type (void)
-{
-	static GType type = 0;
-
-	if (G_UNLIKELY (type == 0))
-	{
-		static const GTypeInfo type_info =
-		{
-			sizeof (GtranslatorModuleClass),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) gtranslator_module_class_init,
-			(GClassFinalizeFunc) NULL,
-			NULL,
-			sizeof (GtranslatorModule),
-			0, /* n_preallocs */
-			(GInstanceInitFunc) gtranslator_module_init,
-		};
-
-		type = g_type_register_static (G_TYPE_TYPE_MODULE,
-					       "GtranslatorModule",
-					       &type_info, 0);
-	}
+enum {
+	PROP_0,
+	PROP_MODULE_NAME,
+	PROP_PATH
+};
 
-	return type;
-}
+G_DEFINE_TYPE (GtranslatorModule, gtranslator_module, G_TYPE_TYPE_MODULE);
 
 static gboolean
 gtranslator_module_load (GTypeModule *gmodule)
 {
 	GtranslatorModule *module = GTR_MODULE (gmodule);
 	GtranslatorModuleRegisterFunc register_func;
+	gchar *path;
+
+	DEBUG_PRINT ( "Loading %s module from %s",
+			     module->module_name, module->path);
 
-	g_message( "Loading %s", module->path);
+	path = g_module_build_path (module->path, module->module_name);
+	g_return_val_if_fail (path != NULL, FALSE);
+	DEBUG_PRINT ( "Module filename: %s", path);
 
-	module->library = g_module_open (module->path, 0);
+	module->library = g_module_open (path, 0);
+	g_free (path);
 
 	if (module->library == NULL)
 	{
@@ -136,7 +99,7 @@
 
 	if (module->type == 0)
 	{
-		g_warning ("Invalid gtranslator plugin contained by module %s", module->path);
+		g_warning ("Invalid gtranslator plugin contained by module %s", module->module_name);
 		return FALSE;
 	}
 
@@ -148,7 +111,7 @@
 {
 	GtranslatorModule *module = GTR_MODULE (gmodule);
 
-	g_message( "Unloading %s", module->path);
+	DEBUG_PRINT ( "Unloading %s", module->path);
 
 	g_module_close (module->library);
 
@@ -156,31 +119,16 @@
 	module->type = 0;
 }
 
-const gchar *
-gtranslator_module_get_path (GtranslatorModule *module)
-{
-	g_return_val_if_fail (GTR_IS_MODULE (module), NULL);
-
-	return module->path;
-}
-
-GObject *
-gtranslator_module_new_object (GtranslatorModule *module)
+static void
+gtranslator_module_class_real_garbage_collect (void)
 {
-	g_message( "Creating object of type %s", g_type_name (module->type));
-
-	if (module->type == 0)
-	{
-		return NULL;
-	}
-
-	return g_object_new (module->type, NULL);
+	/* Do nothing */
 }
 
 static void
 gtranslator_module_init (GtranslatorModule *module)
 {
-	g_message( "GtranslatorModule %p initialising", module);
+	DEBUG_PRINT ( "GtranslatorModule %p initialising", module);
 }
 
 static void
@@ -188,41 +136,123 @@
 {
 	GtranslatorModule *module = GTR_MODULE (object);
 
-	g_message( "GtranslatorModule %p finalising", module);
+	DEBUG_PRINT ( "GtranslatorModule %p finalising", module);
 
 	g_free (module->path);
+	g_free (module->module_name);
 
-	G_OBJECT_CLASS (parent_class)->finalize (object);
+	G_OBJECT_CLASS (gtranslator_module_parent_class)->finalize (object);
 }
 
 static void
-gtranslator_module_class_init (GtranslatorModuleClass *class)
+gtranslator_module_get_property (GObject    *object,
+			   guint       prop_id,
+			   GValue     *value,
+			   GParamSpec *pspec)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (class);
-	GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
+	GtranslatorModule *module = GTR_MODULE (object);
+
+	switch (prop_id)
+	{
+		case PROP_MODULE_NAME:
+			g_value_set_string (value, module->module_name);
+			break;
+		case PROP_PATH:
+			g_value_set_string (value, module->path);
+			break;
+		default:
+			g_return_if_reached ();
+	}
+}
 
-	parent_class = (GObjectClass *) g_type_class_peek_parent (class);
+static void
+gtranslator_module_set_property (GObject      *object,
+			   guint         prop_id,
+			   const GValue *value,
+			   GParamSpec   *pspec)
+{
+	GtranslatorModule *module = GTR_MODULE (object);
 
+	switch (prop_id)
+	{
+		case PROP_MODULE_NAME:
+			module->module_name = g_value_dup_string (value);
+			g_type_module_set_name (G_TYPE_MODULE (object),
+						module->module_name);
+			break;
+		case PROP_PATH:
+			module->path = g_value_dup_string (value);
+			break;
+		default:
+			g_return_if_reached ();
+	}
+}
+
+static void
+gtranslator_module_class_init (GtranslatorModuleClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
+
+	object_class->set_property = gtranslator_module_set_property;
+	object_class->get_property = gtranslator_module_get_property;
 	object_class->finalize = gtranslator_module_finalize;
 
 	module_class->load = gtranslator_module_load;
 	module_class->unload = gtranslator_module_unload;
+
+	klass->garbage_collect = gtranslator_module_class_real_garbage_collect;
+
+	g_object_class_install_property (object_class,
+					 PROP_MODULE_NAME,
+					 g_param_spec_string ("module-name",
+							      "Module Name",
+							      "The module to load for this plugin",
+							      NULL,
+							      G_PARAM_READWRITE |
+							      G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
+					 PROP_PATH,
+					 g_param_spec_string ("path",
+							      "Path",
+							      "The path to use when loading this module",
+							      NULL,
+							      G_PARAM_READWRITE |
+							      G_PARAM_CONSTRUCT_ONLY));
 }
 
-GtranslatorModule *
-gtranslator_module_new (const gchar *path)
+void
+gtranslator_module_class_garbage_collect (GtranslatorModuleClass *klass)
 {
-	GtranslatorModule *result;
+	g_return_if_fail (GTR_IS_MODULE_CLASS (klass));
 
-	if (path == NULL || path[0] == '\0')
-	{
-		return NULL;
-	}
+	GTR_MODULE_CLASS (klass)->garbage_collect ();
+}
+
+GObject *
+gtranslator_module_new_object (GtranslatorModule *module)
+{
+	g_return_val_if_fail (module->type != 0, NULL);
 
-	result = g_object_new (GTR_TYPE_MODULE, NULL);
+	DEBUG_PRINT ( "Creating object of type %s",
+			     g_type_name (module->type));
 
-	g_type_module_set_name (G_TYPE_MODULE (result), path);
-	result->path = g_strdup (path);
+	return g_object_new (module->type, NULL);
+}
+
+const gchar *
+gtranslator_module_get_path (GtranslatorModule *module)
+{
+	g_return_val_if_fail (GTR_IS_MODULE (module), NULL);
+
+	return module->path;
+}
+
+const gchar *
+gtranslator_module_get_module_name (GtranslatorModule *module)
+{
+	g_return_val_if_fail (GTR_IS_MODULE (module), NULL);
 
-	return result;
+	return module->module_name;
 }

Modified: trunk/src/plugin-system/module.h
==============================================================================
--- trunk/src/plugin-system/module.h	(original)
+++ trunk/src/plugin-system/module.h	Tue Sep 16 07:58:13 2008
@@ -33,13 +33,14 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: module.h 5263 2006-10-08 14:26:02Z pborelli $
+ * $Id: module.h 6263 2008-05-05 10:52:10Z sfre $
  */
  
-#ifndef GTR_MODULE_H
-#define GTR_MODULE_H
+#ifndef __GTR_MODULE_H__
+#define __GTR_MODULE_H__
 
 #include <glib-object.h>
+#include <gmodule.h>
 
 G_BEGIN_DECLS
 
@@ -47,19 +48,43 @@
 #define GTR_MODULE(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GTR_TYPE_MODULE, GtranslatorModule))
 #define GTR_MODULE_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GTR_TYPE_MODULE, GtranslatorModuleClass))
 #define GTR_IS_MODULE(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTR_TYPE_MODULE))
-#define GTR_IS_MODULE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((obj), GTR_TYPE_MODULE))
+#define GTR_IS_MODULE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_MODULE))
 #define GTR_MODULE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_MODULE, GtranslatorModuleClass))
 
-typedef struct _GtranslatorModule	GtranslatorModule;
+typedef struct _GtranslatorModule GtranslatorModule;
 
-GType		 gtranslator_module_get_type		(void) G_GNUC_CONST;
+struct _GtranslatorModule
+{
+	GTypeModule parent;
+
+	GModule *library;
+
+	gchar *path;
+	gchar *module_name;
+	GType type;
+};
+
+typedef struct _GtranslatorModuleClass GtranslatorModuleClass;
+
+struct _GtranslatorModuleClass
+{
+	GTypeModuleClass parent_class;
 
-GtranslatorModule	*gtranslator_module_new		(const gchar *path);
+	/* Virtual class methods */
+	void		 (* garbage_collect)	();
+};
+
+GType		 gtranslator_module_get_type		(void) G_GNUC_CONST;
 
 const gchar	*gtranslator_module_get_path		(GtranslatorModule *module);
 
+const gchar	*gtranslator_module_get_module_name	(GtranslatorModule *module);
+
 GObject		*gtranslator_module_new_object	(GtranslatorModule *module);
 
+void		 gtranslator_module_class_garbage_collect
+						(GtranslatorModuleClass *klass);
+
 G_END_DECLS
 
 #endif

Modified: trunk/src/plugin-system/plugin-info-priv.h
==============================================================================
--- trunk/src/plugin-system/plugin-info-priv.h	(original)
+++ trunk/src/plugin-system/plugin-info-priv.h	Tue Sep 16 07:58:13 2008
@@ -35,12 +35,6 @@
 #include "plugin-info.h"
 #include "plugin.h"
 
-typedef enum
-{
-	GTR_PLUGIN_LOADER_C,
-	GTR_PLUGIN_LOADER_PY,
-} GtranslatorPluginLoader;
-
 struct _GtranslatorPluginInfo
 {
 	gint               refcount;
@@ -48,8 +42,8 @@
 	gchar             *file;
 
 	gchar             *module_name;
-	GtranslatorPluginLoader  loader;
-	GTypeModule       *module;
+	GType              module_type;
+	GtranslatorModule       *module;
 	gchar            **dependencies;
 
 	gchar             *name;

Modified: trunk/src/plugin-system/plugin-info.c
==============================================================================
--- trunk/src/plugin-system/plugin-info.c	(original)
+++ trunk/src/plugin-system/plugin-info.c	Tue Sep 16 07:58:13 2008
@@ -39,9 +39,13 @@
 
 #include "plugin-info.h"
 #include "plugin-info-priv.h"
-//#include "gtranslator-debug.h"
+#include "debug.h"
 #include "plugin.h"
 
+#ifdef ENABLE_PYTHON
+#include "gtranslator-python-module.h"
+#endif
+
 void
 _gtranslator_plugin_info_ref (GtranslatorPluginInfo *info)
 {
@@ -63,7 +67,7 @@
 
 	if (info->plugin != NULL)
 	{
-		g_message( "Unref plugin %s", info->name);
+		DEBUG_PRINT ( "Unref plugin %s", info->name);
 
 		g_object_unref (info->plugin);
 		
@@ -123,7 +127,7 @@
 
 	g_return_val_if_fail (file != NULL, NULL);
 
-	g_message( "Loading plugin: %s", file);
+	DEBUG_PRINT ( "Loading plugin: %s", file);
 
 	info = g_new0 (GtranslatorPluginInfo, 1);
 	info->refcount = 1;
@@ -141,7 +145,7 @@
 				 "IAge",
 				 NULL))
 	{
-		g_message(
+		DEBUG_PRINT (
 				     "IAge key does not exist in file: %s", file);
 		goto error;
 	}
@@ -152,7 +156,7 @@
 				    "IAge",
 				    NULL) != 2)
 	{
-		g_message(
+		DEBUG_PRINT (
 				     "Wrong IAge in file: %s", file);
 		goto error;
 	}
@@ -181,7 +185,7 @@
 							 NULL);
 	if (info->dependencies == NULL)
 	{
-		g_message( "Could not find 'Depends' in %s", file);
+		DEBUG_PRINT ( "Could not find 'Depends' in %s", file);
 		info->dependencies = g_new0 (gchar *, 1);
 	}
 
@@ -192,16 +196,17 @@
 				     NULL);
 	if (str && strcmp(str, "python") == 0)
 	{
-		info->loader = GTR_PLUGIN_LOADER_PY;
 #ifndef ENABLE_PYTHON
 		g_warning ("Cannot load Python plugin '%s' since gtranslator was not "
 			   "compiled with Python support.", file);
 		goto error;
+#else
+		info->module_type = GTR_TYPE_PYTHON_MODULE;
 #endif
 	}
 	else
 	{
-		info->loader = GTR_PLUGIN_LOADER_C;
+		info->module_type = GTR_TYPE_MODULE;
 	}
 	g_free (str);
 
@@ -226,7 +231,7 @@
 	if (str)
 		info->desc = str;
 	else
-		g_message( "Could not find 'Description' in %s", file);
+		DEBUG_PRINT ( "Could not find 'Description' in %s", file);
 
 	/* Get Icon */
 	str = g_key_file_get_locale_string (plugin_file,
@@ -236,7 +241,7 @@
 	if (str)
 		info->icon_name = str;
 	else
-		g_message( "Could not find 'Icon' in %s, using 'plugin'", file);
+		DEBUG_PRINT ( "Could not find 'Icon' in %s, using 'plugin'", file);
 	
 
 	/* Get Authors */
@@ -246,7 +251,7 @@
 						    NULL,
 						    NULL);
 	if (info->authors == NULL)
-		g_message( "Could not find 'Authors' in %s", file);
+		DEBUG_PRINT ( "Could not find 'Authors' in %s", file);
 
 
 	/* Get Copyright */
@@ -257,7 +262,7 @@
 	if (str)
 		info->copyright = str;
 	else
-		g_message( "Could not find 'Copyright' in %s", file);
+		DEBUG_PRINT ( "Could not find 'Copyright' in %s", file);
 
 	/* Get Website */
 	str = g_key_file_get_string (plugin_file,
@@ -267,7 +272,7 @@
 	if (str)
 		info->website = str;
 	else
-		g_message( "Could not find 'Website' in %s", file);
+		DEBUG_PRINT ( "Could not find 'Website' in %s", file);
 		
 	g_key_file_free (plugin_file);
 	
@@ -306,7 +311,7 @@
 gboolean
 gtranslator_plugin_info_is_configurable (GtranslatorPluginInfo *info)
 {
-	g_message( "Is '%s' configurable?", info->name);
+	DEBUG_PRINT ( "Is '%s' configurable?", info->name);
 
 	g_return_val_if_fail (info != NULL, FALSE);
 

Modified: trunk/src/plugin-system/plugin-info.h
==============================================================================
--- trunk/src/plugin-system/plugin-info.h	(original)
+++ trunk/src/plugin-system/plugin-info.h	Tue Sep 16 07:58:13 2008
@@ -33,6 +33,7 @@
 #define __GTR_PLUGIN_INFO_H__
 
 #include <glib-object.h>
+#include "module.h"
 
 G_BEGIN_DECLS
 

Modified: trunk/src/plugin-system/plugin-manager.c
==============================================================================
--- trunk/src/plugin-system/plugin-manager.c	(original)
+++ trunk/src/plugin-system/plugin-manager.c	Tue Sep 16 07:58:13 2008
@@ -26,7 +26,7 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: plugin-manager.c 6079 2008-01-12 20:18:55Z sdeburca $
+ * $Id: plugin-manager.c 6406 2008-08-13 20:04:04Z pborelli $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -36,13 +36,12 @@
 #include <string.h>
 
 #include <glib/gi18n.h>
-#include <glade/glade-xml.h>
 
 #include "plugin-manager.h"
 #include "utils.h"
 #include "plugins-engine.h"
 #include "plugin.h"
-//#include "gtranslator-debug.h"
+#include "debug.h"
 
 enum
 {
@@ -104,7 +103,7 @@
 		gtk_widget_destroy (pm->priv->about);
 
 	pm->priv->about = g_object_new (GTK_TYPE_ABOUT_DIALOG,
-		"name", gtranslator_plugin_info_get_name (info),
+		"program-name", gtranslator_plugin_info_get_name (info),
 		"copyright", gtranslator_plugin_info_get_copyright (info),
 		"authors", gtranslator_plugin_info_get_authors (info),
 		"comments", gtranslator_plugin_info_get_description (info),
@@ -142,7 +141,7 @@
 
 	g_return_if_fail (info != NULL);
 
-	g_message( "Configuring: %s\n", 
+	DEBUG_PRINT ( "Configuring: %s\n", 
 			     gtranslator_plugin_info_get_name (info));
 
 	toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(pm)));
@@ -150,7 +149,7 @@
 	gtranslator_plugins_engine_configure_plugin (pm->priv->engine,
 					       info, toplevel);
 
-	g_message( "Done");	
+	DEBUG_PRINT ( "Done");	
 }
 
 static void
@@ -336,7 +335,7 @@
 	{
 		/* activate the plugin */
 		if (!gtranslator_plugins_engine_activate_plugin (pm->priv->engine, info)) {
-			g_message( "Could not activate %s.\n", 
+			DEBUG_PRINT ( "Could not activate %s.\n", 
 					     gtranslator_plugin_info_get_name (info));
 
 			res = FALSE;
@@ -346,7 +345,7 @@
 	{
 		/* deactivate the plugin */
 		if (!gtranslator_plugins_engine_deactivate_plugin (pm->priv->engine, info)) {
-			g_message( "Could not deactivate %s.\n", 
+			DEBUG_PRINT ( "Could not deactivate %s.\n", 
 					     gtranslator_plugin_info_get_name (info));
 
 			res = FALSE;

Modified: trunk/src/plugin-system/plugin.c
==============================================================================
--- trunk/src/plugin-system/plugin.c	(original)
+++ trunk/src/plugin-system/plugin.c	Tue Sep 16 07:58:13 2008
@@ -25,7 +25,7 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: plugin.c 4509 2006-01-06 16:45:20Z pborelli $
+ * $Id: plugin.c 6448 2008-08-25 10:28:33Z icq $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -72,6 +72,13 @@
 	/* Empty */
 }
 
+/**
+ * gtranslator_plugin_activate:
+ * @plugin: a #GtranslatorPlugin
+ * @window: a #GtranslatorWindow
+ * 
+ * Activates the plugin.
+ */
 void
 gtranslator_plugin_activate (GtranslatorPlugin *plugin,
 		       GtranslatorWindow *window)
@@ -82,6 +89,13 @@
 	GTR_PLUGIN_GET_CLASS (plugin)->activate (plugin, window);
 }
 
+/**
+ * gtranslator_plugin_deactivate:
+ * @plugin: a #GtranslatorPlugin
+ * @window: a #GtranslatorWindow
+ * 
+ * Deactivates the plugin.
+ */
 void
 gtranslator_plugin_deactivate	(GtranslatorPlugin *plugin,
 			 GtranslatorWindow *window)
@@ -91,7 +105,15 @@
 
 	GTR_PLUGIN_GET_CLASS (plugin)->deactivate (plugin, window);
 }
-				 
+
+/**
+ * gtranslator_plugin_update_ui:
+ * @plugin: a #GtranslatorPlugin
+ * @window: a #GtranslatorWindow
+ *
+ * Triggers an update of the user interface to take into account state changes
+ * caused by the plugin.
+ */		 
 void
 gtranslator_plugin_update_ui	(GtranslatorPlugin *plugin,
 			 GtranslatorWindow *window)
@@ -102,6 +124,14 @@
 	GTR_PLUGIN_GET_CLASS (plugin)->update_ui (plugin, window);
 }
 
+/**
+ * gtranslator_plugin_is_configurable:
+ * @plugin: a #GtranslatorPlugin
+ *
+ * Whether the plugin is configurable.
+ *
+ * Returns: TRUE if the plugin is configurable:
+ */
 gboolean
 gtranslator_plugin_is_configurable (GtranslatorPlugin *plugin)
 {
@@ -110,6 +140,14 @@
 	return GTR_PLUGIN_GET_CLASS (plugin)->is_configurable (plugin);
 }
 
+/**
+ * gtranslator_plugin_create_configure_dialog:
+ * @plugin: a #GtranslatorPlugin
+ *
+ * Creates the configure dialog widget for the plugin.
+ *
+ * Returns: the configure dialog widget for the plugin.
+ */
 GtkWidget *
 gtranslator_plugin_create_configure_dialog (GtranslatorPlugin *plugin)
 {

Modified: trunk/src/plugin-system/plugin.h
==============================================================================
--- trunk/src/plugin-system/plugin.h	(original)
+++ trunk/src/plugin-system/plugin.h	Tue Sep 16 07:58:13 2008
@@ -25,7 +25,7 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: plugin.h 5666 2007-06-29 19:52:25Z sfre $
+ * $Id: plugin.h 6448 2008-08-25 10:28:33Z icq $
  */
 
 #ifndef __GTR_PLUGIN_H__
@@ -34,7 +34,7 @@
 #include <glib-object.h>
 
 #include "window.h"
-//#include <gtranslator/gtranslator-debug.h>
+#include "debug.h"
 
 /* TODO: add a .h file that includes all the .h files normally needed to
  * develop a plugin */ 
@@ -112,10 +112,10 @@
 GtkWidget	*gtranslator_plugin_create_configure_dialog		
 						(GtranslatorPlugin *plugin);
 
-/*
- * Utility macro used to register plugins
+/**
+ * GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE):
  *
- * use: GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE)
+ * Utility macro used to register plugins with additional code.
  */
 #define GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE)	\
 										\
@@ -152,7 +152,7 @@
 		(GInstanceInitFunc) plugin_name##_init				\
 	};									\
 										\
-	g_message( "Registering " #PluginName);	\
+	DEBUG_PRINT ( "Registering " #PluginName);	\
 										\
 	/* Initialise the i18n stuff */						\
 	bindtextdomain (GETTEXT_PACKAGE, GTR_LOCALEDIR);			\
@@ -169,18 +169,18 @@
 	return plugin_name##_type;						\
 }
 
-/*
- * Utility macro used to register plugins
- *
- * use: GTR_PLUGIN_REGISTER_TYPE(PluginName, plugin_name)
+/**
+ * GTR_PLUGIN_REGISTER_TYPE(PluginName, plugin_name):
+ * 
+ * Utility macro used to register plugins.
  */
 #define GTR_PLUGIN_REGISTER_TYPE(PluginName, plugin_name)			\
 	GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, ;)
 
-/*
- * Utility macro used to register gobject types in plugins with additional code
+/**
+ * GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE):
  *
- * use: GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE)
+ * Utility macro used to register gobject types in plugins with additional code.
  */
 #define GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE)	\
 										\
@@ -217,7 +217,7 @@
 		(GInstanceInitFunc) object_name##_init				\
 	};									\
 										\
-	g_message( "Registering " #ObjectName);	\
+	DEBUG_PRINT ( "Registering " #ObjectName);	\
 										\
 	g_define_type_id = g_type_module_register_type (module,			\
 					   	        PARENT_TYPE,		\
@@ -230,10 +230,10 @@
 	return g_define_type_id;						\
 }
 
-/*
- * Utility macro used to register gobject types in plugins
+/**
+ * GTR_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE):
  *
- * use: GTR_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE)
+ * Utility macro used to register gobject types in plugins.
  */
 #define GTR_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE)		\
 	GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, ;)

Modified: trunk/src/plugin-system/plugins-engine.c
==============================================================================
--- trunk/src/plugin-system/plugins-engine.c	(original)
+++ trunk/src/plugin-system/plugins-engine.c	Tue Sep 16 07:58:13 2008
@@ -25,7 +25,7 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: plugins-engine.c 6052 2008-01-04 17:32:52Z sfre $
+ * $Id: plugins-engine.c 6376 2008-08-10 14:01:38Z pborelli $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -40,7 +40,7 @@
 #include "plugins-engine.h"
 #include "plugin-info-priv.h"
 #include "plugin.h"
-//#include "gtranslator-debug.h"
+#include "debug.h"
 #include "application.h"
 
 #include "module.h"
@@ -84,13 +84,6 @@
 static void	gtranslator_plugins_engine_deactivate_plugin_real (GtranslatorPluginsEngine *engine,
 							     GtranslatorPluginInfo    *info);
 
-static gint
-compare_plugin_info (GtranslatorPluginInfo *info1,
-		     GtranslatorPluginInfo *info2)
-{
-	return strcmp (info1->module_name, info2->module_name);
-}
-
 static void
 gtranslator_plugins_engine_load_dir (GtranslatorPluginsEngine *engine,
 			       const gchar        *dir,
@@ -103,7 +96,7 @@
 	g_return_if_fail (engine->priv->gconf_client != NULL);
 	g_return_if_fail (dir != NULL);
 
-	g_message( "DIR: %s", dir);
+	DEBUG_PRINT ( "DIR: %s", dir);
 
 	d = g_dir_open (dir, 0, &error);
 	if (!d)
@@ -129,9 +122,7 @@
 
 			/* If a plugin with this name has already been loaded
 			 * drop this one (user plugins override system plugins) */
-			if (g_list_find_custom (engine->priv->plugin_list,
-						info,
-						(GCompareFunc)compare_plugin_info) != NULL)
+			if (gtranslator_plugins_engine_get_plugin_info (engine, info->module_name) != NULL)
 			{
 				g_warning ("Two or more plugins named '%s'. "
 					   "Only the first will be considered.\n",
@@ -150,7 +141,7 @@
 
 			engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info);
 
-			g_message( "Plugin %s loaded", info->name);
+			DEBUG_PRINT ( "Plugin %s loaded", info->name);
 		}
 	}
 
@@ -160,7 +151,7 @@
 static void
 gtranslator_plugins_engine_load_all (GtranslatorPluginsEngine *engine)
 {
-	GSList *active_plugins;
+	GSList *active_plugins = NULL;
 	const gchar *home;
 	const gchar *pdirs_env;
 	gchar **pdirs;
@@ -196,13 +187,15 @@
 	if (pdirs_env == NULL)
 		pdirs_env = GTR_PLUGINDIR;
 
-	g_message( "GTR_PLUGINS_PATH=%s", pdirs_env);
+	DEBUG_PRINT ( "GTR_PLUGINS_PATH=%s", pdirs_env);
 	pdirs = g_strsplit (pdirs_env, G_SEARCHPATH_SEPARATOR_S, 0);
 
 	for (i = 0; pdirs[i] != NULL; i++)
 		gtranslator_plugins_engine_load_dir (engine, pdirs[i], active_plugins);
 
 	g_strfreev (pdirs);
+	g_slist_foreach (active_plugins, (GFunc) g_free, NULL);
+	g_slist_free (active_plugins);
 }
 
 static void
@@ -239,9 +232,15 @@
 void
 gtranslator_plugins_engine_garbage_collect (GtranslatorPluginsEngine *engine)
 {
-#ifdef ENABLE_PYTHON
-	gtranslator_python_garbage_collect ();
-#endif
+	GType *module_types = g_type_children (GTR_TYPE_MODULE, NULL);
+	unsigned i;
+	for (i = 0; module_types[i] != 0; i++)
+	{
+		gpointer klass = g_type_class_peek (module_types[i]);
+		if (klass != NULL)
+			gtranslator_module_class_garbage_collect (klass);
+	}
+	g_free (module_types);
 }
 
 static void
@@ -325,10 +324,26 @@
 	return engine->priv->plugin_list;
 }
 
+static gint
+compare_plugin_info_and_name (GtranslatorPluginInfo *info,
+			      const gchar *module_name)
+{
+	return strcmp (info->module_name, module_name);
+}
+
+GtranslatorPluginInfo *
+gtranslator_plugins_engine_get_plugin_info (GtranslatorPluginsEngine *engine,
+				      const gchar        *name)
+{
+	GList *l = g_list_find_custom (engine->priv->plugin_list,
+				       name,
+				       (GCompareFunc) compare_plugin_info_and_name);
+	return l == NULL ? NULL : (GtranslatorPluginInfo *) l->data;
+}
+
 static gboolean
 load_plugin_module (GtranslatorPluginInfo *info)
 {
-	gchar *path;
 	gchar *dirname;
 
 	//gtranslator_debug (DEBUG_PLUGINS);
@@ -338,107 +353,52 @@
 	g_return_val_if_fail (info->module_name != NULL, FALSE);
 	g_return_val_if_fail (info->plugin == NULL, FALSE);
 	g_return_val_if_fail (info->available, FALSE);
-	
-	switch (info->loader)
-	{
-		case GTR_PLUGIN_LOADER_C:
-			dirname = g_path_get_dirname (info->file);	
-			g_return_val_if_fail (dirname != NULL, FALSE);
-
-			path = g_module_build_path (dirname, info->module_name);
-			g_free (dirname);
-			g_return_val_if_fail (path != NULL, FALSE);
-	
-			info->module = G_TYPE_MODULE (gtranslator_module_new (path));
-			g_free (path);
-			
-			break;
+
+	dirname = g_path_get_dirname (info->file);
+	g_return_val_if_fail (dirname != NULL, FALSE);
 
 #ifdef ENABLE_PYTHON
-		case GTR_PLUGIN_LOADER_PY:
+	if (info->module_type == GTR_TYPE_PYTHON_MODULE)
+	{
+		if (!gtranslator_python_init ())
 		{
-			gchar *dir;
-			
-			if (!gtranslator_python_init ())
-			{
-				/* Mark plugin as unavailable and fails */
-				info->available = FALSE;
-				
-				g_warning ("Cannot load Python plugin '%s' since gtranslator "
-				           "was not able to initialize the Python interpreter.",
-				           info->name);
-
-				return FALSE;
-			}
-
-			dir = g_path_get_dirname (info->file);
-			
-			g_return_val_if_fail ((info->module_name != NULL) &&
-			                      (info->module_name[0] != '\0'),
-			                      FALSE);
-
-			info->module = G_TYPE_MODULE (
-					gtranslator_python_module_new (dir, info->module_name));
-					
-			g_free (dir);
-			break;
+			/* Mark plugin as unavailable and fail */
+			info->available = FALSE;
+			g_warning ("Cannot load Python plugin '%s' since gtranslator "
+			           "was not able to initialize the Python interpreter.",
+			           info->name);
 		}
-#endif
-		default:
-			g_return_val_if_reached (FALSE);
 	}
+#endif
 
-	if (!g_type_module_use (info->module))
-	{
-		switch (info->loader)
-		{
-			case GTR_PLUGIN_LOADER_C:
-				g_warning ("Cannot load plugin '%s' since file '%s' cannot be read.",
-					   info->name,			           
-					   gtranslator_module_get_path (GTR_MODULE (info->module)));
-				break;
-
-			case GTR_PLUGIN_LOADER_PY:
-				g_warning ("Cannot load Python plugin '%s' since file '%s' cannot be read.",
-					   info->name,			           
-					   info->module_name);
-				break;
+	info->module = GTR_MODULE (g_object_new (info->module_type,
+						   "path", dirname,
+						   "module-name", info->module_name,
+						   NULL));
+
+	g_free (dirname);
+
+	if (!g_type_module_use (G_TYPE_MODULE (info->module)))
+	{
+		g_warning ("Cannot load plugin '%s' since file '%s' cannot be read.",
+			   gtranslator_module_get_module_name (info->module),
+			   gtranslator_module_get_path (info->module));
 
-			default:
-				g_return_val_if_reached (FALSE);				
-		}
-			   
 		g_object_unref (G_OBJECT (info->module));
 		info->module = NULL;
 
-		/* Mark plugin as unavailable and fails */
+		/* Mark plugin as unavailable and fail. */
 		info->available = FALSE;
 		
 		return FALSE;
 	}
-	
-	switch (info->loader)
-	{
-		case GTR_PLUGIN_LOADER_C:
-			info->plugin = 
-				GTR_PLUGIN (gtranslator_module_new_object (GTR_MODULE (info->module)));
-			break;
 
-#ifdef ENABLE_PYTHON
-		case GTR_PLUGIN_LOADER_PY:
-			info->plugin = 
-				GTR_PLUGIN (gtranslator_python_module_new_object (GTR_PYTHON_MODULE (info->module)));
-			break;
-#endif
+	info->plugin = GTR_PLUGIN (gtranslator_module_new_object (info->module));
 
-		default:
-			g_return_val_if_reached (FALSE);
-	}
-	
-	g_type_module_unuse (info->module);
+	g_type_module_unuse (G_TYPE_MODULE (info->module));
+
+	DEBUG_PRINT ( "End");
 
-	g_message( "End");
-	
 	return TRUE;
 }
 
@@ -576,7 +536,7 @@
 		}
 	}
 	
-	g_message( "End");
+	DEBUG_PRINT ( "End");
 }
 
 void
@@ -601,7 +561,7 @@
 		if (!info->available || !info->active)
 			continue;
 			
-	       	g_message( "Updating UI of %s", info->name);
+	       	DEBUG_PRINT ( "Updating UI of %s", info->name);
 		
 		gtranslator_plugin_update_ui (info->plugin, window);
 	}

Modified: trunk/src/plugin-system/plugins-engine.h
==============================================================================
--- trunk/src/plugin-system/plugins-engine.h	(original)
+++ trunk/src/plugin-system/plugins-engine.h	Tue Sep 16 07:58:13 2008
@@ -25,7 +25,7 @@
  * list of people on the gtranslator Team.  
  * See the ChangeLog files for a list of changes. 
  *
- * $Id: plugins-engine.h 6045 2007-12-28 20:45:22Z sfre $
+ * $Id: plugins-engine.h 6264 2008-05-05 11:00:38Z sfre $
  */
 
 #ifndef __GTR_PLUGINS_ENGINE_H__
@@ -75,6 +75,9 @@
 
 const GList	*gtranslator_plugins_engine_get_plugin_list 	(GtranslatorPluginsEngine *engine);
 
+GtranslatorPluginInfo	*gtranslator_plugins_engine_get_plugin_info	(GtranslatorPluginsEngine *engine,
+							 const gchar        *name);
+
 gboolean 	 gtranslator_plugins_engine_activate_plugin 	(GtranslatorPluginsEngine *engine,
 							 GtranslatorPluginInfo    *info);
 gboolean 	 gtranslator_plugins_engine_deactivate_plugin	(GtranslatorPluginsEngine *engine,

Modified: trunk/src/plugin-system/update-from-gedit.sh
==============================================================================
--- trunk/src/plugin-system/update-from-gedit.sh	(original)
+++ trunk/src/plugin-system/update-from-gedit.sh	Tue Sep 16 07:58:13 2008
@@ -25,12 +25,13 @@
 	-e 's/gedit-plugin-info/plugin-info/g' \
 	-e 's/gedit-plugin/plugin/g' \
 	-e 's/gedit-panel.h/panel.h/g' \
+	-e 's/#include <gedit\/gedit-window.h>/#include "window.h"/g' \
 	-e 's/gedit-window.h/window.h/g' \
 	-e 's/gedit-utils.h/utils.h/g' \
-	-e 's/#include <gedit\/gedit-debug.h>/\/\/#include <gedit\/gedit-debug.h>/g' \
-	-e 's/#include "gedit-debug.h"/\/\/#include "gedit-debug.h"/g' \
+	-e 's/#include <gedit\/gedit-debug.h>/#include "debug.h"/g' \
+	-e 's/#include "gedit-debug.h"/#include "debug.h"/g' \
 	-e 's/#include "gedit-app.h"/#include "application.h"/g' \
-	-e 's/gedit_debug_message (DEBUG_PLUGINS,/g_warning(/g' \
+	-e 's/gedit_debug_message (DEBUG_PLUGINS,/DEBUG_PRINT (/g' \
 	-e 's/gedit_debug/\/\/gedit_debug/g' \
 	-e 's/gedit_app/gtranslator_application/g' \
 	-e 's/.gnome2\/gedit\/plugins\//.gtranslator\/plugins\//g' \

Modified: trunk/src/po.c
==============================================================================
--- trunk/src/po.c	(original)
+++ trunk/src/po.c	Tue Sep 16 07:58:13 2008
@@ -24,10 +24,15 @@
 #include <config.h>
 #endif
 
+#include "application.h"
+#include "debug.h"
 #include "file-dialogs.h"
 #include "po.h"
 #include "msg.h"
 #include "gtranslator-enum-types.h"
+#include "prefs-manager.h"
+#include "profile.h"
+#include "utils.h"
 
 #include <string.h>
 #include <errno.h>
@@ -37,6 +42,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <gettext-po.h>
+#include <gio/gio.h>
 
 #define GTR_PO_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
 					 (object),	\
@@ -48,10 +54,7 @@
 
 struct _GtranslatorPoPrivate
 {
-	/*
-	 * Absolute file name
-	 */
-	gchar *filename;
+	GFile *location;
 	
 	/*
 	 * Gettext's file handle
@@ -175,6 +178,9 @@
 gtranslator_po_init (GtranslatorPo *po)
 {
 	po->priv = GTR_PO_GET_PRIVATE (po);
+	
+	po->priv->location = NULL;
+	po->priv->gettext_po_file = NULL;
 }
 
 static void
@@ -192,7 +198,8 @@
 		g_list_free (po->priv->domains);
 	}
 
-	g_free (po->priv->filename);
+	if (po->priv->location)
+		g_object_unref (po->priv->location);
 	g_free (po->priv->obsolete);
 
 	if (po->priv->gettext_po_file)
@@ -254,12 +261,32 @@
 	message_error = g_strdup_printf("%s.\n %s",message_text1, message_text2);
 }
 
+static gboolean
+po_file_is_empty (po_file_t file)
+{
+	const gchar * const * domains = po_file_domains (file);
+	
+	for (; *domains != NULL; domains++) 
+	{
+		po_message_iterator_t iter = po_message_iterator (file, *domains);
+		if (po_next_message (iter) != NULL)
+		{
+			po_message_iterator_free (iter);
+			return FALSE;
+		}
+		po_message_iterator_free (iter);
+	}
+	return TRUE;
+}
+
 /***************************** Public funcs ***********************************/
 
 /**
  * gtranslator_po_new:
  *
- * Return value: a new #GtranslatorPo object
+ * Creates a new #GtranslatorPo.
+ *
+ * Returns: a new #GtranslatorPo object
  **/
 GtranslatorPo *
 gtranslator_po_new(void)
@@ -274,17 +301,19 @@
 /**
  * gtranslator_po_parse:
  * @po: a #GtranslatorPo
- * @filename: the filename path to open
+ * @location: the file to open
  * @error: a variable to store the errors
  *
- * 
+ * Parses all things related to the #GtranslatorPo and initilizes all neccessary
+ * variables.
  **/
 void
-gtranslator_po_parse(GtranslatorPo *po,
-		     const gchar *filename,
-		     GError **error)
+gtranslator_po_parse (GtranslatorPo *po,
+		      GFile *location,
+		      GError **error)
 {
 	GtranslatorPoPrivate *priv = po->priv;
+	gchar *filename;
 	GtranslatorMsg *msg;
 	struct po_xerror_handler handler;
 	po_message_t message;
@@ -295,12 +324,8 @@
 	gint i = 0;
 	gint pos = 1;
 	
-	g_return_if_fail(filename!=NULL);
-	g_return_if_fail(GTR_IS_PO(po));
-
-	base=g_path_get_basename(filename);
-	g_return_if_fail(base[0]!='\0');
-	g_free(base);
+	g_return_if_fail (GTR_IS_PO (po));
+	g_return_if_fail (location != NULL);
 	
 	/*
 	 * Initialice the handler error.
@@ -315,25 +340,28 @@
 	}
 
 	/*
-	 * Get absolute filename.
+	 * Get filename path.
 	 */
-	if (!g_path_is_absolute(filename)) 
-		priv->filename = g_build_filename(filename);
-	else
-		priv->filename = g_strdup(filename);
-	
-	priv->gettext_po_file = po_file_read(priv->filename,
-					     &handler);
-	if(priv->gettext_po_file == NULL)
+	po->priv->location = g_file_dup (location);
+	filename = g_file_get_path (location);
+	
+	if (po->priv->gettext_po_file)
+		po_file_free (po->priv->gettext_po_file);
+	
+	priv->gettext_po_file = po_file_read (filename,
+					      &handler);
+	if (priv->gettext_po_file == NULL)
 	{
-		g_set_error(error,
-			    GTR_PO_ERROR,
-			    GTR_PO_ERROR_FILENAME,
-			    _("Failed opening file '%s': %s"),
-			    priv->filename, g_strerror(errno));
+		g_set_error (error,
+			     GTR_PO_ERROR,
+			     GTR_PO_ERROR_FILENAME,
+			     _("Failed opening file '%s': %s"),
+			     filename, g_strerror (errno));
 		g_object_unref(po);
+		g_free (filename);
 		return;
 	}
+	g_free (filename);
 	
 	/*
 	 * No need to return; this can be corrected by the user
@@ -342,7 +370,17 @@
 		g_set_error(error,
 			    GTR_PO_ERROR,
 			    GTR_PO_ERROR_RECOVERY,
-			    message_error);
+			    "%s", message_error);
+	}
+	
+	if (po_file_is_empty (priv->gettext_po_file))
+	{
+		g_set_error (error,
+			     GTR_PO_ERROR,
+			     GTR_PO_ERROR_FILE_EMPTY,
+			     _("The file is empty"));
+		g_object_unref(po);
+		return;
 	}
 	
 	/*
@@ -482,15 +520,7 @@
 		if (!po_message_is_obsolete (message))
 		{
 			/* Unpack into a GtrMsg */
-			msg = gtranslator_msg_new (iter);
-			gtranslator_msg_set_message (msg, message);
-  
-			/* Set the status */
-			if (gtranslator_msg_is_fuzzy (msg))
-				gtranslator_msg_set_status (msg, GTR_MSG_STATUS_FUZZY);
-			else if (gtranslator_msg_is_translated (msg))
-				gtranslator_msg_set_status (msg, GTR_MSG_STATUS_TRANSLATED);
-			else gtranslator_msg_set_status (msg, GTR_MSG_STATUS_UNTRANSLATED);
+			msg = gtranslator_msg_new (iter, message);
 
 			/* Set position in PO file */
 			gtranslator_msg_set_po_position (msg, pos++);
@@ -540,11 +570,30 @@
 		   *header_comment;
 	const char *prev_translator;
 
-	time_t now;
-	struct tm *now_here;
-	char t[22];
-	gchar *year=g_malloc(5);
+	gchar *current_date;
+	gchar *current_time;
+	gchar *year;
+	gchar *new_date;
 	gchar *aux;
+	gchar *aux2;
+	const gchar *comments;
+	gchar **comments_lines;
+	gchar **comments_translator_values;
+
+	gboolean take_my_options;
+
+	gint i = 0;
+	gint j;
+	gint k = 0;
+	gint l;
+
+	gchar *new_comments = "";
+	gchar *old_line;
+	gchar *line = "";
+	gchar *comp_year;
+	gchar *line_without_dot;
+
+	take_my_options = gtranslator_prefs_manager_get_take_my_options ();
 
 	/*
 	 * Get header's fields
@@ -568,35 +617,102 @@
 	msgstr = po_message_msgstr(message);
 
 	/*
+	 * If button take_my_options is pulsed, then header's values
+	 * should be taking from default profile
+	 */
+
+	if (take_my_options) {
+
+	  GtranslatorProfile *active_profile;
+
+	  active_profile = gtranslator_application_get_active_profile (GTR_APP);
+   
+	  gtranslator_header_set_translator (header, gtranslator_profile_get_author_name (active_profile));
+	  gtranslator_header_set_tr_email (header, gtranslator_profile_get_author_email (active_profile));
+	  gtranslator_header_set_language (header, gtranslator_profile_get_language_name (active_profile));
+	  gtranslator_header_set_charset (header, gtranslator_profile_get_charset (active_profile));
+	  gtranslator_header_set_encoding (header, gtranslator_profile_get_encoding (active_profile));
+	  gtranslator_header_set_lg_email (header, gtranslator_profile_get_group_email (active_profile));
+	  gtranslator_header_set_plural_forms (header, gtranslator_profile_get_plurals (active_profile));
+	}
+
+	/*
 	 * Update the po date 
 	 */
-	now = time(NULL);
-	now_here = localtime(&now);
-	strftime(t, 22, "%Y-%m-%d %H:%M%z", now_here);
-	strftime(year, 5, "%Y", now_here);
-	
-	aux = g_strdup (t);
-	gtranslator_header_set_po_date (header, aux);
-	g_free (aux);
-	
+	current_date = gtranslator_utils_get_current_date ();
+	current_time = gtranslator_utils_get_current_time ();
+	year = gtranslator_utils_get_current_year ();
+
+	new_date = g_strconcat (current_date, " ", current_time, NULL);
+
+	gtranslator_header_set_po_date (header, new_date);
+
+	g_free (new_date);
+
 	/*
          * Update the header's comment
          */
-        aux = g_strconcat(gtranslator_header_get_translator(header), " ", "<", 
+	comments = po_message_comments (message);
+	comments_lines = g_strsplit (comments, "\n", -1);
+	
+	/*
+	 * Searching if the current translator is in comments.
+	 */
+	while (comments_lines[i] != NULL) {
+	  if (g_str_has_prefix (comments_lines[i], prev_translator)) {
+	    comments_translator_values = g_strsplit (comments_lines[i], ",", -1);
+	    j = i;
+	  }
+	  i++;
+	}
+	aux = g_strconcat(gtranslator_header_get_translator(header), " ", "<",
 			  gtranslator_header_get_tr_email(header), ">", NULL);
-	if (strcmp(prev_translator, aux))
-	{
-		gchar *aux2;
-		
-		header_comment = po_message_comments (message);
-		aux2 = g_strconcat(header_comment, gtranslator_header_get_translator(header), " ", "<",
-				   gtranslator_header_get_tr_email(header), ">", ",", " ", year, NULL);
-		
-		po_message_set_comments (message, aux2);
-		g_free (aux2);
+	
+	comp_year = g_strconcat (" ", year, ".", NULL);
+
+	/*
+	 * Current translator is already in comments but its last year < current year.
+	 */
+	if ((g_utf8_collate (prev_translator, aux) == 0) && 
+	    (g_utf8_collate (comments_translator_values[g_strv_length (comments_translator_values)-1], comp_year) != 0)) {
+	  
+	  if (g_str_has_suffix (comments_lines[j], ".")) {
+	    line_without_dot = g_strndup (comments_lines[j], g_utf8_strlen(comments_lines[j], -1) -1);  
+	    line = g_strconcat (line_without_dot, ", ", year, ".", NULL);
+	    g_free (line_without_dot);
+	  }else {
+	    line = g_strconcat (comments_lines[j], ", ", year, ".", NULL);
+	  }
+	  
+	  for (l=j; l<(g_strv_length (comments_lines)); l++) {
+	    comments_lines[l] = comments_lines[l+1];
+	  }
+	  
+	  comments_lines[g_strv_length (comments_lines)-1] = line;
+	  while (comments_lines[k] != NULL) {
+	    new_comments = g_strconcat (new_comments, comments_lines[k], "\n", NULL);
+	    k++;
+	    }
+	  po_message_set_comments (message, new_comments);
+	  
+	  g_free (line);
+	  g_free (new_comments);
+	}    
+
+	/*
+	 * Current translator is not in the comments.
+	 */
+	if (g_utf8_collate (prev_translator, aux) != 0) {
+	  
+	  header_comment = po_message_comments (message);
+	  aux2 = g_strconcat(header_comment, gtranslator_header_get_translator(header), " ", "<",
+			     gtranslator_header_get_tr_email(header), ">", ",", " ", year, ".", NULL);
+	  
+	  po_message_set_comments (message, aux2);
+	  g_free (aux2);
 	}
 	g_free (aux);
-
+	
 	/*
          * Write the header's fields
          */
@@ -615,7 +731,7 @@
 	msgstr = po_header_set_field (msgstr, "Language-Team", aux);
 	g_free (aux);
 	
-	aux = g_strconcat(" text/plain;", " charset=",
+	aux = g_strconcat("text/plain;", " charset=",
 			  gtranslator_header_get_charset(header),NULL);
 	msgstr = po_header_set_field (msgstr, "Content-Type", aux);
 	g_free (aux);
@@ -638,6 +754,8 @@
 			 GError **error)
 {
 	struct po_xerror_handler handler;
+	gchar *msg_error;
+	gchar *filename;
 	
 	/*
 	 * Initialice the handler error.
@@ -645,7 +763,9 @@
 	handler.xerror = &on_gettext_po_xerror;
 	handler.xerror2 = &on_gettext_po_xerror2;
 	
-	if (g_str_has_suffix(po->priv->filename, ".pot"))
+	filename = g_file_get_path (po->priv->location);
+	
+	if (g_str_has_suffix (filename, ".pot"))
 	{
 		g_set_error (error,
 			     GTR_PO_ERROR,
@@ -653,25 +773,47 @@
 			     _("You are saving a file with a .pot extension.\n"
 			     "Pot files are generated by the compilation process.\n"
 			     "Your file should likely be named '%s.po'."), 
-			     po->priv->filename);
+			     filename);
+		g_free (filename);
 		return;
 	}
 	
 	/*
+	 * Check if the file is right
+	 */
+	/*msg_error = gtranslator_po_check_po_file (po);
+	if (msg_error != NULL)
+	{
+		g_set_error (error,
+			     GTR_PO_ERROR,
+			     GTR_PO_ERROR_GETTEXT,
+			     _("There is an error in the PO file: %s"),
+			     msg_error);
+		g_free (msg_error);
+	}*/
+	
+	
+	/*
 	 * Save header fields into msg
 	 */
 	gtranslator_po_save_header_in_msg (po);	
 	
 	if (!po_file_write (gtranslator_po_get_po_file (po),
-			    po->priv->filename, &handler))
+			    filename, &handler))
 	{
 		g_set_error (error,
 			     GTR_PO_ERROR,
 			     GTR_PO_ERROR_FILENAME,
 			     _("There was an error writing the PO file: %s"),
 			     message_error);
+		g_free (message_error);
+		g_free (filename);
 		return;
 	}
+	g_free (filename);
+	
+	/* If we are here everything is ok and we can set the state as saved */
+	gtranslator_po_set_state (po, GTR_PO_STATE_SAVED);
 	
 	/*
 	 * If the warn if fuzzy option is enabled we have to show an error
@@ -692,31 +834,36 @@
  * gtranslator_po_get_filename:
  * @po: a #GtranslatorPo
  * 
- * Return value: the file name string
+ * Gets the GFile of the po file.
+ * 
+ * Returns: the GFile associated with the @po. The returned location must be freed
+ * with g_object_unref.
  **/
-const gchar *
-gtranslator_po_get_filename(GtranslatorPo *po)
+GFile *
+gtranslator_po_get_location (GtranslatorPo *po)
 {
-	return po->priv->filename;
+	g_return_val_if_fail (GTR_IS_PO (po), NULL);
+	
+	return g_file_dup (po->priv->location);
 }
 
 /**
- * gtranslator_po_set_filename:
+ * gtranslator_po_set_location:
  * @po: a #GtranslatorPo
- * @data: The file name text you want to set
+ * @location: The GFile to set to the #GtranslatorPo
  *
- * Sets the text path within the #GtranslatorPo object. It overwrites any text
- * that was there before.
+ * Sets the GFile location within the #GtranslatorPo object.
  **/
 void
-gtranslator_po_set_filename(GtranslatorPo *po,
-			    gchar *data)
+gtranslator_po_set_location (GtranslatorPo *po,
+			     GFile *location)
 {
 	g_return_if_fail(GTR_IS_PO(po));
 	
-	if(po->priv->filename)
-		g_free(po->priv->filename);
-	po->priv->filename = g_strdup(data);
+	if (po->priv->location)
+		g_object_unref (po->priv->location);
+	
+	po->priv->location = g_file_dup (location);
 }
 
 /**
@@ -925,6 +1072,68 @@
 }
 
 /**
+ * gtranslator_po_get_next_fuzzy_or_untrans:
+ * @po: a #GtranslatorPo
+ *
+ * Return value: a pointer to the next fuzzy or untranslated message
+ * or NULL if there is not next fuzzy or untranslated message.
+ **/
+GList *
+gtranslator_po_get_next_fuzzy_or_untrans (GtranslatorPo *po)
+{
+	GList *msg;
+	
+	msg = po->priv->current;
+	while (msg = g_list_next (msg))
+	{
+		if (gtranslator_msg_is_fuzzy (msg->data) ||
+		    !gtranslator_msg_is_translated (msg->data))
+			return msg;
+	}
+	
+	return NULL;
+}
+
+/**
+ * gtranslator_po_get_prev_fuzzy_or_untrans:
+ * @po: a #GtranslatorPo
+ *
+ * Return value: a pointer to the previously fuzzy or untranslated message
+ * or NULL if there is not previously fuzzy or untranslated message.
+ **/
+GList *
+gtranslator_po_get_prev_fuzzy_or_untrans (GtranslatorPo *po)
+{
+	GList *msg;
+	
+	msg = po->priv->current;
+	while (msg = g_list_previous (msg))
+	{
+		if (gtranslator_msg_is_fuzzy (msg->data) ||
+		    !gtranslator_msg_is_translated (msg->data))
+			return msg;
+	}
+	
+	return NULL;
+}
+
+/**
+ * gtranslator_po_get_msg_from_number:
+ * @po: a #GtranslatorPo
+ * @number: the message to jump
+ *
+ * Gets the message at the given position.
+ */
+GList *
+gtranslator_po_get_msg_from_number (GtranslatorPo *po,
+				    gint number)
+{
+	g_return_val_if_fail (GTR_IS_PO (po), NULL);
+	
+	return g_list_nth (po->priv->messages, number);
+}
+
+/**
  * gtranslator_po_get_header:
  * @po: a #GtranslatorPo
  *
@@ -1009,6 +1218,9 @@
 {
 	g_return_val_if_fail (GTR_IS_PO (po), -1);
 	
+	/*DEBUG_PRINT ("length: %d | translated: %d | fuzzy: %d | untranslated: %d", g_list_length (po->priv->messages),
+		     po->priv->translated, po->priv->fuzzy, (g_list_length (po->priv->messages) - po->priv->translated - po->priv->fuzzy));*/
+	
 	return (g_list_length (po->priv->messages) - po->priv->translated - po->priv->fuzzy);
 }
 
@@ -1045,9 +1257,10 @@
  * @po: a #GtranslatorPo
  *
  * Test whether an entire PO file is valid, like msgfmt does it.
- * Return value: If it is invalid, returns the error.
+ * Returns: If it is invalid, returns the error. The return value must be freed
+ * with g_free.
  **/
-const gchar *
+gchar *
 gtranslator_po_check_po_file (GtranslatorPo *po)
 {
 	struct po_xerror_handler handler;
@@ -1056,12 +1269,7 @@
 
 	handler.xerror = &on_gettext_po_xerror;
 	handler.xerror2 = &on_gettext_po_xerror2;
-	
-	if (message_error != NULL)
-	{
-		g_free (message_error);
-		message_error = NULL;
-	}
+	message_error = NULL;
 	
 	po_file_check_all (po->priv->gettext_po_file, &handler);
 

Modified: trunk/src/po.h
==============================================================================
--- trunk/src/po.h	(original)
+++ trunk/src/po.h	Tue Sep 16 07:58:13 2008
@@ -23,6 +23,7 @@
 #include <glib-object.h>
 #include <gtk/gtk.h>
 #include <gettext-po.h>
+#include <gio/gio.h>
 
 #include "header.h"
 
@@ -71,6 +72,7 @@
 	GTR_PO_ERROR_GETTEXT,
 	GTR_PO_ERROR_FILENAME,
 	GTR_PO_ERROR_RECOVERY,
+	GTR_PO_ERROR_FILE_EMPTY,
 	GTR_PO_ERROR_OTHER,
 };
 
@@ -92,8 +94,8 @@
 GtranslatorPo	*gtranslator_po_new			(void);
 
 void		gtranslator_po_parse			(GtranslatorPo *po,
-							const gchar *filename,
-							GError **error);
+							 GFile *filename,
+							 GError **error);
 
 void		gtranslator_po_save_header_in_msg	(GtranslatorPo *po);
 
@@ -105,10 +107,10 @@
 void            gtranslator_po_set_state                (GtranslatorPo *po,
 							 GtranslatorPoState state);
 
-const gchar    *gtranslator_po_get_filename		(GtranslatorPo *po);
+GFile          *gtranslator_po_get_location             (GtranslatorPo *po);
 
-void            gtranslator_po_set_filename		(GtranslatorPo *po,
-							gchar *data);
+void            gtranslator_po_set_location		(GtranslatorPo *po,
+							 GFile *location);
 
 gboolean         gtranslator_po_get_write_perms		(GtranslatorPo *po);
 
@@ -131,6 +133,13 @@
 
 GList           *gtranslator_po_get_prev_untrans	(GtranslatorPo *po);
 
+GList           *gtranslator_po_get_next_fuzzy_or_untrans (GtranslatorPo *po);
+
+GList           *gtranslator_po_get_prev_fuzzy_or_untrans (GtranslatorPo *po);
+
+GList           *gtranslator_po_get_msg_from_number     (GtranslatorPo *po,
+							 gint number);
+
 GtranslatorHeader  
 		*gtranslator_po_get_header		(GtranslatorPo *po);
 
@@ -144,7 +153,7 @@
 
 gint             gtranslator_po_get_message_position	(GtranslatorPo *po);
 
-const gchar     *gtranslator_po_check_po_file		(GtranslatorPo *po);
+gchar           *gtranslator_po_check_po_file		(GtranslatorPo *po);
 
 /* Unexported funcs */
 void            _gtranslator_po_increase_decrease_translated

Modified: trunk/src/prefs-manager-app.c
==============================================================================
--- trunk/src/prefs-manager-app.c	(original)
+++ trunk/src/prefs-manager-app.c	Tue Sep 16 07:58:13 2008
@@ -63,6 +63,15 @@
 							GConfEntry  *entry, 
 							gpointer     user_data);
 
+static void gtranslator_prefs_manager_autosave_changed (GConfClient *client,
+							guint        cnxn_id,
+							GConfEntry  *entry,
+							gpointer     user_data);
+
+static void gtranslator_prefs_manager_scheme_color_changed (GConfClient *client,
+							    guint        cnxn_id, 
+							    GConfEntry  *entry, 
+							    gpointer     user_data);
 
 /* GUI state is serialized to a .desktop file, not in gconf */
 
@@ -435,7 +444,16 @@
 				GPM_GDL_STYLE,
 				gtranslator_prefs_manager_gdl_style_changed,
 				NULL, NULL, NULL);
+
+		gconf_client_notify_add (gtranslator_prefs_manager->gconf_client,
+					 GPM_AUTOSAVE,
+					 gtranslator_prefs_manager_autosave_changed,
+					 NULL, NULL, NULL);
 		
+		gconf_client_notify_add (gtranslator_prefs_manager->gconf_client,
+					 GPM_SCHEME_COLOR,
+					 gtranslator_prefs_manager_scheme_color_changed,
+					 NULL, NULL, NULL);
 	}
 
 	return gtranslator_prefs_manager != NULL;	
@@ -622,3 +640,80 @@
 		      "switcher-style", style, NULL);
 }
 
+static void
+gtranslator_prefs_manager_autosave_changed (GConfClient *client,
+					    guint        cnxn_id,
+					    GConfEntry  *entry,
+					    gpointer     user_data)
+{
+	GList *tabs;
+	GList *l;
+	GtranslatorWindow *window;
+
+	g_return_if_fail (entry->key != NULL);
+	g_return_if_fail (entry->value != NULL);
+
+	window = gtranslator_application_get_active_window (GTR_APP);
+
+	if (strcmp (entry->key, GPM_AUTOSAVE) == 0)
+	{
+		gboolean autosave;
+
+		if (entry->value->type == GCONF_VALUE_BOOL)
+			autosave = gconf_value_get_bool (entry->value);
+		else
+			autosave = GPM_DEFAULT_AUTOSAVE;
+
+		tabs = gtranslator_window_get_all_tabs (window);
+
+		for (l = tabs; l != NULL; l = g_list_next (l))
+		{
+			GtranslatorTab *tab = GTR_TAB (l->data);
+
+			gtranslator_tab_set_autosave_enabled (tab, autosave);
+		}
+
+		g_list_free (tabs);
+	}
+	else if (strcmp (entry->key,  GPM_AUTOSAVE_INTERVAL) == 0)
+	{
+		gint autosave_interval;
+
+		if (entry->value->type == GCONF_VALUE_INT)
+		{
+			autosave_interval = gconf_value_get_int (entry->value);
+
+			if (autosave_interval <= 0)
+				autosave_interval = GPM_DEFAULT_AUTOSAVE_INTERVAL;
+		}
+		else
+			autosave_interval = GPM_DEFAULT_AUTOSAVE_INTERVAL;
+
+		tabs = gtranslator_window_get_all_tabs (window);
+
+		for (l = tabs; l != NULL; l = g_list_next (l))
+		{
+			GtranslatorTab *tab = GTR_TAB (l->data);
+
+			gtranslator_tab_set_autosave_interval (tab, autosave_interval);
+		}
+
+		g_list_free (tabs);
+	}
+}
+
+static void
+gtranslator_prefs_manager_scheme_color_changed (GConfClient *client,
+						guint        cnxn_id, 
+						GConfEntry  *entry, 
+						gpointer     user_data)
+{
+	GList *views, *l;
+	
+	views = gtranslator_application_get_views (GTR_APP, TRUE, TRUE);
+	
+	for (l = views; l != NULL; l = g_list_next (l))
+	{
+		gtranslator_view_reload_scheme_color (GTR_VIEW (l->data));
+	}
+}

Modified: trunk/src/prefs-manager.c
==============================================================================
--- trunk/src/prefs-manager.c	(original)
+++ trunk/src/prefs-manager.c	Tue Sep 16 07:58:13 2008
@@ -278,13 +278,9 @@
 		GPM_AUTOSAVE_INTERVAL,
 		GPM_DEFAULT_AUTOSAVE_INTERVAL)
 
-DEFINE_BOOL_PREF(append_suffix,
-		 GPM_APPEND_SUFFIX,
-		 GPM_DEFAULT_APPEND_SUFFIX)
-
-DEFINE_STRING_PREF(autosave_suffix,
-		   GPM_AUTOSAVE_SUFFIX,
-		   GPM_DEFAULT_AUTOSAVE_SUFFIX)
+DEFINE_BOOL_PREF(create_backup,
+		 GPM_CREATE_BACKUP,
+		 GPM_DEFAULT_CREATE_BACKUP)
 
 /* Editor */
 DEFINE_BOOL_PREF(highlight,
@@ -307,10 +303,6 @@
 		 GPM_UNMARK_FUZZY,
 		 GPM_DEFAULT_UNMARK_FUZZY)
 
-DEFINE_BOOL_PREF(keep_obsolete,
-		 GPM_KEEP_OBSOLETE,
-		 GPM_DEFAULT_KEEP_OBSOLETE)
-
 DEFINE_BOOL_PREF(spellcheck,
 		 GPM_SPELLCHECK,
 		 GPM_DEFAULT_SPELLCHECK)
@@ -333,6 +325,35 @@
 		 GPM_GDL_STYLE,
 		 GPM_DEFAULT_GDL_STYLE)
 
+DEFINE_STRING_PREF (scheme_color,
+		    GPM_SCHEME_COLOR,
+		    GPM_DEFAULT_SCHEME_COLOR)
+
+/* Translation Memory */
+DEFINE_STRING_PREF (tm_dir,
+		    GPM_TM_DIR,
+		    GPM_DEFAULT_TM_DIR)
+
+DEFINE_INT_PREF (use_lang_profile,
+		    GPM_TM_USE_LANG_PROFILE,
+		    GPM_DEFAULT_TM_USE_LANG_PROFILE)
+
+DEFINE_STRING_PREF (tm_lang_entry,
+		    GPM_TM_LANG_ENTRY,
+		    GPM_DEFAULT_TM_LANG_ENTRY)
+
+DEFINE_INT_PREF (show_tm_options,
+		 GPM_TM_SHOW_TM_OPTIONS,
+		 GPM_DEFAULT_TM_SHOW_TM_OPTIONS)
+
+DEFINE_INT_PREF (missing_words,
+		 GPM_TM_MISSING_WORDS,
+		 GPM_DEFAULT_TM_MISSING_WORDS)
+
+DEFINE_INT_PREF (sentence_length,
+		 GPM_TM_SENTENCE_LENGTH,
+		 GPM_DEFAULT_TM_SENTENCE_LENGTH)
+
 /* The following functions are taken from gconf-client.c 
  * and partially modified. 
  * The licensing terms on these is: 

Modified: trunk/src/prefs-manager.h
==============================================================================
--- trunk/src/prefs-manager.h	(original)
+++ trunk/src/prefs-manager.h	Tue Sep 16 07:58:13 2008
@@ -31,6 +31,8 @@
 
 #define GPM_PREFS_DIR			GTR_BASE_KEY "/preferences"
 
+#define GPM_HEADER                      GTR_BASE_KEY "/header"
+
 /* Files */
 #define GPM_GENERAL_DIR			GPM_PREFS_DIR "/files/general"
 #define GPM_WARN_IF_FUZZY		GPM_GENERAL_DIR "/warn_if_fuzzy"
@@ -39,8 +41,7 @@
 #define GPM_AUTOSAVE_DIR		GPM_PREFS_DIR "/files/autosave"
 #define GPM_AUTOSAVE			GPM_AUTOSAVE_DIR "/autosave"
 #define GPM_AUTOSAVE_INTERVAL		GPM_AUTOSAVE_DIR "/autosave_interval"
-#define GPM_APPEND_SUFFIX		GPM_AUTOSAVE_DIR "/append_suffix"
-#define GPM_AUTOSAVE_SUFFIX		GPM_AUTOSAVE_DIR "/autosave_suffix"
+#define GPM_CREATE_BACKUP		GPM_AUTOSAVE_DIR "/create_backup"
 
 /* Editor */
 #define GPM_TEXT_DISPLAY_DIR		GPM_PREFS_DIR "/editor/text_display"
@@ -56,7 +57,7 @@
 #define GPM_SPELLCHECK			GPM_CONTENTS_DIR "/spellcheck"
 
 /* Edit Header */
-#define GPM_TAKE_MY_OPTIONS		GPM_PREFS_DIR "/take_my_options"
+#define GPM_TAKE_MY_OPTIONS		GPM_HEADER "/take_my_options"
 
 /* PO header */
 #define GPM_PERSONAL_INFORMATION_DIR	GPM_PREFS_DIR "/po_header/personal_information"
@@ -70,12 +71,21 @@
 #define GPM_TRANSFER_ENCODING		GPM_LANGUAGE_SETTINGS_DIR "/transfer_encoding"
 #define GPM_TEAM_EMAIL			GPM_LANGUAGE_SETTINGS_DIR "/team_email"
 
+/* Translation Memory */
+#define GPM_TM_DIR                      GPM_PREFS_DIR "/tm/dir_entry"
+#define GPM_TM_USE_LANG_PROFILE         GPM_PREFS_DIR "/tm/use_lang_profile"
+#define GPM_TM_LANG_ENTRY               GPM_PREFS_DIR "/tm/tm_lang_profile"
+#define GPM_TM_SHOW_TM_OPTIONS          GPM_PREFS_DIR "/tm/show_tm_options"
+#define GPM_TM_MISSING_WORDS            GPM_PREFS_DIR "/tm/missing_words"
+#define GPM_TM_SENTENCE_LENGTH          GPM_PREFS_DIR "/tm/sentence_lenght"
+
 /*FIXME: With profiles i think that this has to change*/
 #define GPM_PLURAL_FORM			GPM_LANGUAGE_SETTINGS_DIR "/plural_form"
 
 /* Interface */
 #define GPM_INTERFACE_DIR		GPM_PREFS_DIR "/interface"
 #define GPM_GDL_STYLE			GPM_INTERFACE_DIR "/gdl_style"
+#define GPM_SCHEME_COLOR		GPM_INTERFACE_DIR "/scheme_color"
 
 /* Fallback default values. Keep in sync with gtranslator.schemas */
 
@@ -85,8 +95,7 @@
 
 #define GPM_DEFAULT_AUTOSAVE		  0 /* FALSE */
 #define GPM_DEFAULT_AUTOSAVE_INTERVAL	  4
-#define GPM_DEFAULT_APPEND_SUFFIX         0 /* FALSE */
-#define GPM_DEFAULT_AUTOSAVE_SUFFIX	  (const gchar*) "autosave"
+#define GPM_DEFAULT_CREATE_BACKUP         0 /* FALSE */
 
 /* Editor */
 #define GPM_DEFAULT_HIGHLIGHT             1 /* TRUE */
@@ -114,6 +123,15 @@
 
 /* Interface */
 #define GPM_DEFAULT_GDL_STYLE           2 //Both icons and text
+#define GPM_DEFAULT_SCHEME_COLOR	"classic"
+
+/* Translation Memory */
+#define GPM_DEFAULT_TM_DIR              (const gchar*) ""
+#define GPM_DEFAULT_TM_USE_LANG_PROFILE 0 /*FALSE*/
+#define GPM_DEFAULT_TM_LANG_ENTRY       (const gchar*) ""
+#define GPM_DEFAULT_TM_SHOW_TM_OPTIONS  0 /*FALSE*/
+#define GPM_DEFAULT_TM_MISSING_WORDS    2
+#define GPM_DEFAULT_TM_SENTENCE_LENGTH  2
 
 /** LIFE CYCLE MANAGEMENT FUNCTIONS **/
 
@@ -145,13 +163,9 @@
 void                     gtranslator_prefs_manager_set_autosave_interval        (gint timeout);
 gint                     gtranslator_prefs_manager_get_autosave_interval        (void);
 
-/*Append suffix*/
-void                     gtranslator_prefs_manager_set_append_suffix            (gboolean aws);
-gboolean                 gtranslator_prefs_manager_get_append_suffix            (void);
-
-/*Autosave suffix*/
-void                     gtranslator_prefs_manager_set_autosave_suffix          (const gchar *suffix);
-const gchar *            gtranslator_prefs_manager_get_autosave_suffix          (void);
+/*Create backup*/
+void                     gtranslator_prefs_manager_set_create_backup            (gboolean backup);
+gboolean                 gtranslator_prefs_manager_get_create_backup            (void);
 
 /*Highlight*/
 void                     gtranslator_prefs_manager_set_highlight                (gboolean highlight);
@@ -173,10 +187,6 @@
 void                     gtranslator_prefs_manager_set_unmark_fuzzy             (gboolean unmark);
 gboolean                 gtranslator_prefs_manager_get_unmark_fuzzy             (void);
 
-/*keep obsolete*/
-void                     gtranslator_prefs_manager_set_keep_obsolete            (gboolean keep_obsolete);
-gboolean                 gtranslator_prefs_manager_get_keep_obsolete            (void);
-
 /*Spellcheck*/
 void                     gtranslator_prefs_manager_set_spellcheck               (gboolean spell_checking);
 gboolean                 gtranslator_prefs_manager_get_spellcheck               (void);
@@ -197,4 +207,27 @@
 void                     gtranslator_prefs_manager_set_gdl_style                (gint style);
 gint                     gtranslator_prefs_manager_get_gdl_style                (void);
 
+/*Scheme color*/
+void                     gtranslator_prefs_manager_set_scheme_color             (const gchar *scheme);
+const gchar *            gtranslator_prefs_manager_get_scheme_color             (void);
+
+/*Translation Memory*/
+void                     gtranslator_prefs_manager_set_tm_dir                   (const gchar *dir);
+const gchar *            gtranslator_prefs_manager_get_tm_dir                   (void);
+
+void                     gtranslator_prefs_manager_set_show_tm_options          (gboolean show_tm_options);
+gboolean                 gtranslator_prefs_manager_get_show_tm_options          (void);
+
+void                     gtranslator_prefs_manager_set_tm_lang_entry            (const gchar *dir);
+const gchar *            gtranslator_prefs_manager_get_tm_lang_entry            (void);
+
+void                     gtranslator_prefs_manager_set_use_lang_profile         (gboolean use_lang_profile);
+gboolean                 gtranslator_prefs_manager_get_use_lang_profile         (void);
+
+void                     gtranslator_prefs_manager_set_missing_words            (gint timeout);
+gint                     gtranslator_prefs_manager_get_missing_words            (void);
+
+void                     gtranslator_prefs_manager_set_sentence_length          (gint timeout);
+gint                     gtranslator_prefs_manager_get_sentence_length          (void);
+
 #endif  /* __GTR_PREFS_MANAGER_H__ */

Modified: trunk/src/profile.c
==============================================================================
--- trunk/src/profile.c	(original)
+++ trunk/src/profile.c	Tue Sep 16 07:58:13 2008
@@ -15,7 +15,8 @@
  *  along with this program; if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
- 
+
+#include "application.h" 
 #include "profile.h"
 #include "preferences-dialog.h"
 #include "utils.h"
@@ -241,15 +242,15 @@
 	
 	root = xmlDocGetRootElement (doc);
 	profile_node = xmlNewChild (root, NULL, "profile", NULL);
-	xmlNewChild (profile_node, NULL, "profile_name", profile->priv->name);
-	xmlNewChild (profile_node, NULL, "author_name", profile->priv->author_name);
-	xmlNewChild (profile_node, NULL, "autor_email", profile->priv->author_email);
-	xmlNewChild (profile_node, NULL, "language_name", profile->priv->language_name);
-	xmlNewChild (profile_node, NULL, "language_code", profile->priv->language_code);
-	xmlNewChild (profile_node, NULL, "charset", profile->priv->charset);
-	xmlNewChild (profile_node, NULL, "encoding", profile->priv->encoding);
-	xmlNewChild (profile_node, NULL, "group_email", profile->priv->group_email);
-	xmlNewChild (profile_node, NULL, "plurals", profile->priv->plurals);
+	xmlNewTextChild (profile_node, NULL, "profile_name", profile->priv->name);
+	xmlNewTextChild (profile_node, NULL, "author_name", profile->priv->author_name);
+	xmlNewTextChild (profile_node, NULL, "author_email", profile->priv->author_email);
+	xmlNewTextChild (profile_node, NULL, "language_name", profile->priv->language_name);
+	xmlNewTextChild (profile_node, NULL, "language_code", profile->priv->language_code);
+	xmlNewTextChild (profile_node, NULL, "charset", profile->priv->charset);
+	xmlNewTextChild (profile_node, NULL, "encoding", profile->priv->encoding);
+	xmlNewTextChild (profile_node, NULL, "group_email", profile->priv->group_email);
+	xmlNewTextChild (profile_node, NULL, "plurals", profile->priv->plurals);
 }
 
 /**
@@ -304,13 +305,19 @@
 {
   GList *profiles_list = NULL;
   GtranslatorProfile *profile;
-  xmlNodePtr root, child;
+  xmlNodePtr root, child, active;
   xmlDocPtr doc;
+  gchar *active_profile;
+  GList *l;
 
   doc = gtranslator_xml_open_file (filename);
 
   root = xmlDocGetRootElement (doc);
   child = root->xmlChildrenNode;
+  active = child->xmlChildrenNode;
+
+  active_profile = xmlNodeGetContent (active);
+  child = child->next;
 
   while (child != NULL) {
     profile = gtranslator_profile_xml_get_entry (child);
@@ -318,5 +325,39 @@
     child = child->next;
   }
   
+  for (l = profiles_list; l; l = l->next) {
+    GtranslatorProfile *profile;
+    profile = (GtranslatorProfile *)l->data;
+    if (!strcmp(gtranslator_profile_get_name (profile), active_profile))
+      gtranslator_application_set_active_profile (GTR_APP, profile);
+  }
+  
   return profiles_list;
 }
+
+void gtranslator_profile_save_profiles_in_xml (gchar *filename) {
+  
+  xmlNodePtr root, child, active;
+  xmlDocPtr doc;
+  GList *profiles_list, *l;
+  GtranslatorProfile *active_profile;
+
+  doc = gtranslator_xml_new_doc ("list_of_profiles");
+  
+  profiles_list = gtranslator_application_get_profiles (GTR_APP);
+  active_profile = gtranslator_application_get_active_profile (GTR_APP);
+
+  root = xmlDocGetRootElement (doc);
+  child = root->xmlChildrenNode;
+  active = child->xmlChildrenNode;
+
+  xmlNewChild (root, NULL, "active", gtranslator_profile_get_name (active_profile));
+  
+  for (l = profiles_list; l; l = l->next) {
+    GtranslatorProfile *profile;
+    profile = (GtranslatorProfile *)l->data;
+    gtranslator_profile_xml_new_entry (doc, profile);
+  }
+  
+  xmlSaveFile (filename, doc);
+}

Modified: trunk/src/profile.h
==============================================================================
--- trunk/src/profile.h	(original)
+++ trunk/src/profile.h	Tue Sep 16 07:58:13 2008
@@ -102,4 +102,6 @@
 
 GList          *gtranslator_profile_get_profiles_from_xml_file   (gchar *filename);
 
+void           gtranslator_profile_save_profiles_in_xml (gchar *filename);
+
 #endif /* __PROFILE_H__ */

Modified: trunk/src/statusbar.c
==============================================================================
--- trunk/src/statusbar.c	(original)
+++ trunk/src/statusbar.c	Tue Sep 16 07:58:13 2008
@@ -39,6 +39,9 @@
 	
 	GtkWidget     *overwrite_mode_label;
 
+	/* default context data */
+	guint          default_context_id;
+	
 	/* tmp flash timeout data */
 	guint          flash_timeout;
 	guint          flash_context_id;
@@ -83,6 +86,8 @@
 	gtk_widget_show (statusbar->priv->statusbar);
 	gtk_box_pack_end (GTK_BOX (statusbar), statusbar->priv->statusbar,
 			  TRUE, TRUE, 0);
+	statusbar->priv->default_context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar->priv->statusbar),
+									    "default-context-id");
 	
 	/*
 	 * Progress bar
@@ -129,6 +134,48 @@
 	return GTK_WIDGET (g_object_new (GTR_TYPE_STATUSBAR, NULL));
 }
 
+/**
+ * gtranslator_statusbar_push_default:
+ * @statusbar: a #GtranslatorStatusbar
+ * @text: the text to push in the statusbar
+ *
+ * Pushes a text onto the statusbar in the default context id.
+ */
+void
+gtranslator_statusbar_push_default (GtranslatorStatusbar *statusbar,
+				    const gchar *text)
+{
+	g_return_if_fail (GTR_IS_STATUSBAR (statusbar));
+	
+	gtk_statusbar_push (GTK_STATUSBAR (statusbar->priv->statusbar),
+			    statusbar->priv->default_context_id, text);
+}
+
+/**
+ * gtranslator_statusbar_pop_default:
+ * @statusbar: a #GtranslatorStatusbar
+ *
+ * Pops the text in the statusbar of the default context id.
+ */
+void
+gtranslator_statusbar_pop_default (GtranslatorStatusbar *statusbar)
+{
+	g_return_if_fail (GTR_IS_STATUSBAR (statusbar));
+	
+	gtk_statusbar_pop (GTK_STATUSBAR (statusbar->priv->statusbar),
+			   statusbar->priv->default_context_id);
+}
+
+/**
+ * gtranslator_statusbar_push:
+ * @statusbar: a #GtranslatorStatusbar
+ * @context_id: the message's context id, as returned by gtk_statusbar_get_context_id()
+ * @text: the text to push in the statusbar
+ *
+ * Pushes a new message onto a statusbar's stack.
+ *
+ * Returns: a message id that can be used with gtk_statusbar_remove()
+ */
 guint
 gtranslator_statusbar_push (GtranslatorStatusbar *statusbar,
 			    guint context_id,
@@ -140,6 +187,13 @@
 				   context_id, text);
 }
 
+/**
+ * gtranslator_statusbar_pop:
+ * @statusbar: a #GtranslatorStatusbar
+ * @context_id: a context identifier
+ * 
+ * Removes the first message in the GtkStatusBar's stack with the given context id. 
+ */
 void
 gtranslator_statusbar_pop (GtranslatorStatusbar *statusbar,
 			   guint context_id)
@@ -151,6 +205,24 @@
 }
 
 /**
+ * gtranslator_statusbar_get_context_id:
+ * @statusbar: a #GtranslatorStatusbar
+ * @context_description: textual description of what context the new message is being used in
+ *
+ * Returns a new context identifier, given a description of the actual context.
+ * Note that the description is not shown in the UI.
+ * 
+ * Returns: an integer id
+ */
+guint
+gtranslator_statusbar_get_context_id (GtranslatorStatusbar *statusbar,
+				      const gchar *context_description)
+{
+  return gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar->priv->statusbar),
+				       context_description);
+}
+
+/**
  * gtranslator_statusbar_set_overwrite:
  * @statusbar: a #GtranslatorStatusbar
  * @overwrite: if the overwrite mode is set
@@ -168,6 +240,12 @@
 	else gtk_label_set_text(GTK_LABEL(statusbar->priv->overwrite_mode_label), _("INS"));
 }
 
+/**
+ * gtranslator_statusbar_clear_overwrite:
+ * @statusbar: a #GtranslatorStatusbar
+ *
+ * Clears the statusbar overwrite label.
+ */
 void
 gtranslator_statusbar_clear_overwrite (GtranslatorStatusbar *statusbar)
 {
@@ -218,7 +296,7 @@
 		g_source_remove (statusbar->priv->flash_timeout);
 		statusbar->priv->flash_timeout = 0;
 
-		gtk_statusbar_remove (GTK_STATUSBAR (statusbar),
+		gtk_statusbar_remove (GTK_STATUSBAR (statusbar->priv->statusbar),
 				      statusbar->priv->flash_context_id,
 				      statusbar->priv->flash_message_id);
 	}
@@ -235,8 +313,13 @@
 	g_free (msg);
 }
 
-/*
- * Update the progress bar
+/**
+ * gtranslator_statusbar_update_progress_bar:
+ * @statusbar: a #GtranslatorStatusbar
+ * @translated_count: the number of translated messages
+ * @messages_count: the number of messages
+ * 
+ * Updates the state of the progress bar with the given values.
  */
 void
 gtranslator_statusbar_update_progress_bar (GtranslatorStatusbar *statusbar,

Modified: trunk/src/statusbar.h
==============================================================================
--- trunk/src/statusbar.h	(original)
+++ trunk/src/statusbar.h	Tue Sep 16 07:58:13 2008
@@ -53,12 +53,20 @@
 
 GtkWidget	*gtranslator_statusbar_new			(void);
 
+void             gtranslator_statusbar_push_default             (GtranslatorStatusbar *statusbar,
+								 const gchar *text);
+
+void             gtranslator_statusbar_pop_default              (GtranslatorStatusbar *statusbar);
+
 guint            gtranslator_statusbar_push                     (GtranslatorStatusbar *statusbar,
 								 guint context_id,
 								 const gchar *text);
 
 void             gtranslator_statusbar_pop                      (GtranslatorStatusbar *statusbar,
 								 guint context_id);
+								 
+guint            gtranslator_statusbar_get_context_id           (GtranslatorStatusbar *statusbar,
+								 const gchar *context_description);
 
 void		 gtranslator_statusbar_set_overwrite		(GtranslatorStatusbar   *statusbar,
 								 gboolean          overwrite);

Modified: trunk/src/tab.c
==============================================================================
--- trunk/src/tab.c	(original)
+++ trunk/src/tab.c	Tue Sep 16 07:58:13 2008
@@ -24,7 +24,8 @@
 #include <config.h>
 #endif
 
-#include "comment.h"
+#include "application.h"
+#include "context.h"
 #include "io-error-message-area.h"
 #include "message-area.h"
 #include "message-table.h"
@@ -33,6 +34,9 @@
 #include "po.h"
 #include "prefs-manager.h"
 #include "view.h"
+#include "translation-memory.h"
+#include "translation-memory-ui.h"
+#include "window.h"
 
 #include <glib.h>
 #include <glib-object.h>
@@ -58,19 +62,27 @@
 	GtkWidget *content_pane;
 	GtkWidget *panel;
 	GtkWidget *message_table;
+	GtkWidget *lateral_panel; //TM, Context, etc.
 
 	GtkWidget *comment_pane;
-	GtkWidget *comment;
+	GtkWidget *context;
+        GtkWidget *translation_memory;
+	
+	/*Comment button*/
+	GtkWidget *comment_button;
 	
 	/*Message area*/
 	GtkWidget *message_area;
 	
 	/*Original text*/
-	GtkWidget *text_notebook;
+        GtkWidget *msgid_hbox;
+	GtkWidget *text_vbox;
 	GtkWidget *text_msgid;
+	GtkWidget *text_plural_scroll;
 	GtkWidget *text_msgid_plural;
 	
 	/*Translated text*/
+        GtkWidget *msgstr_hbox;
 	GtkWidget *trans_notebook;
 	GtkWidget *trans_msgstr[MAX_PLURALS];
 	
@@ -78,17 +90,140 @@
 	GtkWidget *translated;
 	GtkWidget *fuzzy;
 	GtkWidget *untranslated;
+	
+	/* Autosave */
+	GTimer *timer;
+	gint autosave_interval;
+	guint autosave_timeout;
+	gint autosave : 1;
+	
+	/*Blocking movement*/
+	gboolean blocking;
 };
 
 enum
 {
 	SHOWED_MESSAGE,
 	MESSAGE_CHANGED,
+	MESSAGE_EDITION_FINISHED,
 	LAST_SIGNAL
 };
 
+enum
+{
+	PROP_0,
+	PROP_AUTOSAVE,
+	PROP_AUTOSAVE_INTERVAL
+};
+
 static guint signals[LAST_SIGNAL];
 
+static gboolean gtranslator_tab_autosave (GtranslatorTab *tab);
+
+static void
+install_autosave_timeout (GtranslatorTab *tab)
+{
+	gint timeout;
+
+	g_return_if_fail (tab->priv->autosave_timeout <= 0);
+	g_return_if_fail (tab->priv->autosave);
+	g_return_if_fail (tab->priv->autosave_interval > 0);
+	
+	/* Add a new timeout */
+	timeout = g_timeout_add (tab->priv->autosave_interval * 1000 * 60,
+				 (GSourceFunc) gtranslator_tab_autosave,
+				 tab);
+	
+	tab->priv->autosave_timeout = timeout;
+}
+
+static gboolean
+install_autosave_timeout_if_needed (GtranslatorTab *tab)
+{	
+	g_return_val_if_fail (tab->priv->autosave_timeout <= 0, FALSE);
+
+ 	if (tab->priv->autosave)
+ 	{
+ 		install_autosave_timeout (tab);
+ 		
+ 		return TRUE;
+ 	}
+ 	
+ 	return FALSE;
+}
+
+static gboolean
+gtranslator_tab_autosave (GtranslatorTab *tab)
+{
+	GError *error = NULL;
+	
+	if (!gtranslator_po_get_state (tab->priv->po) == GTR_PO_STATE_MODIFIED)
+		return TRUE;
+	
+	gtranslator_po_save_file (tab->priv->po, &error);
+	if (error)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+	}
+	
+	return TRUE;
+}
+
+static void
+remove_autosave_timeout (GtranslatorTab *tab)
+{
+	g_return_if_fail (tab->priv->autosave_timeout > 0);
+	
+	g_source_remove (tab->priv->autosave_timeout);
+	tab->priv->autosave_timeout = 0;
+}
+
+static void
+gtranslator_tab_showed_message (GtranslatorTab *tab,
+				GtranslatorMsg *msg)
+{
+	if (strcmp (gtranslator_msg_get_comment (msg), "") != 0)
+		gtk_widget_show (tab->priv->comment_button);
+	else gtk_widget_hide (tab->priv->comment_button);
+}
+
+static void
+gtranslator_tab_edition_finished (GtranslatorTab *tab,
+				  GtranslatorMsg *msg)
+{
+	GtranslatorTranslationMemory *tm;
+	gchar *message_error;
+	GtkWidget *message_area;
+	
+	tm = GTR_TRANSLATION_MEMORY (gtranslator_application_get_translation_memory (GTR_APP));
+	
+	if (gtranslator_msg_is_translated (msg) && !gtranslator_msg_is_fuzzy (msg))
+		gtranslator_translation_memory_store (tm,
+						      gtranslator_msg_get_msgid (msg),
+						      gtranslator_msg_get_msgstr (msg));
+	
+	/*
+	 * Checking message
+	 */
+	message_error = gtranslator_msg_check (msg);
+	
+	if (message_error != NULL)
+	{
+		gtranslator_tab_block_movement (tab);
+		
+		message_area = create_error_message_area (_("There is an error in the message:"),
+							  message_error);
+		gtranslator_tab_set_message_area (tab, message_area);
+		g_free (message_error);
+	}
+	else
+	{
+		gtranslator_tab_unblock_movement (tab);
+		gtranslator_tab_set_message_area (tab, NULL);
+	}
+}
+
 /*
  * Write the change back to the gettext PO instance in memory and
  * mark the page dirty
@@ -170,9 +305,9 @@
 
 
 static GtkWidget *
-gtranslator_tab_append_page(const gchar *tab_label,
-			    GtkWidget *notebook,
-			    gboolean spellcheck)
+gtranslator_tab_append_msgstr_page (const gchar *tab_label,
+				    GtkWidget *box,
+				    gboolean spellcheck)
 {
 	GtkWidget *scroll;
 	GtkWidget *label;
@@ -190,14 +325,18 @@
 		gtranslator_view_enable_spellcheck(GTR_VIEW(widget),
 						    spellcheck);
 	
-	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll),
-					      widget);
+	gtk_container_add (GTK_CONTAINER (scroll),
+			   widget);
 	
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
-				       GTK_POLICY_AUTOMATIC,
-				       GTK_POLICY_AUTOMATIC);
-		
-	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, label);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+					GTK_POLICY_AUTOMATIC,
+					GTK_POLICY_AUTOMATIC);
+	
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
+					     GTK_SHADOW_IN);
+	
+	gtk_notebook_append_page (GTK_NOTEBOOK (box), scroll, label);
+
 	return widget;
 }
 
@@ -228,6 +367,38 @@
 	}
 }
 
+static GtkWidget *
+gtranslator_tab_create_comment_button ()
+{
+	GtkWidget *button;
+	GtkWidget *image;
+	
+	/* setup close button */
+	button = gtk_button_new ();
+	gtk_button_set_relief (GTK_BUTTON (button),
+			       GTK_RELIEF_NONE);
+	/* don't allow focus on the close button */
+	gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
+
+	image = gtk_image_new_from_stock (GTK_STOCK_INDEX,
+					  GTK_ICON_SIZE_MENU);
+	gtk_widget_show (image);
+	gtk_container_add (GTK_CONTAINER (button), image);
+
+	gtk_widget_set_tooltip_text (button, _("Open comment dialog"));
+	
+	return button;
+}
+
+static void
+on_comment_button_clicked (GtkButton *button,
+			   gpointer useless)
+{
+	GtranslatorWindow *window = gtranslator_application_get_active_window (GTR_APP);
+	
+	gtranslator_show_comment_dialog (window);
+}
+
 /*
  * gtranslator_tab_show_message:
  * @tab: a #GtranslationTab
@@ -263,10 +434,9 @@
 	{
 		msgstr = gtranslator_msg_get_msgstr(msg);
 		/*
-		 * Disable notebook tabs
+		 * Disable notebook tabs and hide widgets
 		 */
-		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(priv->text_notebook), FALSE);
-		gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->text_notebook), 0);
+		gtk_widget_hide (priv->text_plural_scroll);
 		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(priv->trans_notebook), FALSE);
 		gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->trans_notebook), 0);
 		if(msgstr) 
@@ -278,7 +448,7 @@
 		}
 	}
 	else {
-		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(tab->priv->text_notebook), TRUE);
+		gtk_widget_show (priv->text_plural_scroll);
 		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(tab->priv->trans_notebook), TRUE);
 		buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tab->priv->text_msgid_plural));
 		gtk_text_buffer_set_text(buf, (gchar*)msgid_plural, -1);
@@ -304,37 +474,40 @@
 {
 	GtranslatorMsgStatus status;
 	GtranslatorPoState po_state;
+	gboolean fuzzy, translated;
 	
 	status = gtranslator_msg_get_status (msg);
 	po_state = gtranslator_po_get_state (tab->priv->po);
+	
+	fuzzy = gtranslator_msg_is_fuzzy (msg);
+	translated = gtranslator_msg_is_translated (msg);
 
-	if((status == GTR_MSG_STATUS_FUZZY) && !gtranslator_msg_is_fuzzy(msg))
+	if ((status == GTR_MSG_STATUS_FUZZY) && !fuzzy)
 	{
 		_gtranslator_po_increase_decrease_fuzzy(tab->priv->po, FALSE);
-		if(gtranslator_msg_is_translated(msg))
+		if (translated)
 		{
 			status = GTR_MSG_STATUS_TRANSLATED;
 			_gtranslator_po_increase_decrease_translated(tab->priv->po, TRUE);
 		}
 		else {
 			status = GTR_MSG_STATUS_UNTRANSLATED;
-			_gtranslator_po_increase_decrease_translated(tab->priv->po, FALSE);
 		}
 	}
-	else if((status == GTR_MSG_STATUS_TRANSLATED) && !gtranslator_msg_is_translated(msg))
+	else if ((status == GTR_MSG_STATUS_TRANSLATED) && !translated)
 	{
 		status = GTR_MSG_STATUS_UNTRANSLATED;
 		_gtranslator_po_increase_decrease_translated(tab->priv->po, FALSE);
 	}
-	else if((status == GTR_MSG_STATUS_TRANSLATED) && gtranslator_msg_is_fuzzy(msg))
+	else if ((status == GTR_MSG_STATUS_TRANSLATED) && fuzzy)
 	{
 		status = GTR_MSG_STATUS_FUZZY;
 		_gtranslator_po_increase_decrease_translated(tab->priv->po, FALSE);
 		_gtranslator_po_increase_decrease_fuzzy(tab->priv->po, TRUE);
 	}
-	else if((status == GTR_MSG_STATUS_UNTRANSLATED) && gtranslator_msg_is_translated(msg))
+	else if ((status == GTR_MSG_STATUS_UNTRANSLATED) && translated)
 	{
-		if(gtranslator_msg_is_fuzzy(msg))
+		if (fuzzy)
 		{
 			status = GTR_MSG_STATUS_FUZZY;
 			_gtranslator_po_increase_decrease_fuzzy(tab->priv->po, TRUE);
@@ -353,31 +526,6 @@
 }
 
 static void
-set_message_area (GtranslatorTab  *tab,
-                  GtkWidget *message_area)
-{
-        if (tab->priv->message_area == message_area)
-                return;
-
-        if (tab->priv->message_area != NULL)
-                gtk_widget_destroy (tab->priv->message_area);
-
-        tab->priv->message_area = message_area;
-
-        if (message_area == NULL)
-                return;
-
-        gtk_box_pack_start (GTK_BOX (tab),
-                            tab->priv->message_area,
-                            FALSE,
-                            FALSE,
-                            0);         
-
-        g_object_add_weak_pointer (G_OBJECT (tab->priv->message_area), 
-                                   (gpointer *)&tab->priv->message_area);
-}
-
-static void
 comment_pane_position_changed (GObject		*tab_gobject,
 			       GParamSpec	*arg1,
 			       GtranslatorTab	*tab)
@@ -409,9 +557,9 @@
 	
 	do{
 		label = g_strdup_printf (_("Plural %d"), i+1);
-		priv->trans_msgstr[i] = gtranslator_tab_append_page (label,
-								     priv->trans_notebook,
-								     TRUE);
+		priv->trans_msgstr[i] = gtranslator_tab_append_msgstr_page (label,
+									    priv->trans_notebook,
+									    TRUE);
 		buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->trans_msgstr[i]));
 		g_signal_connect (buf, "end-user-action",
 				  G_CALLBACK (gtranslator_message_translation_update),
@@ -428,10 +576,16 @@
 static void
 gtranslator_tab_draw (GtranslatorTab *tab)
 {
+        gint current_page_num;
 	GtkWidget *image;
 	GtkWidget *vertical_box;
 	GtkWidget *label_widget;
-	
+	GtkWidget *msgid_label;
+	GtkWidget *msgstr_label;
+	GtkWidget *current_page;
+	GtkWidget *notebook, *tm_layout, *tm, *comments_label, *tm_label, *scroll;
+	GtkWidget *hbox;
+	GtkWidget *label;
 	GtranslatorTabPrivate *priv = tab->priv;
 	
 	/*
@@ -453,6 +607,9 @@
 	gtk_notebook_append_page (GTK_NOTEBOOK (priv->panel),
 				  priv->message_table,
 				  label_widget);
+
+	gtk_notebook_set_show_tabs(GTK_NOTEBOOK (priv->panel),
+				   FALSE);
 	
 	/*
 	 * Comment pane
@@ -464,13 +621,31 @@
 			  G_CALLBACK (comment_pane_position_changed),
 			  tab);
 	gtk_widget_show (priv->comment_pane);
+	
+	/*
+	 * Lateral panel
+	 */
+	tab->priv->lateral_panel = gtk_notebook_new ();
+	gtk_widget_show (tab->priv->lateral_panel);
+
+	gtk_paned_pack2(GTK_PANED(priv->comment_pane), tab->priv->lateral_panel,
+			TRUE, TRUE);
+	
+	/*
+	 * Context
+	 */
+	priv->context = gtranslator_context_panel_new (GTK_WIDGET (tab));
+	gtk_widget_show (priv->context);
+	gtranslator_tab_add_widget_to_lateral_panel (tab, priv->context,
+						     _("Context"));
 
 	/*
-	 * Comment
+	 * TM
 	 */
-	priv->comment = gtranslator_comment_panel_new(GTK_WIDGET(tab));
-	gtk_paned_pack2(GTK_PANED(priv->comment_pane), priv->comment, TRUE, TRUE);
-	gtk_widget_show (priv->comment);
+	priv->translation_memory = gtranslator_translation_memory_ui_new (GTK_WIDGET (tab));
+	gtk_widget_show (priv->translation_memory);
+	gtranslator_tab_add_widget_to_lateral_panel (tab, priv->translation_memory,
+						     _("Translation Memory"));
 	
 	/*
 	 * Content pane; this is where the message table and message area go
@@ -495,27 +670,90 @@
 	/*
 	 * Orignal text widgets
 	 */
-	priv->text_notebook = gtk_notebook_new();
-	gtk_notebook_set_show_border(GTK_NOTEBOOK(priv->text_notebook), FALSE);
-	gtk_widget_show (priv->text_notebook);
-	priv->text_msgid = gtranslator_tab_append_page(_("Singular"),
-						       priv->text_notebook,
-						       FALSE);
-	gtk_text_view_set_editable(GTK_TEXT_VIEW(priv->text_msgid), FALSE);
-	priv->text_msgid_plural = gtranslator_tab_append_page(_("Plural"),
-							      priv->text_notebook,
-							      FALSE);
-	gtk_text_view_set_editable(GTK_TEXT_VIEW(priv->text_msgid_plural), FALSE);
-	gtk_box_pack_start(GTK_BOX(vertical_box), priv->text_notebook, TRUE, TRUE, 0);
+	priv->msgid_hbox = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (priv->msgid_hbox);
+	
+	msgid_label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (msgid_label),
+			      "<b>Original Text:</b>");
+	gtk_misc_set_padding (GTK_MISC (msgid_label), 0, 5);
+	gtk_widget_show (msgid_label);
+
+	gtk_box_pack_start(GTK_BOX(priv->msgid_hbox), msgid_label, FALSE, FALSE, 0);
+
+	priv->text_vbox = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (priv->text_vbox);
+	
+	/* Singular */
+	scroll = gtk_scrolled_window_new (NULL, NULL);
+	gtk_widget_show (scroll);
+	
+	priv->text_msgid = gtranslator_view_new ();
+	gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->text_msgid), FALSE);
+	gtk_widget_show (priv->text_msgid);
+	
+	gtk_container_add (GTK_CONTAINER (scroll),
+			   priv->text_msgid);
+	
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+				        GTK_POLICY_AUTOMATIC,
+				        GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
+					     GTK_SHADOW_IN);
+	
+	gtk_box_pack_start (GTK_BOX (priv->text_vbox), scroll, TRUE, TRUE, 0);
+	
+	/* Plural */
+	priv->text_plural_scroll = gtk_scrolled_window_new (NULL, NULL);
+	gtk_widget_show (priv->text_plural_scroll);
+	
+	priv->text_msgid_plural = gtranslator_view_new ();
+	gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->text_msgid_plural),
+				    FALSE);
+	gtk_widget_show (priv->text_msgid_plural);
+	
+	gtk_container_add (GTK_CONTAINER (priv->text_plural_scroll),
+			   priv->text_msgid_plural);
+	
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->text_plural_scroll),
+				        GTK_POLICY_AUTOMATIC,
+				        GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->text_plural_scroll),
+					     GTK_SHADOW_IN);
+	
+	gtk_box_pack_start (GTK_BOX (priv->text_vbox), priv->text_plural_scroll,
+			    TRUE, TRUE, 0);
+
+	gtk_box_pack_start (GTK_BOX (vertical_box), priv->msgid_hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vertical_box), priv->text_vbox, TRUE, TRUE, 0);
 
 	
 	/*
 	 * Translation widgets
 	 */
+	priv->msgstr_hbox = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (priv->msgstr_hbox);
+	
+	msgstr_label = gtk_label_new (NULL);
+	gtk_label_set_markup_with_mnemonic (GTK_LABEL (msgstr_label),
+					    "<b>Tran_slated Text:</b>");
+	gtk_misc_set_padding (GTK_MISC (msgstr_label), 0, 5);
+	gtk_misc_set_alignment (GTK_MISC (msgstr_label), 0, 0.5);
+	gtk_widget_show (msgstr_label);
+
+	gtk_box_pack_start(GTK_BOX(priv->msgstr_hbox), msgstr_label, TRUE, TRUE, 0);
+	
+	priv->comment_button = gtranslator_tab_create_comment_button ();
+	gtk_box_pack_start (GTK_BOX (priv->msgstr_hbox), priv->comment_button,
+			    FALSE, FALSE, 0);
+	g_signal_connect (priv->comment_button, "clicked",
+			  G_CALLBACK (on_comment_button_clicked), NULL);
+
 	priv->trans_notebook = gtk_notebook_new();
 	gtk_notebook_set_show_border(GTK_NOTEBOOK(priv->trans_notebook), FALSE);
 	gtk_widget_show (priv->trans_notebook);
 
+	gtk_box_pack_start(GTK_BOX(vertical_box), priv->msgstr_hbox, FALSE, FALSE, 0);	
 	gtk_box_pack_start(GTK_BOX(vertical_box), priv->trans_notebook, TRUE, TRUE, 0);	
 
 	gtk_paned_pack1(GTK_PANED(priv->comment_pane), vertical_box, FALSE, FALSE);
@@ -526,29 +764,88 @@
 static void
 gtranslator_tab_init (GtranslatorTab *tab)
 {
-	GtkWidget *image;
-	
 	tab->priv = GTR_TAB_GET_PRIVATE (tab);
 	
 	g_signal_connect(tab, "message-changed",
 			 G_CALLBACK(update_status), NULL);
 	
 	gtranslator_tab_draw(tab);
+	
+	/* Manage auto save data */
+	tab->priv->autosave = gtranslator_prefs_manager_get_autosave ();
+	tab->priv->autosave = (tab->priv->autosave != FALSE);
+
+	tab->priv->autosave_interval = gtranslator_prefs_manager_get_autosave_interval ();
+	if (tab->priv->autosave_interval <= 0)
+		tab->priv->autosave_interval = GPM_DEFAULT_AUTOSAVE_INTERVAL;
 }
 
 static void
 gtranslator_tab_finalize (GObject *object)
 {
-	GtranslatorTab *tab = GTR_TAB(object);
-	gint i;
+	GtranslatorTab *tab = GTR_TAB (object);
 	
-	if(tab->priv->po)
-		g_object_unref(tab->priv->po);
+	if (tab->priv->po)
+		g_object_unref (tab->priv->po);
+		
+	if (tab->priv->timer != NULL)
+		g_timer_destroy (tab->priv->timer);
+	
+	if (tab->priv->autosave_timeout > 0)
+		remove_autosave_timeout (tab);
 	
 	G_OBJECT_CLASS (gtranslator_tab_parent_class)->finalize (object);
 }
 
 static void
+gtranslator_tab_get_property (GObject    *object,
+			      guint       prop_id,
+			      GValue     *value,
+			      GParamSpec *pspec)
+{
+	GtranslatorTab *tab = GTR_TAB (object);
+
+	switch (prop_id)
+	{
+		case PROP_AUTOSAVE:
+			g_value_set_boolean (value,
+					     gtranslator_tab_get_autosave_enabled (tab));
+			break;
+		case PROP_AUTOSAVE_INTERVAL:
+			g_value_set_int (value,
+					 gtranslator_tab_get_autosave_interval (tab));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+gtranslator_tab_set_property (GObject      *object,
+			      guint         prop_id,
+			      const GValue *value,
+			      GParamSpec   *pspec)
+{
+	GtranslatorTab *tab = GTR_TAB (object);
+
+	switch (prop_id)
+	{
+		case PROP_AUTOSAVE:
+			gtranslator_tab_set_autosave_enabled (tab,
+							      g_value_get_boolean (value));
+			break;
+		case PROP_AUTOSAVE_INTERVAL:
+			gtranslator_tab_set_autosave_interval (tab,
+							       g_value_get_int (value));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;			
+	}
+}
+
+static void
 gtranslator_tab_class_init (GtranslatorTabClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -556,7 +853,12 @@
 	g_type_class_add_private (klass, sizeof (GtranslatorTabPrivate));
 
 	object_class->finalize = gtranslator_tab_finalize;
-	
+	object_class->set_property = gtranslator_tab_set_property;
+	object_class->get_property = gtranslator_tab_get_property;
+	klass->showed_message = gtranslator_tab_showed_message;
+	klass->message_edition_finished = gtranslator_tab_edition_finished;
+
+	/* Signals */
 	signals[SHOWED_MESSAGE] = 
 		g_signal_new("showed-message",
 			     G_OBJECT_CLASS_TYPE (klass),
@@ -576,6 +878,37 @@
 			     g_cclosure_marshal_VOID__POINTER,
 			     G_TYPE_NONE, 1,
 			     G_TYPE_POINTER);
+	
+	signals[MESSAGE_EDITION_FINISHED] = 
+		g_signal_new("message-edition-finished",
+			     G_OBJECT_CLASS_TYPE (klass),
+			     G_SIGNAL_RUN_LAST,
+			     G_STRUCT_OFFSET (GtranslatorTabClass, message_edition_finished),
+			     NULL, NULL,
+			     g_cclosure_marshal_VOID__POINTER,
+			     G_TYPE_NONE, 1,
+			     G_TYPE_POINTER);
+			     
+	/* Properties */
+	g_object_class_install_property (object_class,
+					 PROP_AUTOSAVE,
+					 g_param_spec_boolean ("autosave",
+							       "Autosave",
+							       "Autosave feature",
+							       TRUE,
+							       G_PARAM_READWRITE |
+							       G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+					 PROP_AUTOSAVE_INTERVAL,
+					 g_param_spec_int ("autosave-interval",
+							   "AutosaveInterval",
+							   "Time between two autosaves",
+							   0,
+							   G_MAXINT,
+							   0,
+							   G_PARAM_READWRITE |
+							   G_PARAM_STATIC_STRINGS));
 }
 
 /***************************** Public funcs ***********************************/
@@ -584,6 +917,8 @@
  * gtranslator_tab_new:
  * @po: a #GtranslatorPo
  * 
+ * Creates a new #GtranslatorTab.
+ * 
  * Return value: a new #GtranslatorTab object
  **/
 GtranslatorTab *
@@ -597,6 +932,7 @@
 	
 	tab->priv->po = po;
 	g_object_set_data (G_OBJECT (po), GTR_TAB_KEY, tab);
+	install_autosave_timeout_if_needed (tab);
 	
 	/*
 	 * Now we have to initialize the number of msgstr tabs
@@ -637,18 +973,6 @@
 }
 
 /**
- * gtranslator_tab_get_active_text_tab:
- * @tab: a #GtranslationTab
- * 
- * Return value: the number of the active original text notebook.
- **/
-gint
-gtranslator_tab_get_active_text_tab(GtranslatorTab *tab)
-{
-	return gtk_notebook_get_current_page(GTK_NOTEBOOK(tab->priv->text_notebook));
-}
-
-/**
  * gtranslator_tab_get_active_trans_tab:
  * @tab: a #GtranslationTab
  * 
@@ -661,15 +985,29 @@
 }
 
 /**
- * gtranslator_tab_get_comment_panel:
+ * gtranslator_tab_get_context_panel:
  * @tab: a #GtranslatorTab
  *
- * Return value: the #GtranslaorCommentPanel
+ * Return value: the #GtranslaorContextPanel
  */
-GtranslatorCommentPanel *
-gtranslator_tab_get_comment_panel(GtranslatorTab *tab)
+GtranslatorContextPanel *
+gtranslator_tab_get_context_panel(GtranslatorTab *tab)
 {
-	return GTR_COMMENT_PANEL(tab->priv->comment);
+	return GTR_CONTEXT_PANEL(tab->priv->context);
+}
+
+/**
+ * gtranslator_tab_get_translation_memory_ui:
+ * @tab: a #GtranslatorTab
+ *
+ * Returns: the #GtranslatorTranslationMemoryUi panel.
+ */
+GtkWidget *
+gtranslator_tab_get_translation_memory_ui (GtranslatorTab *tab)
+{
+	g_return_val_if_fail (GTR_IS_TAB (tab), NULL);
+	
+	return tab->priv->translation_memory;
 }
 
 /**
@@ -759,19 +1097,20 @@
  * gtranslator_tab_message_go_to:
  * @tab: a #GtranslatorTab
  * @to_go: the #GtranslatorMsg you want to jump
+ * @searching: TRUE if we are searching in the message list
  *
  * Jumps to the specific @to_go pointer message and show the message
  * in the #GtranslatorView.
 **/
 void 
-gtranslator_tab_message_go_to(GtranslatorTab *tab,
-			      GList * to_go)
+gtranslator_tab_message_go_to (GtranslatorTab *tab,
+			       GList * to_go,
+			       gboolean searching,
+			       GtranslatorTabMove move)
 {
 	GtranslatorPo *po;
-	static gint pos = 0;
 	GList *current_msg;
-	const gchar *message_error;
-	GtkWidget *message_area;
+	static gboolean first_msg = TRUE;
  
 	g_return_if_fail (tab != NULL);
 	g_return_if_fail (to_go != NULL);
@@ -779,34 +1118,96 @@
 		
 	po = tab->priv->po;
 	
-	current_msg = gtranslator_po_get_current_message(po);
-	message_error = gtranslator_msg_check(current_msg->data);
-	if(message_error == NULL)
+	current_msg = gtranslator_po_get_current_message (po);
+	
+	/*
+	 * Emitting message-edition-finished signal
+	 */
+	if (!searching && !first_msg)
+		g_signal_emit (G_OBJECT (tab), signals[MESSAGE_EDITION_FINISHED],
+			       0, GTR_MSG (current_msg->data));
+	
+	if (!tab->priv->blocking || first_msg)
 	{
-		gtranslator_tab_show_message(tab, to_go->data);
-		set_message_area(tab, NULL);
+		gboolean plurals;
+		gint current_page, n_pages;
+		/*
+		 * If the current message is plural and we press next/prev
+		 * we have to change to the next/prev plural tab in case is not
+		 * the last
+		 * To implement that:
+		 * if the tabs are showed then we check if we want prev or 
+		 * next and then if we need to change the tab we change it 
+		 * in other case we show the message
+		 * 
+		 * I don't like too much this implementation so if anybody can
+		 * rewrite this is a better way would be great.
+		 */
+		plurals = gtk_notebook_get_show_tabs (GTK_NOTEBOOK (tab->priv->trans_notebook));
+		current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (tab->priv->trans_notebook));
+		n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (tab->priv->trans_notebook));
+		if ((plurals == TRUE) && (move != GTR_TAB_MOVE_NONE))
+		{
+			if ((n_pages - 1) == current_page && move == GTR_TAB_MOVE_NEXT)
+			{
+				gtk_notebook_set_current_page (GTK_NOTEBOOK (tab->priv->trans_notebook),
+							       0);
+				gtranslator_tab_show_message (tab, to_go->data);
+			}
+			else if (current_page == 0 && move == GTR_TAB_MOVE_PREV)
+			{
+				gtk_notebook_set_current_page (GTK_NOTEBOOK (tab->priv->trans_notebook),
+							       n_pages - 1);
+				gtranslator_tab_show_message (tab, to_go->data);
+			}
+			else
+			{
+				if (move == GTR_TAB_MOVE_NEXT)
+					gtk_notebook_set_current_page (GTK_NOTEBOOK (tab->priv->trans_notebook),
+								       current_page + 1);
+				else
+					gtk_notebook_set_current_page (GTK_NOTEBOOK (tab->priv->trans_notebook),
+								       current_page - 1);
+				return;
+			}
+		}
+		else
+			gtranslator_tab_show_message (tab, to_go->data);
+		first_msg = FALSE;
 	}
 	else
-	{
-		message_area = create_error_message_area(_("There is an error in the message:"),
-							 message_error);
-		set_message_area(tab, message_area);
 		return;
-	}
 	
 	/*
 	 * Emitting showed-message signal
 	 */
-	g_signal_emit(G_OBJECT(tab), signals[SHOWED_MESSAGE], 0, GTR_MSG(to_go->data)); 
-	
+	if (!searching)
+		g_signal_emit (G_OBJECT (tab), signals[SHOWED_MESSAGE], 0,
+			       GTR_MSG (to_go->data)); 
 }
 
+/**
+ * _gtranslator_tab_can_close:
+ * @tab: a #GtranslatorTab
+ *
+ * Whether a #GtranslatorTab can be closed.
+ *
+ * Returns: TRUE if the #GtranslatorPo of the @tab is already saved
+ */
 gboolean
 _gtranslator_tab_can_close (GtranslatorTab *tab)
 {
 	return gtranslator_po_get_state (tab->priv->po) == GTR_PO_STATE_SAVED;
 }
 
+/**
+ * gtranslator_tab_get_from_document:
+ * @po: a #GtranslatorPo
+ *
+ * Returns the #GtranslatorTab for a specific #GtranslatorPo.
+ *
+ * Returns: the #GtranslatorTab for a specific #GtranslatorPo
+ */
 GtranslatorTab *
 gtranslator_tab_get_from_document (GtranslatorPo *po)
 {
@@ -818,3 +1219,522 @@
 	
 	return (res != NULL) ? GTR_TAB (res) : NULL;
 }
+
+/**
+ * gtranslator_tab_get_autosave_enabled:
+ * @tab: a #GtranslatorTab
+ * 
+ * Gets the current state for the autosave feature
+ * 
+ * Return value: TRUE if the autosave is enabled, else FALSE
+ **/
+gboolean
+gtranslator_tab_get_autosave_enabled (GtranslatorTab *tab)
+{
+	g_return_val_if_fail (GTR_IS_TAB (tab), FALSE);
+
+	return tab->priv->autosave;
+}
+
+/**
+ * gtranslator_tab_set_autosave_enabled:
+ * @tab: a #GtranslatorTab
+ * @enable: enable (TRUE) or disable (FALSE) auto save
+ * 
+ * Enables or disables the autosave feature. It does not install an
+ * autosave timeout if the document is new or is read-only
+ **/
+void
+gtranslator_tab_set_autosave_enabled (GtranslatorTab *tab, 
+				      gboolean enable)
+{
+	g_return_if_fail (GTR_IS_TAB (tab));
+
+	if (tab->priv->autosave == enable)
+		return;
+
+	tab->priv->autosave = enable;
+
+ 	if (enable && 
+ 	    (tab->priv->autosave_timeout <= 0))
+ 	{
+		install_autosave_timeout (tab);
+		
+		return;
+	}
+ 		
+ 	if (!enable && (tab->priv->autosave_timeout > 0))
+ 	{
+		remove_autosave_timeout (tab);
+		
+ 		return; 
+ 	} 
+
+ 	g_return_if_fail (!enable && (tab->priv->autosave_timeout <= 0)); 
+}
+
+/**
+ * gtranslator_tab_get_autosave_interval:
+ * @tab: a #GtranslatorTab
+ * 
+ * Gets the current interval for the autosaves
+ * 
+ * Return value: the value of the autosave
+ **/
+gint 
+gtranslator_tab_get_autosave_interval (GtranslatorTab *tab)
+{
+	g_return_val_if_fail (GTR_IS_TAB (tab), 0);
+
+	return tab->priv->autosave_interval;
+}
+
+/**
+ * gtranslator_tab_set_autosave_interval:
+ * @tab: a #GtranslatorTab
+ * @interval: the new interval
+ * 
+ * Sets the interval for the autosave feature. It does nothing if the
+ * interval is the same as the one already present. It removes the old
+ * interval timeout and adds a new one with the autosave passed as
+ * argument.
+ **/
+void 
+gtranslator_tab_set_autosave_interval (GtranslatorTab *tab, 
+				       gint interval)
+{
+	g_return_if_fail (GTR_IS_TAB (tab));
+	g_return_if_fail (interval > 0);
+
+	if (tab->priv->autosave_interval == interval)
+		return;
+
+	tab->priv->autosave_interval = interval;
+		
+	if (!tab->priv->autosave)
+		return;
+
+	if (tab->priv->autosave_timeout > 0)
+	{
+		remove_autosave_timeout (tab);
+
+		install_autosave_timeout (tab);
+	}
+}
+
+/**
+ * gtranslator_tab_add_widget_to_lateral_panel:
+ * @tab: a #GtranslatorTab
+ * @widget: a #GtkWidget
+ * @tab_name: the tab name in the notebook
+ *
+ * Adds a new widget to the laberal panel notebook.
+ */
+void
+gtranslator_tab_add_widget_to_lateral_panel (GtranslatorTab *tab,
+					     GtkWidget *widget,
+					     const gchar *tab_name)
+{
+	GtkWidget *label;
+	
+	g_return_if_fail (GTR_IS_TAB (tab));
+	g_return_if_fail (GTK_IS_WIDGET (widget));
+	
+	label = gtk_label_new (tab_name);
+	
+	gtk_notebook_append_page (GTK_NOTEBOOK (tab->priv->lateral_panel),
+				  widget, label);
+}
+
+/**
+ * gtranslator_tab_remove_widget_from_lateral_panel:
+ * @tab: a #GtranslatorTab
+ * @widget: a #GtkWidget
+ *
+ * Removes the @widget from the lateral panel notebook of @tab.
+ */
+void
+gtranslator_tab_remove_widget_from_lateral_panel (GtranslatorTab *tab,
+						  GtkWidget *widget)
+{
+	gint page;
+	
+	g_return_if_fail (GTR_IS_TAB (tab));
+	g_return_if_fail (GTK_IS_WIDGET (widget));
+	
+	page = gtk_notebook_page_num (GTK_NOTEBOOK (tab->priv->lateral_panel),
+				      widget);
+	
+	gtk_notebook_remove_page (GTK_NOTEBOOK (tab->priv->lateral_panel),
+				  page);
+}
+
+/**
+ * gtranslator_tab_show_lateral_panel_widget:
+ * @tab: a #GtranslatorTab
+ * @widget: the widget to be shown.
+ *
+ * Shows the notebook page of the @widget.
+ */
+void
+gtranslator_tab_show_lateral_panel_widget (GtranslatorTab *tab,
+					   GtkWidget *widget)
+{
+	gint page;
+	
+	page = gtk_notebook_page_num (GTK_NOTEBOOK (tab->priv->lateral_panel),
+				      widget);
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (tab->priv->lateral_panel),
+				       page);
+}
+
+/**
+ * gtranslator_tab_clear_msgstr_views:
+ * @tab: a #GtranslatorTab
+ * 
+ * Clears all text from msgstr text views.
+ */
+void
+gtranslator_tab_clear_msgstr_views (GtranslatorTab *tab)
+{
+	gint i = 0;
+	GtranslatorHeader *header;
+	GtkTextBuffer *buf;
+	
+	g_return_if_fail (GTR_IS_TAB (tab));
+	
+	header = gtranslator_po_get_header (tab->priv->po);
+	
+	do {
+		buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tab->priv->trans_msgstr[i]));
+		gtk_text_buffer_begin_user_action (buf);
+		gtk_text_buffer_set_text (buf, "", -1);
+		gtk_text_buffer_end_user_action (buf);
+		i++;
+	}while (i < gtranslator_header_get_nplurals (header));
+}
+
+/**
+ * gtranslator_tab_block_movement:
+ * @tab: a #GtranslatorTab
+ *
+ * Blocks the movement to the next/prev message.
+ */
+void
+gtranslator_tab_block_movement (GtranslatorTab *tab)
+{
+	g_return_if_fail (GTR_IS_TAB (tab));
+	
+	tab->priv->blocking = TRUE;
+}
+
+/**
+ * gtranslator_tab_unblock_movement:
+ * @tab: a #GtranslatorTab
+ * 
+ * Unblocks the movement to the next/prev message.
+ */
+void
+gtranslator_tab_unblock_movement (GtranslatorTab *tab)
+{
+	g_return_if_fail (GTR_IS_TAB (tab));
+	
+	tab->priv->blocking = FALSE;
+}
+
+/**
+ * gtranslator_tab_go_to_next:
+ * @tab: a #GtranslatorTab
+ *
+ * Moves to the next message or plural tab in case the message has plurals.
+ */
+void
+gtranslator_tab_go_to_next (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	gtranslator_tab_message_go_to (tab,
+				       g_list_next (gtranslator_po_get_current_message (po)),
+				       FALSE,
+				       GTR_TAB_MOVE_NEXT);
+}
+
+/**
+ * gtranslator_tab_go_to_prev:
+ * @tab: a #GtranslatorTab
+ *
+ * Moves to the previous message or plural tab in case the message has plurals.
+ */
+void
+gtranslator_tab_go_to_prev (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	gtranslator_tab_message_go_to (tab,
+				       g_list_previous (gtranslator_po_get_current_message (po)),
+				       FALSE,
+				       GTR_TAB_MOVE_PREV);
+}
+
+/**
+ * gtranslator_tab_go_to_first:
+ * @tab: a #GtranslatorTab
+ *
+ * Jumps to the first message.
+ */
+void
+gtranslator_tab_go_to_first (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	gtranslator_tab_message_go_to (tab,
+				       g_list_first (gtranslator_po_get_current_message (po)),
+				       FALSE,
+				       GTR_TAB_MOVE_NONE);
+}
+
+/**
+ * gtranslator_tab_go_to_last:
+ * @tab: a #GtranslatorTab 
+ *
+ * Jumps to the last message.
+ */
+void
+gtranslator_tab_go_to_last (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	gtranslator_tab_message_go_to (tab,
+				       g_list_last (gtranslator_po_get_current_message (po)),
+				       FALSE,
+				       GTR_TAB_MOVE_NONE);
+}
+
+/**
+ * gtranslator_tab_go_to_next_fuzzy:
+ * @tab: a #GtranslatorTab
+ *
+ * If there is a next fuzzy message it jumps to it.
+ *
+ * Returns: TRUE if there is a next fuzzy message.
+ */
+gboolean
+gtranslator_tab_go_to_next_fuzzy (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	GList *msg;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	msg = gtranslator_po_get_next_fuzzy (po);
+	if(msg != NULL)
+	{
+		gtranslator_tab_message_go_to (tab, msg, FALSE,
+					       GTR_TAB_MOVE_NONE);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+/**
+ * gtranslator_tab_go_to_prev_fuzzy:
+ * @tab: a #GtranslatorTab
+ *
+ * If there is a prev fuzzy message it jumps to it.
+ *
+ * Returns: TRUE if there is a prev fuzzy message.
+ */
+gboolean
+gtranslator_tab_go_to_prev_fuzzy (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	GList *msg;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	msg = gtranslator_po_get_prev_fuzzy (po);
+	if(msg != NULL)
+	{
+		gtranslator_tab_message_go_to (tab, msg, FALSE,
+					       GTR_TAB_MOVE_NONE);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+/**
+ * gtranslator_tab_go_to_next_untrans:
+ * @tab: a #GtranslatorTab
+ *
+ * If there is a next untranslated message it jumps to it.
+ *
+ * Returns: TRUE if there is a next untranslated message.
+ */
+gboolean
+gtranslator_tab_go_to_next_untrans (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	GList *msg;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	msg = gtranslator_po_get_next_untrans (po);
+	if(msg != NULL)
+	{
+		gtranslator_tab_message_go_to (tab, msg, FALSE,
+					       GTR_TAB_MOVE_NONE);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+/**
+ * gtranslator_tab_go_to_prev_untrans:
+ * @tab: a #GtranslatorTab
+ *
+ * If there is a prev untranslated message it jumps to it.
+ *
+ * Returns: TRUE if there is a prev untranslated message.
+ */
+gboolean
+gtranslator_tab_go_to_prev_untrans (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	GList *msg;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	msg = gtranslator_po_get_prev_untrans (po);
+	if(msg != NULL)
+	{
+		gtranslator_tab_message_go_to (tab, msg, FALSE,
+					       GTR_TAB_MOVE_NONE);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+/**
+ * gtranslator_tab_go_to_next_fuzzy_or_untrans:
+ * @tab: a #GtranslatorTab
+ *
+ * If there is a next fuzzy or untranslated message it jumps to it.
+ *
+ * Returns: TRUE if there is a next fuzzy or untranslated message.
+ */
+gboolean
+gtranslator_tab_go_to_next_fuzzy_or_untrans (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	GList *msg;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	msg = gtranslator_po_get_next_fuzzy_or_untrans (po);
+	if(msg != NULL)
+	{
+		gtranslator_tab_message_go_to (tab, msg, FALSE,
+					       GTR_TAB_MOVE_NONE);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+/**
+ * gtranslator_tab_go_to_prev_fuzzy_or_untrans:
+ * @tab: a #GtranslatorTab
+ *
+ * If there is a prev fuzzy or untranslated message it jumps to it.
+ *
+ * Returns: TRUE if there is a prev fuzzy or untranslated message.
+ */
+gboolean
+gtranslator_tab_go_to_prev_fuzzy_or_untrans (GtranslatorTab *tab)
+{
+	GtranslatorPo *po;
+	GList *msg;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	msg = gtranslator_po_get_prev_fuzzy_or_untrans (po);
+	if(msg != NULL)
+	{
+		gtranslator_tab_message_go_to (tab, msg, FALSE,
+					       GTR_TAB_MOVE_NONE);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+/**
+ * gtranslator_tab_go_to_number:
+ * @tab: a #GtranslatorTab
+ * @number: the message number you want to jump
+ *
+ * Jumps to the message with the @number in the list, if the message does not
+ * exists it does not jump.
+ */
+void
+gtranslator_tab_go_to_number (GtranslatorTab *tab,
+			      gint number)
+{
+	GtranslatorPo *po;
+	GList *msg;
+	
+	po = gtranslator_tab_get_po (tab);
+	
+	msg = gtranslator_po_get_msg_from_number (po, number);
+	if(msg != NULL)
+	{
+		gtranslator_tab_message_go_to (tab, msg, FALSE,
+					       GTR_TAB_MOVE_NONE);
+	}
+}
+
+/**
+ * gtranslator_tab_set_message_area:
+ * @tab: a #GtranslatorTab
+ * @message_area: a #GtranslatorMessageArea
+ *
+ * Sets the @message_area to be shown in the @tab.
+ */
+void
+gtranslator_tab_set_message_area (GtranslatorTab  *tab,
+				  GtkWidget *message_area)
+{
+	g_return_if_fail (GTR_IS_TAB (tab));
+	
+        if (tab->priv->message_area == message_area)
+                return;
+
+        if (tab->priv->message_area != NULL)
+                gtk_widget_destroy (tab->priv->message_area);
+
+        tab->priv->message_area = message_area;
+
+        if (message_area == NULL)
+                return;
+
+        gtk_box_pack_start (GTK_BOX (tab),
+                            tab->priv->message_area,
+                            FALSE,
+                            FALSE,
+                            0);
+
+        g_object_add_weak_pointer (G_OBJECT (tab->priv->message_area), 
+                                   (gpointer *)&tab->priv->message_area);
+}
\ No newline at end of file

Modified: trunk/src/tab.h
==============================================================================
--- trunk/src/tab.h	(original)
+++ trunk/src/tab.h	Tue Sep 16 07:58:13 2008
@@ -23,7 +23,7 @@
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
-#include "comment.h"
+#include "context.h"
 #include "msg.h"
 #include "po.h"
 #include "view.h"
@@ -69,8 +69,17 @@
 				  GtranslatorMsg *msg);
 	void (* message_changed) (GtranslatorTab *tab,
 				  GtranslatorMsg *msg);
+	void (* message_edition_finished)  (GtranslatorTab *tab,
+					    GtranslatorMsg *msg);
 };
 
+typedef enum
+{
+	GTR_TAB_MOVE_NONE,
+	GTR_TAB_MOVE_NEXT,
+	GTR_TAB_MOVE_PREV
+}GtranslatorTabMove;
+
 /*
  * Public methods
  */
@@ -84,11 +93,11 @@
 
 GtkWidget             *gtranslator_tab_get_panel           (GtranslatorTab *tab);
 
-gint                   gtranslator_tab_get_active_text_tab (GtranslatorTab *tab);
-
 gint                   gtranslator_tab_get_active_trans_tab(GtranslatorTab *tab);
 
-GtranslatorCommentPanel *gtranslator_tab_get_comment_panel   (GtranslatorTab *tab);
+GtranslatorContextPanel *gtranslator_tab_get_context_panel (GtranslatorTab *tab);
+
+GtkWidget             *gtranslator_tab_get_translation_memory_ui (GtranslatorTab *tab);
 
 GtranslatorView       *gtranslator_tab_get_active_view     (GtranslatorTab *tab);
 
@@ -99,9 +108,63 @@
 gchar                 *gtranslator_tab_get_name            (GtranslatorTab *tab);
 
 void                   gtranslator_tab_message_go_to       (GtranslatorTab *tab,
-							    GList * to_go);
+							    GList * to_go,
+							    gboolean searching,
+							    GtranslatorTabMove move);
 							    
 GtranslatorTab        *gtranslator_tab_get_from_document   (GtranslatorPo *po);
+
+gboolean               gtranslator_tab_get_autosave_enabled (GtranslatorTab *tab);
+
+void                   gtranslator_tab_set_autosave_enabled (GtranslatorTab *tab, 
+							     gboolean enable);
+
+gint                   gtranslator_tab_get_autosave_interval (GtranslatorTab *tab);
+
+void                   gtranslator_tab_set_autosave_interval (GtranslatorTab *tab, 
+							      gint interval);
+
+void                   gtranslator_tab_add_widget_to_lateral_panel (GtranslatorTab *tab,
+								    GtkWidget *widget,
+								    const gchar *tab_name);
+
+void                   gtranslator_tab_remove_widget_from_lateral_panel (GtranslatorTab *tab,
+									 GtkWidget *widget);
+
+void                   gtranslator_tab_show_lateral_panel_widget (GtranslatorTab *tab,
+								  GtkWidget *widget);
+
+void                   gtranslator_tab_clear_msgstr_views  (GtranslatorTab *tab);
+
+void                   gtranslator_tab_block_movement      (GtranslatorTab *tab);
+
+void                   gtranslator_tab_unblock_movement    (GtranslatorTab *tab);
+
+void                   gtranslator_tab_go_to_next          (GtranslatorTab *tab);
+
+void                   gtranslator_tab_go_to_prev          (GtranslatorTab *tab);
+
+void                   gtranslator_tab_go_to_first         (GtranslatorTab *tab);
+
+void                   gtranslator_tab_go_to_last          (GtranslatorTab *tab);
+
+gboolean               gtranslator_tab_go_to_next_fuzzy    (GtranslatorTab *tab);
+
+gboolean               gtranslator_tab_go_to_prev_fuzzy    (GtranslatorTab *tab);
+
+gboolean               gtranslator_tab_go_to_next_untrans  (GtranslatorTab *tab);
+
+gboolean               gtranslator_tab_go_to_prev_untrans  (GtranslatorTab *tab);
+
+gboolean               gtranslator_tab_go_to_next_fuzzy_or_untrans (GtranslatorTab *tab);
+
+gboolean               gtranslator_tab_go_to_prev_fuzzy_or_untrans (GtranslatorTab *tab);
+
+void                   gtranslator_tab_go_to_number        (GtranslatorTab *tab,
+							    gint number);
+
+void                   gtranslator_tab_set_message_area    (GtranslatorTab  *tab,
+							    GtkWidget *message_area);
 							    
 gboolean              _gtranslator_tab_can_close           (GtranslatorTab *tab);
 

Modified: trunk/src/toolbareditor/egg-editable-toolbar.c
==============================================================================
--- trunk/src/toolbareditor/egg-editable-toolbar.c	(original)
+++ trunk/src/toolbareditor/egg-editable-toolbar.c	Tue Sep 16 07:58:13 2008
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- *  $Id: egg-editable-toolbar.c 826 2007-08-16 08:05:50Z carlosgc $
+ *  $Id: egg-editable-toolbar.c 891 2008-08-08 21:14:52Z friemann $
  */
 
 #include "config.h"
@@ -25,26 +25,7 @@
 #include "egg-toolbars-model.h"
 #include "egg-toolbar-editor.h"
 
-#include <gtk/gtkvseparator.h>
-#include <gtk/gtkiconfactory.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtkdnd.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtktoggleaction.h>
-#include <gtk/gtkcheckmenuitem.h>
-#include <gtk/gtkimagemenuitem.h>
-#include <gtk/gtkseparatormenuitem.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtkstock.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkbutton.h>
-#include <gtk/gtktoolbar.h>
-#include <gtk/gtktoolitem.h>
-#include <gtk/gtktoolbutton.h>
-#include <gtk/gtkseparatortoolitem.h>
-#include <gtk/gtkicontheme.h>
+#include <gtk/gtk.h>
 #include <glib/gi18n.h>
 #include <string.h>
 
@@ -935,7 +916,7 @@
        * produce duplicates, but don't worry about it. If your language
        * normally has a mnemonic at the start, please use the _. If not,
        * please remove. */
-      action_label = g_strdup_printf (_("Show \"_%s\""), tmp);
+      action_label = g_strdup_printf (_("Show â_%sâ"), tmp);
       g_free (tmp);
       
       sprintf(action_name, "ToolbarToggle%d", i);
@@ -1827,7 +1808,7 @@
 }
 
 static GdkPixbuf *
-new_separator_pixbuf ()
+new_separator_pixbuf (void)
 {
   GtkWidget *separator;
   GdkPixbuf *pixbuf;

Modified: trunk/src/toolbareditor/egg-editable-toolbar.h
==============================================================================
--- trunk/src/toolbareditor/egg-editable-toolbar.h	(original)
+++ trunk/src/toolbareditor/egg-editable-toolbar.h	Tue Sep 16 07:58:13 2008
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- *  $Id: egg-editable-toolbar.h 813 2007-07-01 12:58:48Z jhaitsma $
+ *  $Id: egg-editable-toolbar.h 891 2008-08-08 21:14:52Z friemann $
  */
 
 #ifndef EGG_EDITABLE_TOOLBAR_H
@@ -24,12 +24,7 @@
 
 #include "egg-toolbars-model.h"
 
-#include <gtk/gtkuimanager.h>
-#include <gtk/gtkselection.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtktoolitem.h>
-#include <gtk/gtktoolbar.h>
-#include <gtk/gtkmenu.h>
+#include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 

Modified: trunk/src/toolbareditor/egg-toolbar-editor.c
==============================================================================
--- trunk/src/toolbareditor/egg-toolbar-editor.c	(original)
+++ trunk/src/toolbareditor/egg-toolbar-editor.c	Tue Sep 16 07:58:13 2008
@@ -15,7 +15,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- *  $Id: egg-toolbar-editor.c 832 2007-11-03 22:14:56Z friemann $
+ *  $Id: egg-toolbar-editor.c 891 2008-08-08 21:14:52Z friemann $
  */
 
 #include "config.h"
@@ -25,14 +25,6 @@
 
 #include <string.h>
 #include <libxml/tree.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkeventbox.h>
-#include <gtk/gtkdnd.h>
-#include <gtk/gtkscrolledwindow.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtktable.h>
-#include <gtk/gtkstock.h>
-#include <gtk/gtkhbox.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
 
@@ -174,10 +166,12 @@
 egg_toolbar_editor_set_model (EggToolbarEditor *t,
 			      EggToolbarsModel *model)
 {
+  EggToolbarEditorPrivate *priv;
+
   g_return_if_fail (EGG_IS_TOOLBAR_EDITOR (t));
   g_return_if_fail (model != NULL);
 
-  EggToolbarEditorPrivate *priv = t->priv;
+  priv = t->priv;
 
   if (priv->model)
     {

Modified: trunk/src/toolbareditor/egg-toolbar-editor.h
==============================================================================
--- trunk/src/toolbareditor/egg-toolbar-editor.h	(original)
+++ trunk/src/toolbareditor/egg-toolbar-editor.h	Tue Sep 16 07:58:13 2008
@@ -19,8 +19,7 @@
 #ifndef EGG_TOOLBAR_EDITOR_H
 #define EGG_TOOLBAR_EDITOR_H
 
-#include <gtk/gtkvbox.h>
-#include <gtk/gtkuimanager.h>
+#include <gtk/gtk.h>
 
 #include "egg-toolbars-model.h"
 

Modified: trunk/src/toolbareditor/egg-toolbars-model.c
==============================================================================
--- trunk/src/toolbareditor/egg-toolbars-model.c	(original)
+++ trunk/src/toolbareditor/egg-toolbars-model.c	Tue Sep 16 07:58:13 2008
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- *  $Id: egg-toolbars-model.c 815 2007-07-02 15:02:15Z friemann $
+ *  $Id: egg-toolbars-model.c 891 2008-08-08 21:14:52Z friemann $
  */
 
 #include "config.h"
@@ -28,7 +28,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <libxml/tree.h>
-#include <gdk/gdkproperty.h>
+#include <gdk/gdk.h>
 
 static void egg_toolbars_model_finalize   (GObject               *object);
 

Modified: trunk/src/toolbareditor/egg-toolbars-model.h
==============================================================================
--- trunk/src/toolbareditor/egg-toolbars-model.h	(original)
+++ trunk/src/toolbareditor/egg-toolbars-model.h	Tue Sep 16 07:58:13 2008
@@ -15,7 +15,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  * 
- *  $Id: egg-toolbars-model.h 813 2007-07-01 12:58:48Z jhaitsma $
+ *  $Id: egg-toolbars-model.h 891 2008-08-08 21:14:52Z friemann $
  */
 
 #ifndef EGG_TOOLBARS_MODEL_H
@@ -23,7 +23,7 @@
 
 #include <glib.h>
 #include <glib-object.h>
-#include <gdk/gdktypes.h>
+#include <gdk/gdk.h>
 
 G_BEGIN_DECLS
 

Modified: trunk/src/toolbareditor/eggtreemultidnd.c
==============================================================================
--- trunk/src/toolbareditor/eggtreemultidnd.c	(original)
+++ trunk/src/toolbareditor/eggtreemultidnd.c	Tue Sep 16 07:58:13 2008
@@ -18,10 +18,7 @@
  */
 
 #include <string.h>
-#include <gtk/gtktreeselection.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkmain.h>
+#include <gtk/gtk.h>
 #include "eggtreemultidnd.h"
 
 #define EGG_TREE_MULTI_DND_STRING "EggTreeMultiDndString"

Modified: trunk/src/toolbareditor/eggtreemultidnd.h
==============================================================================
--- trunk/src/toolbareditor/eggtreemultidnd.h	(original)
+++ trunk/src/toolbareditor/eggtreemultidnd.h	Tue Sep 16 07:58:13 2008
@@ -20,9 +20,7 @@
 #ifndef __EGG_TREE_MULTI_DND_H__
 #define __EGG_TREE_MULTI_DND_H__
 
-#include <gtk/gtktreemodel.h>
-#include <gtk/gtktreeview.h>
-#include <gtk/gtkdnd.h>
+#include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 

Added: trunk/src/translation-memory/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,45 @@
+SUBDIRS = berkeley
+
+INCLUDES =                                                      \
+        -I$(top_srcdir)                                         \
+        -I$(top_builddir)                                       \
+        -I$(top_srcdir)/src                                     \
+        -I$(top_builddir)/src                                   \
+	-I$(headerdir)						\
+	-DPIXMAPSDIR=\""$(datadir)"/pixmaps/gtranslator\"       \
+        $(GTRANSLATOR_CFLAGS)                                   \
+        $(WARN_CFLAGS)                                          \
+        $(DISABLE_DEPRECATED_CFLAGS)
+
+noinst_LTLIBRARIES = \
+	libtranslationmemory.la
+
+INST_H_FILES = \
+	translation-memory.h \
+	translation-memory-ui.h
+
+headerdir = $(prefix)/include/gtranslator- GTR_API_VERSION@/gtranslator
+
+header_DATA = \
+	$(INST_H_FILES)	
+
+libtranslationmemory_la_SOURCES = \
+	$(INST_H_FILES) \
+	translation-memory.c \
+	translation-memory-ui.c
+
+libtranslationmemory_la_CFLAGS = \
+	$(GTRANSLATOR_CFLAGS)			\
+	$(WARN_CFLAGS)				\
+	$(DISABLE_DEPRECATED)			\
+	-DCURSOR_DIR=\"$(pkgdatadir)\"		\
+	$(AM_CFLAGS)
+
+libtranslationmemory_la_LDFLAGS = \
+	-export-dynamic
+
+libtranslationmemory_la_LIBADD = \
+	berkeley/libberkeley.la
+
+EXTRA_DIST = $(pixmaps__DATA)
+

Added: trunk/src/translation-memory/berkeley/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/Makefile.am	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,38 @@
+INCLUDES =                                                      \
+        -I$(top_srcdir)                                         \
+        -I$(top_builddir)                                       \
+        -I$(top_srcdir)/src                                     \
+        -I$(top_builddir)/src                                   \
+        -I$(top_srcdir)/src/translation-memory                  \
+	-I$(headerdir)						\
+	-DPIXMAPSDIR=\""$(datadir)"/pixmaps/gtranslator\"       \
+        $(GTRANSLATOR_CFLAGS)                                   \
+        $(WARN_CFLAGS)                                          \
+        $(DISABLE_DEPRECATED_CFLAGS)
+
+noinst_LTLIBRARIES = \
+	libberkeley.la
+
+libberkeley_la_SOURCES = \
+	berkeley.c \
+	berkeley.h \
+	db-base.h \
+	db-base.c \
+	db-trans.h \
+	db-trans.c \
+	db-orig.h \
+	db-orig.c \
+	db-words.h \
+	db-words.c \
+	db-keys.h \
+	db-keys.c
+
+libberkeley_la_CFLAGS = \
+	$(GTRANSLATOR_CFLAGS)			\
+	$(WARN_CFLAGS)				\
+	$(DISABLE_DEPRECATED)			\
+	-DCURSOR_DIR=\"$(pkgdatadir)\"		\
+	$(AM_CFLAGS)
+
+EXTRA_DIST = $(pixmaps__DATA)
+

Added: trunk/src/translation-memory/berkeley/berkeley.c
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/berkeley.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,638 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based in poedit transmem.cpp file:
+ *     Copyright (C) 2001-2007 Vaclav Slavik
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "berkeley.h"
+#include "translation-memory.h"
+#include DB_HEADER //This can be something like <db.h>
+#include "db-trans.h"
+#include "db-orig.h"
+#include "db-words.h"
+#include "utils.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#define GTR_BERKELEY_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 (object),		       \
+						 GTR_TYPE_BERKELEY,            \
+						 GtranslatorBerkeleyPrivate))
+
+static void gtranslator_translation_memory_iface_init (GtranslatorTranslationMemoryIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtranslatorBerkeley,
+			 gtranslator_berkeley,
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (GTR_TYPE_TRANSLATION_MEMORY,
+				 		gtranslator_translation_memory_iface_init))
+
+struct _GtranslatorBerkeleyPrivate
+{
+	GtranslatorDbOrig *orig;
+	GtranslatorDbTrans *trans;
+	GtranslatorDbWords *words;
+	
+	gsize max_omits;
+	gsize max_delta;
+	gint max_items;
+};
+
+static gboolean
+gtranslator_berkeley_store (GtranslatorTranslationMemory *tm,
+			    const gchar *original,
+			    const gchar *translation)
+{
+	GtranslatorBerkeley *ber = GTR_BERKELEY (tm);
+	gboolean ok;
+	db_recno_t key;
+	
+	g_return_val_if_fail (GTR_IS_BERKELEY (ber), FALSE);
+	
+	key = gtranslator_db_orig_read (ber->priv->orig,
+					original);
+	if (key == 0)
+	{
+		key = gtranslator_db_trans_write_string (ber->priv->trans,
+							 translation, 0);
+
+		ok = (key != 0) && gtranslator_db_orig_write (ber->priv->orig, original, key);
+		if (ok)
+		{
+			gchar **words = NULL;
+			gsize i;
+			
+			words = gtranslator_utils_split_string_in_words (original);
+			gsize sz = g_strv_length (words);
+			
+			for (i = 0; i < sz; i++)
+				gtranslator_db_words_append (ber->priv->words,
+							     words[i],
+							     sz,
+							     key);
+			g_strfreev (words);
+		}
+		return ok;
+	}
+	else
+	{
+		gboolean found = FALSE;
+		gint i = 0;
+		gchar *translation_collate;
+		GPtrArray *t = gtranslator_db_trans_read (ber->priv->trans,
+							  key);
+		if (!t)
+			return FALSE;
+		
+		translation_collate = g_utf8_collate_key (translation, -1);
+		// -1 because we know that last element is NULL
+		while (i < t->len - 1)
+		{
+			gchar *array_word = g_utf8_collate_key (g_ptr_array_index (t, i), -1);
+			
+			if (strcmp (array_word, translation_collate) == 0)
+			{
+				found = TRUE;
+				g_free (array_word);
+				break;
+			}
+			
+			g_free (array_word);
+			i++;
+		}
+		g_free (translation_collate);
+		
+		if (!found)
+		{
+			gchar **translations = NULL;
+			
+			/*
+			 * We remove the previous NULL data and then we add the new data
+			 */
+			g_ptr_array_remove_index (t, t->len-1);
+			g_ptr_array_add (t, g_strdup (translation));
+			g_ptr_array_add (t, NULL);
+			
+			translations = (gchar **)g_ptr_array_free (t, FALSE);
+			
+			db_recno_t key2 = gtranslator_db_trans_write (ber->priv->trans,
+								      translations,
+								      key);
+			g_strfreev (translations);
+			ok = (key2 != 0);
+		}
+		else
+		{
+			ok = TRUE;
+			g_ptr_array_free (t, TRUE);
+		}
+
+		return ok;
+	}
+}
+
+static GtranslatorDbKeys *
+union_of_db_keys (GtranslatorBerkeley *ber,
+		  gsize cnt,
+		  GtranslatorDbKeys **keys,
+		  gboolean *mask)
+{
+	gsize i, minSize;
+	db_recno_t **heads = g_new (db_recno_t *, cnt);
+	gsize *counters = g_new (gsize, cnt);
+	GtranslatorDbKeys *result;
+	db_recno_t *res_list;
+
+	// initialize heads and counters _and_ find size of smallest keys list
+	// (union can't be larger than that)
+	for (minSize = 0, i = 0; i < cnt; i++)
+	{
+		if (mask[i])
+		{
+			gsize count = gtranslator_db_keys_get_count (keys[i]);
+			db_recno_t * list = gtranslator_db_keys_get_list (keys[i]);
+			
+			counters[i] = count;
+			heads[i] = list;
+			if (minSize == 0 || minSize > count)
+				minSize = count;
+		}
+		else
+		{
+			counters[i] = 0;
+			heads[i] = NULL;
+		}
+	}
+	if (minSize == 0)
+	{
+		g_free (counters);
+		g_free (heads);
+
+		return NULL;
+	}
+	
+	result = gtranslator_db_keys_new_with_size (minSize);
+	res_list = gtranslator_db_keys_get_list (result);
+	gsize res_count = 0;
+	
+	// Do union of 'cnt' sorted arrays. Algorithm: treat arrays as lists,
+	// remember pointer to first unprocessed item. In each iteration, do:
+	// if all heads have same value, add that value to output list, otherwise
+	// move the head with smallest value one item forward. (This way we won't
+	// miss any value that could possibly be in the output list, because 
+	// if the smallest value of all heads is not at the beginning of other
+	// lists, it cannot appear later in these lists due to their sorted nature.
+	// We end processing when any head reaches end of (its) list
+	db_recno_t smallestValue;
+	gsize smallestIndex = 0;
+	gboolean allSame;
+	for (;;)
+	{
+		allSame = TRUE;
+		smallestValue = 0;
+		
+		for (i = 0; i < cnt; i++)
+		{
+			if (counters[i] == 0)
+				continue;
+			if (smallestValue == 0)
+			{
+				smallestValue = *heads[i];
+				smallestIndex = i;
+			}
+			else if (smallestValue != *heads[i])
+			{
+				allSame = FALSE;
+				if (smallestValue > *heads[i])
+				{
+					smallestValue = *heads[i];
+					smallestIndex = i;
+				}
+			}
+		}
+		
+		if (smallestValue == 0)
+			break;
+		
+		if (allSame)
+		{
+			gboolean breakMe = FALSE;
+			res_list[res_count++] = smallestValue;
+			for (i = 0; i < cnt; i++)
+			{
+				if (counters[i] == 0)
+					continue;
+				if (--counters[i] == 0)
+				{
+					breakMe = TRUE;
+					break;
+				}
+				heads[i]++;
+			}
+			if (breakMe)
+				break;
+		}
+		else
+		{
+			if (--counters[smallestIndex] == 0)
+				break;
+			heads[smallestIndex]++;
+		}
+	}
+	
+	g_free (counters);
+	g_free (heads);
+	if (res_count == 0)
+	{
+		g_object_unref (result);
+		result = NULL;
+	}
+	else gtranslator_db_keys_set_count (result, res_count);
+	
+	return result;
+}
+
+static gboolean
+advance_cycle (gsize omitted[],
+	       gsize depth,
+	       gsize cnt)
+{
+	if (++omitted[depth] == cnt)
+	{
+		if (depth == 0) 
+			return FALSE;
+		depth--;
+		if (!advance_cycle (omitted, depth, cnt))
+			return FALSE;
+		depth++;
+		omitted[depth] = omitted[depth - 1] + 1;
+		if (omitted[depth] >= cnt)
+			return FALSE;
+		return TRUE;
+	}
+	else
+		return TRUE;
+}
+
+static gboolean
+look_fuzzy (GtranslatorBerkeley *ber,
+	    gchar **words,
+	    GHashTable **hash,
+	    gsize omits,
+	    gsize delta)
+{
+#define RETURN_WITH_CLEANUP(val) \
+	for (i = 0; i < cnt_orig; i++) \
+		if (keys[i]) \
+			g_object_unref (keys[i]); \
+	g_free (keys); \
+	g_free (mask); \
+	g_free (omitted); \
+	return (val);
+
+	gsize i, slot;
+	gsize missing;
+	GtranslatorDbKeys **keys;
+	gboolean *mask;
+	gsize *omitted;
+	gsize cnt = g_strv_length (words);
+	gsize cnt_orig = cnt;
+	GtranslatorDbKeys *result;
+	
+	if (omits >= cnt)
+		return FALSE;
+	if (cnt + delta <= 0)
+		return FALSE;
+	
+	keys = g_new (GtranslatorDbKeys *, cnt);
+	mask = g_new (gboolean, cnt);
+	omitted = g_new (gsize, omits);
+	
+	for (missing = 0, slot = 0, i = 0; i < cnt; i++)
+	{
+		keys[i] = NULL; // so that unused entries are NULL
+		keys[slot] = gtranslator_db_words_read (ber->priv->words,
+							words[i], cnt + delta);
+		if (keys[slot])
+			slot++;
+		else
+			missing++;
+	}
+	
+	if (missing >= cnt || missing > omits)
+	{
+		RETURN_WITH_CLEANUP(FALSE)
+	}
+	cnt -= missing;
+	omits -= missing;
+
+	if (omits == 0)
+	{
+		for (i = 0; i < cnt; i++)
+			mask[i] = TRUE;
+		
+		result = union_of_db_keys (ber, cnt,
+					   keys, mask);
+		if (result != NULL)
+		{
+			GPtrArray *array;
+			
+			db_recno_t *list = gtranslator_db_keys_get_list (result);
+			for (i = 0; i < gtranslator_db_keys_get_count (result); i++)
+			{	
+				array = gtranslator_db_trans_read (ber->priv->trans,
+								   list[i]);
+				if (array)
+				{
+					gint j = 0;
+					gint score = 0;
+					
+					score = (ber->priv->max_omits - omits) * 100 / 
+						(ber->priv->max_omits + 1) +
+						(ber->priv->max_delta - delta) * 100 /
+						((ber->priv->max_delta + 1) *
+						 (ber->priv->max_delta + 1));
+					
+					if (score == 0)
+						score = 1;
+
+					while (j < array->len -1)
+					{
+						gchar *string;
+						
+						string = (gchar *)g_ptr_array_index (array, j);
+						
+						/* The first adding is always better */
+						if (!g_hash_table_lookup (*hash, string))
+							g_hash_table_insert (*hash, string,
+									     GINT_TO_POINTER (score));
+
+						j++;
+					}
+					g_ptr_array_free (array, TRUE);
+				}
+			}
+			g_object_unref (result);
+			RETURN_WITH_CLEANUP(TRUE)
+		}
+	}
+	else
+	{
+		gsize depth = omits - 1;
+		
+		for (i = 0; i < omits; i++)
+			omitted[i] = i;
+		for (;;)
+		{
+			for (i = 0; i < cnt; i++)
+				mask[i] = TRUE;
+			for (i = 0; i < omits; i++)
+				mask[omitted[i]] = FALSE;
+			
+			result = union_of_db_keys (ber, cnt, keys, mask);
+			if (result != NULL)
+			{		
+				GPtrArray *array;
+				
+				db_recno_t *list = gtranslator_db_keys_get_list (result);
+				for (i = 0; i < gtranslator_db_keys_get_count (result); i++)
+				{
+					array = gtranslator_db_trans_read (ber->priv->trans,
+									   list[i]);
+					if (array)
+					{
+						gint j = 0;
+						gint score = 0;
+						
+						score = (ber->priv->max_omits - omits) * 100 / 
+							(ber->priv->max_omits + 1) +
+							(ber->priv->max_delta - delta) * 100 /
+							((ber->priv->max_delta + 1) *
+							 (ber->priv->max_delta + 1));
+						
+						if (score == 0)
+							score = 1;
+						
+						while (j < array->len -1)
+						{
+							gchar *string;
+							
+							string = (gchar *)g_ptr_array_index (array, j);
+							
+							if (!g_hash_table_lookup (*hash, string))
+								g_hash_table_insert (*hash, string,
+										     GINT_TO_POINTER (score));
+							
+							j++;
+						}
+						g_ptr_array_free (array, TRUE);
+					}
+				}
+				g_object_unref (result);
+				RETURN_WITH_CLEANUP(TRUE)
+			}
+			
+			if (!advance_cycle (omitted, depth, cnt))
+				break;
+		}
+	}
+	RETURN_WITH_CLEANUP(FALSE)
+}
+
+static gint
+insert_match_sorted (gconstpointer a,
+		     gconstpointer b)
+{
+	GtranslatorTranslationMemoryMatch *match1 = (GtranslatorTranslationMemoryMatch *)a;
+	GtranslatorTranslationMemoryMatch *match2 = (GtranslatorTranslationMemoryMatch *)b;
+	
+	if (match1->level < match2->level)
+		return 1;
+	else if (match1->level > match2->level)
+		return -1;
+	else
+		return 0;
+}
+
+static GList *
+gtranslator_berkeley_lookup (GtranslatorTranslationMemory *tm,
+			     const gchar *phrase)
+{
+	GPtrArray *array = NULL;
+	gchar **words;
+	gsize omits;
+	gsize delta;
+	GtranslatorBerkeley *ber = GTR_BERKELEY (tm);
+	GHashTable *hash;
+	GHashTableIter iter;
+	gpointer hkey, value;
+	GList *matches = NULL;
+	
+	g_return_val_if_fail (GTR_IS_BERKELEY (ber), NULL);
+	
+	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+	
+	// First of all, try exact match:
+	db_recno_t key = gtranslator_db_orig_read (ber->priv->orig, phrase);
+	if (key != 0)
+	{
+		gint i = 0;
+		
+		array = gtranslator_db_trans_read (ber->priv->trans,
+						   key);
+		
+		if (array != NULL)
+		{
+			while (i < array->len -1 && i < ber->priv->max_items)
+			{
+				g_hash_table_insert (hash, g_strdup (g_ptr_array_index (array, i)),
+						     GINT_TO_POINTER (100));
+				i++;
+			}
+			
+			g_ptr_array_free (array, TRUE);
+		
+			goto list;
+		}
+	}
+	
+	// Then, try to find inexact one within defined limits
+	// (MAX_OMITS is max permitted number of unmatched words,
+	// MAX_DELTA is max difference in sentences lengths).
+	// Start with best matches first, continue to worse ones.
+	words = gtranslator_utils_split_string_in_words (phrase);
+	for (omits = 0; omits <= ber->priv->max_omits && g_hash_table_size (hash) < ber->priv->max_items; omits++)
+	{
+		for (delta = 0; delta <= ber->priv->max_delta && g_hash_table_size (hash) < ber->priv->max_items; delta++)
+		{
+			look_fuzzy (ber, words, &hash, omits, delta);
+		}
+	}
+	
+list:   g_hash_table_iter_init (&iter, hash);
+	while (g_hash_table_iter_next (&iter, &hkey, &value)) 
+	{
+		GtranslatorTranslationMemoryMatch *match = g_new (GtranslatorTranslationMemoryMatch, 1);
+		match->match = g_strdup (hkey);
+		match->level = GPOINTER_TO_INT (value);
+		
+		matches = g_list_prepend (matches, match);
+	}
+	matches = g_list_sort (matches, (GCompareFunc)insert_match_sorted);
+
+	g_hash_table_unref (hash);
+	
+	return matches;
+}
+
+static void
+gtranslator_berkeley_set_max_omits (GtranslatorTranslationMemory *tm,
+				    gsize omits)
+{
+	GtranslatorBerkeley *ber = GTR_BERKELEY (tm);
+	
+	ber->priv->max_omits = omits;
+}
+
+static void
+gtranslator_berkeley_set_max_delta (GtranslatorTranslationMemory *tm,
+				    gsize delta)
+{
+	GtranslatorBerkeley *ber = GTR_BERKELEY (tm);
+	
+	ber->priv->max_delta = delta;
+}
+
+static void
+gtranslator_berkeley_set_max_items (GtranslatorTranslationMemory *tm,
+				    gint items)
+{
+	GtranslatorBerkeley *ber = GTR_BERKELEY (tm);
+	
+	ber->priv->max_items = items;
+}
+
+static void
+gtranslator_translation_memory_iface_init (GtranslatorTranslationMemoryIface *iface)
+{
+	iface->store = gtranslator_berkeley_store;
+	iface->lookup = gtranslator_berkeley_lookup;
+	iface->set_max_omits = gtranslator_berkeley_set_max_omits;
+	iface->set_max_delta = gtranslator_berkeley_set_max_delta;
+	iface->set_max_items = gtranslator_berkeley_set_max_items;
+}
+
+static void
+gtranslator_berkeley_init (GtranslatorBerkeley *pf)
+{
+	pf->priv = GTR_BERKELEY_GET_PRIVATE (pf);
+
+	pf->priv->orig = gtranslator_db_orig_new ();
+	pf->priv->trans = gtranslator_db_trans_new ();
+	pf->priv->words = gtranslator_db_words_new ();
+	pf->priv->max_omits = 0;
+	pf->priv->max_delta = 0;
+	pf->priv->max_items = 0;
+}
+
+static void
+gtranslator_berkeley_finalize (GObject *object)
+{
+	GtranslatorBerkeley *ber = GTR_BERKELEY (object);
+	
+	g_object_unref (ber->priv->orig);
+	g_object_unref (ber->priv->trans);
+	g_object_unref (ber->priv->words);
+	
+	G_OBJECT_CLASS (gtranslator_berkeley_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_berkeley_class_init (GtranslatorBerkeleyClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorBerkeleyPrivate));
+
+	object_class->finalize = gtranslator_berkeley_finalize;
+}
+
+/**
+ * gtranslator_berkeley_new:
+ * 
+ * Creates a new #GtranslatorBerkeley object.
+ *
+ * Returns: a new #GtranslatorBerkeley object
+ */
+GtranslatorBerkeley *
+gtranslator_berkeley_new ()
+{
+	GtranslatorBerkeley *berkeley;
+
+	berkeley = g_object_new (GTR_TYPE_BERKELEY, NULL);
+	
+	return berkeley;
+}
+

Added: trunk/src/translation-memory/berkeley/berkeley.h
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/berkeley.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __BERKELEY_H__
+#define __BERKELEY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_BERKELEY		(gtranslator_berkeley_get_type ())
+#define GTR_BERKELEY(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_BERKELEY, GtranslatorBerkeley))
+#define GTR_BERKELEY_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_BERKELEY, GtranslatorBerkeleyClass))
+#define GTR_IS_BERKELEY(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_BERKELEY))
+#define GTR_IS_BERKELEY_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_BERKELEY))
+#define GTR_BERKELEY_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_BERKELEY, GtranslatorBerkeleyClass))
+
+/* Private structure type */
+typedef struct _GtranslatorBerkeleyPrivate	GtranslatorBerkeleyPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorBerkeley		GtranslatorBerkeley;
+
+struct _GtranslatorBerkeley
+{
+	GObject parent_instance;
+	
+	/*< private > */
+	GtranslatorBerkeleyPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorBerkeleyClass	GtranslatorBerkeleyClass;
+
+struct _GtranslatorBerkeleyClass
+{
+	GObjectClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_berkeley_get_type	  (void) G_GNUC_CONST;
+
+GType		 gtranslator_berkeley_register_type   (GTypeModule * module);
+
+GtranslatorBerkeley   *gtranslator_berkeley_new	  (void);
+
+G_END_DECLS
+
+#endif /* __BERKELEY_H__ */

Added: trunk/src/translation-memory/berkeley/db-base.c
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-base.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based in poedit transmem.cpp file:
+ *     Copyright (C) 2001-2007 Vaclav Slavik
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "utils.h"
+#include "db-base.h"
+#include DB_HEADER
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+#define GTR_DB_BASE_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 (object),		       \
+						 GTR_TYPE_DB_BASE,     \
+						 GtranslatorDbBasePrivate))
+
+G_DEFINE_TYPE(GtranslatorDbBase, gtranslator_db_base, G_TYPE_OBJECT)
+
+
+struct _GtranslatorDbBasePrivate
+{
+	DB *db;
+	gchar *path;
+};
+
+static gchar *
+get_db_base_directory ()
+{
+	gchar *config;
+	gchar *db_dir;
+	
+	config = gtranslator_utils_get_user_config_dir ();
+	
+	db_dir = g_build_filename (config, "berkeley", NULL);
+	g_free (config);
+	
+	if (!g_file_test (db_dir, G_FILE_TEST_IS_DIR))
+	{
+		GFile *file;
+		GError *error = NULL;
+		
+		file = g_file_new_for_path (db_dir);
+		
+		if (!g_file_make_directory (file, NULL, &error))
+		{
+			g_warning ("There was an error making the gtranslator berkeley directory: %s",
+				   error->message);
+					   
+			g_error_free (error);
+			g_object_unref (file);
+			g_free (db_dir);
+			return NULL;
+		}
+		
+		g_object_unref (file);
+	}
+	
+	return db_dir;
+}
+
+static void
+gtranslator_db_base_init (GtranslatorDbBase *base)
+{
+	base->priv = GTR_DB_BASE_GET_PRIVATE (base);
+	
+	base->priv->path = NULL;
+}
+
+static void
+gtranslator_db_base_finalize (GObject *object)
+{
+	GtranslatorDbBase *base = GTR_DB_BASE (object);
+	int err;
+	
+	if ((err = base->priv->db->close(base->priv->db, 0)) != 0)
+	       gtranslator_db_base_show_error (base, err);
+	
+	g_free (base->priv->path);
+	
+	G_OBJECT_CLASS (gtranslator_db_base_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_db_base_class_init (GtranslatorDbBaseClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorDbBasePrivate));
+
+	object_class->finalize = gtranslator_db_base_finalize;
+}
+
+void
+gtranslator_db_base_create_dabatase (GtranslatorDbBase *base,
+				     const gchar *filename,
+				     DBTYPE type)
+{
+	gint error;
+	gchar *db_dir;
+	
+	g_return_if_fail (GTR_IS_DB_BASE (base));
+	
+	error = db_create(&base->priv->db, NULL, 0);
+	if (error != 0)
+	{
+		gtranslator_db_base_show_error (base, error);
+		return;
+	}
+	
+	db_dir = get_db_base_directory ();
+	base->priv->path = g_build_filename (db_dir, filename, NULL);
+	g_free (db_dir);
+
+	error = base->priv->db->open (base->priv->db,
+				      NULL,
+				      base->priv->path,
+				      NULL,
+				      type,
+				      DB_CREATE,
+				      0);
+	
+	if (error != 0)
+	{
+		gtranslator_db_base_show_error (base, error);
+		return;
+	}
+}
+
+void
+gtranslator_db_base_show_error (GtranslatorDbBase *base,
+				int error)
+{
+	gchar *err = NULL;
+	DB_ENV *env;
+	gint e;
+	
+	switch (error)
+	{
+		case DB_NOTFOUND:
+			break;
+		case DB_RUNRECOVERY:
+			g_warning (_("Running recovery..."));
+			
+			env = base->priv->db->get_env (base->priv->db);
+			e = env->open (env, base->priv->path,
+				       DB_RECOVER_FATAL, 0);
+			
+			if (e != 0)
+			{
+				err = g_strdup_printf (_("There was an error recovering the database: %s"),
+						       db_strerror (e));
+				
+				g_warning (err);
+				g_free (err);
+			}
+			break;
+		default:
+			err = g_strdup_printf (_("There was an error in database: %s"),
+					       db_strerror (error));
+			
+			g_warning (err);
+			g_free (err);
+			break;
+	}
+}
+
+gint
+gtranslator_db_base_put (GtranslatorDbBase *base,
+			 DBT *key,
+			 DBT *data,
+			 u_int32_t flags)
+{
+	return base->priv->db->put (base->priv->db, NULL, key, data, flags);
+}
+
+gint
+gtranslator_db_base_get (GtranslatorDbBase *base,
+			 DBT *key,
+			 DBT *data)
+{
+	return base->priv->db->get (base->priv->db, NULL, key, data, 0);
+}

Added: trunk/src/translation-memory/berkeley/db-base.h
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-base.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DB_BASE_H__
+#define __DB_BASE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include DB_HEADER
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_DB_BASE		(gtranslator_db_base_get_type ())
+#define GTR_DB_BASE(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_DB_BASE, GtranslatorDbBase))
+#define GTR_DB_BASE_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_DB_BASE, GtranslatorDbBaseClass))
+#define GTR_IS_DB_BASE(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_DB_BASE))
+#define GTR_IS_DB_BASE_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_DB_BASE))
+#define GTR_DB_BASE_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_DB_BASE, GtranslatorDbBaseClass))
+
+/* Private structure type */
+typedef struct _GtranslatorDbBasePrivate	GtranslatorDbBasePrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorDbBase		GtranslatorDbBase;
+
+struct _GtranslatorDbBase
+{
+	GObject parent_instance;
+	
+	/*< private > */
+	GtranslatorDbBasePrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorDbBaseClass	GtranslatorDbBaseClass;
+
+struct _GtranslatorDbBaseClass
+{
+	GObjectClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_db_base_get_type	     (void) G_GNUC_CONST;
+
+GType		 gtranslator_db_base_register_type   (GTypeModule * module);
+
+void             gtranslator_db_base_create_dabatase (GtranslatorDbBase *base,
+						      const gchar *filename,
+						      DBTYPE type);
+						      
+void             gtranslator_db_base_show_error      (GtranslatorDbBase *base,
+						      gint error);
+						      
+gint             gtranslator_db_base_put             (GtranslatorDbBase *base,
+						      DBT *key,
+						      DBT *data,
+						      u_int32_t flags);
+						      
+gint             gtranslator_db_base_get             (GtranslatorDbBase *base,
+						      DBT *key,
+						      DBT *data);
+
+G_END_DECLS
+
+#endif /* __DB_BASE_H__ */

Added: trunk/src/translation-memory/berkeley/db-keys.c
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-keys.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based in poedit transmem.cpp file:
+ *     Copyright (C) 2001-2007 Vaclav Slavik
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "db-keys.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include DB_HEADER
+#include <string.h>
+
+#define GTR_DB_KEYS_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 (object),		       \
+						 GTR_TYPE_DB_KEYS,     \
+						 GtranslatorDbKeysPrivate))
+
+G_DEFINE_TYPE(GtranslatorDbKeys, gtranslator_db_keys, G_TYPE_OBJECT)
+
+
+struct _GtranslatorDbKeysPrivate
+{
+	db_recno_t *list;
+	gsize count;
+};
+
+static void
+gtranslator_db_keys_init (GtranslatorDbKeys *db_keys)
+{
+	db_keys->priv = GTR_DB_KEYS_GET_PRIVATE (db_keys);
+}
+
+static void
+gtranslator_db_keys_finalize (GObject *object)
+{
+	GtranslatorDbKeys *keys = GTR_DB_KEYS (object);
+	
+	g_free (keys->priv->list);
+	
+	G_OBJECT_CLASS (gtranslator_db_keys_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_db_keys_class_init (GtranslatorDbKeysClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorDbKeysPrivate));
+
+	object_class->finalize = gtranslator_db_keys_finalize;
+}
+
+/**
+ * gtranslator_db_keys_new:
+ * @data: the db_recno_t with the list of keys stored into it
+ *
+ * Creates a new #GtranslatorDbKeys object.
+ *
+ * Returns: a new #GtranslatorDbKeys object
+ */
+GtranslatorDbKeys *
+gtranslator_db_keys_new (DBT *data)
+{
+	GtranslatorDbKeys *db_keys;
+
+	db_keys = g_object_new (GTR_TYPE_DB_KEYS, NULL);
+	
+	db_keys->priv->count = data->size / sizeof(db_recno_t);
+	db_keys->priv->list = g_new (db_recno_t, db_keys->priv->count);
+	memcpy (db_keys->priv->list, data->data, data->size);
+	
+	return db_keys;
+}
+
+/**
+ * gtranslator_db_keys_new_with_size:
+ * @cnt: the number of element for the list
+ *
+ * Creates a new #GtranslatorDbKeys object with #cnt elements.
+ *
+ * Returns: a new #GtranslatorDbKeys object
+ */
+GtranslatorDbKeys *
+gtranslator_db_keys_new_with_size (gsize cnt)
+{
+	GtranslatorDbKeys *db_keys;
+
+	db_keys = g_object_new (GTR_TYPE_DB_KEYS, NULL);
+	
+	db_keys->priv->list = g_new (db_recno_t, cnt);
+	db_keys->priv->count = cnt;
+	
+	return db_keys;
+}
+
+/**
+ * gtranslator_db_keys_get_list:
+ * @db_keys: a #GtranslatorDbKeys
+ * 
+ * Gets the list of keys.
+ * 
+ * Returns: the list of keys
+ */
+db_recno_t *
+gtranslator_db_keys_get_list (GtranslatorDbKeys *db_keys)
+{
+	g_return_val_if_fail (GTR_IS_DB_KEYS (db_keys), NULL);
+	
+	return db_keys->priv->list;
+}
+
+/**
+ * gtranslator_db_keys_get_count:
+ * @db_keys: a #GtranslatorDbKeys
+ *
+ * Gets the number of elements in the list.
+ *
+ * Returns: the number of elements in the list
+ */
+gsize
+gtranslator_db_keys_get_count (GtranslatorDbKeys *db_keys)
+{
+	g_return_val_if_fail (GTR_IS_DB_KEYS (db_keys), 0);
+	
+	return db_keys->priv->count;
+}
+
+void
+gtranslator_db_keys_set_count (GtranslatorDbKeys *db_keys,
+			       gsize count)
+{
+	g_return_if_fail (GTR_IS_DB_KEYS (db_keys));
+	
+	db_keys->priv->count = count;
+}

Added: trunk/src/translation-memory/berkeley/db-keys.h
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-keys.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DB_KEYS_H__
+#define __DB_KEYS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include DB_HEADER
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_DB_KEYS		(gtranslator_db_keys_get_type ())
+#define GTR_DB_KEYS(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_DB_KEYS, GtranslatorDbKeys))
+#define GTR_DB_KEYS_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_DB_KEYS, GtranslatorDbKeysClass))
+#define GTR_IS_DB_KEYS(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_DB_KEYS))
+#define GTR_IS_DB_KEYS_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_DB_KEYS))
+#define GTR_DB_KEYS_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_DB_KEYS, GtranslatorDbKeysClass))
+
+/* Private structure type */
+typedef struct _GtranslatorDbKeysPrivate	GtranslatorDbKeysPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorDbKeys		GtranslatorDbKeys;
+
+struct _GtranslatorDbKeys
+{
+	GObject parent_instance;
+	
+	/*< private > */
+	GtranslatorDbKeysPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorDbKeysClass	GtranslatorDbKeysClass;
+
+struct _GtranslatorDbKeysClass
+{
+	GObjectClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_db_keys_get_type	      (void) G_GNUC_CONST;
+
+GType		 gtranslator_db_keys_register_type    (GTypeModule * module);
+
+GtranslatorDbKeys *gtranslator_db_keys_new	      (DBT *data);
+
+GtranslatorDbKeys *gtranslator_db_keys_new_with_size  (gsize cnt);
+
+db_recno_t      *gtranslator_db_keys_get_list         (GtranslatorDbKeys *db_keys);
+
+gsize            gtranslator_db_keys_get_count        (GtranslatorDbKeys *db_keys);
+
+void             gtranslator_db_keys_set_count        (GtranslatorDbKeys *db_keys,
+						       gsize count);
+
+G_END_DECLS
+
+#endif /* __DB_KEYS_H__ */

Added: trunk/src/translation-memory/berkeley/db-orig.c
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-orig.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based in poedit transmem.cpp file:
+ *     Copyright (C) 2001-2007 Vaclav Slavik
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "db-orig.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#define GTR_DB_ORIG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 (object),		       \
+						 GTR_TYPE_DB_ORIG,     \
+						 GtranslatorDbOrigPrivate))
+
+G_DEFINE_TYPE(GtranslatorDbOrig, gtranslator_db_orig, GTR_TYPE_DB_BASE)
+
+
+struct _GtranslatorDbOrigPrivate
+{
+
+};
+
+static void
+gtranslator_db_orig_init (GtranslatorDbOrig *db_orig)
+{
+	//db_orig->priv = GTR_DB_ORIG_GET_PRIVATE (db_orig);
+	
+	gtranslator_db_base_create_dabatase (GTR_DB_BASE (db_orig),
+					     _("original.db"),
+					     DB_HASH);
+}
+
+static void
+gtranslator_db_orig_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_db_orig_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_db_orig_class_init (GtranslatorDbOrigClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	//g_type_class_add_private (klass, sizeof (GtranslatorDbOrigPrivate));
+
+	object_class->finalize = gtranslator_db_orig_finalize;
+}
+
+/**
+ * gtranslator_db_orig_new:
+ * 
+ * Creates a new #GtranslatorDbOrig object.
+ * 
+ * Returns: a newly #GtranslatorDbOrig object
+ */
+GtranslatorDbOrig *
+gtranslator_db_orig_new ()
+{
+	GtranslatorDbOrig *db_orig;
+
+	db_orig = g_object_new (GTR_TYPE_DB_ORIG, NULL);
+	
+	return db_orig;
+}
+
+/**
+ * gtranslator_db_orig_write:
+ * @orig: a #GtranslatorDbOrig
+ * @string: string to store in the database
+ * @value: the foreign key from #GtranslatorDbTrans
+ *
+ * Stores the @string in the database with the right foreign key @value.
+ * It returns TRUE if there was not any error.
+ *
+ * Returns: TRUE if it was successfully stored.
+ */
+gboolean
+gtranslator_db_orig_write (GtranslatorDbOrig *orig,
+			   const gchar *string,
+			   db_recno_t value)
+{
+	DBT key, data;
+	gint error;
+
+	memset (&key, 0, sizeof (key));
+	memset (&data, 0, sizeof (data));
+	key.data = (gpointer) string;
+	key.size = strlen (string);
+	data.data = &value;
+	data.size = sizeof (value);
+	
+	error = gtranslator_db_base_put (GTR_DB_BASE (orig),
+					 &key,
+					 &data,
+					 0);
+	if (error != 0)
+	{
+		gtranslator_db_base_show_error (GTR_DB_BASE (orig), error);
+		return FALSE;
+	}
+	
+	return TRUE;
+}
+
+/**
+ * gtranslator_db_orig_read:
+ * @orig: a #GtranslatorDbOrig
+ * @string: the primary key of the #GtranslatorDbOrig
+ *
+ * Gets the foreign key for #GtranslatorDbTrans for a given #GtranslatorDbOrig
+ * primary key.
+ *
+ * Returns: the foreign key for #GtranslatorDbTrans
+ */
+db_recno_t
+gtranslator_db_orig_read (GtranslatorDbOrig *orig,
+			  const gchar *string)
+{
+	DBT key, data;
+	gint error;
+
+	memset (&key, 0, sizeof (key));
+	memset (&data, 0, sizeof (data));
+	key.data = (gpointer)string;
+	key.size = strlen (string);
+	
+	error = gtranslator_db_base_get (GTR_DB_BASE (orig),
+					 &key, &data);
+	if (error != 0)
+	{
+		if (error != DB_NOTFOUND)
+			gtranslator_db_base_show_error (GTR_DB_BASE (orig),
+							error);
+		return 0;
+	}
+	
+	return *((db_recno_t*)data.data);
+}

Added: trunk/src/translation-memory/berkeley/db-orig.h
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-orig.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DB_ORIG_H__
+#define __DB_ORIG_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "db-base.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_DB_ORIG		(gtranslator_db_orig_get_type ())
+#define GTR_DB_ORIG(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_DB_ORIG, GtranslatorDbOrig))
+#define GTR_DB_ORIG_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_DB_ORIG, GtranslatorDbOrigClass))
+#define GTR_IS_DB_ORIG(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_DB_ORIG))
+#define GTR_IS_DB_ORIG_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_DB_ORIG))
+#define GTR_DB_ORIG_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_DB_ORIG, GtranslatorDbOrigClass))
+
+/* Private structure type */
+typedef struct _GtranslatorDbOrigPrivate	GtranslatorDbOrigPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorDbOrig		GtranslatorDbOrig;
+
+struct _GtranslatorDbOrig
+{
+	GtranslatorDbBase parent_instance;
+	
+	/*< private > */
+	GtranslatorDbOrigPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorDbOrigClass	GtranslatorDbOrigClass;
+
+struct _GtranslatorDbOrigClass
+{
+	GtranslatorDbBaseClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_db_orig_get_type	      (void) G_GNUC_CONST;
+
+GType		 gtranslator_db_orig_register_type    (GTypeModule * module);
+
+GtranslatorDbOrig *gtranslator_db_orig_new	      (void);
+
+gboolean         gtranslator_db_orig_write            (GtranslatorDbOrig *orig,
+						       const gchar *string,
+						       db_recno_t value);
+						       
+db_recno_t       gtranslator_db_orig_read             (GtranslatorDbOrig *orig,
+						       const gchar *string);
+
+G_END_DECLS
+
+#endif /* __DB_ORIG_H__ */

Added: trunk/src/translation-memory/berkeley/db-trans.c
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-trans.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based in poedit transmem.cpp file:
+ *     Copyright (C) 2001-2007 Vaclav Slavik
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "db-trans.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#define GTR_DB_TRANS_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 (object),		       \
+						 GTR_TYPE_DB_TRANS,     \
+						 GtranslatorDbTransPrivate))
+
+G_DEFINE_TYPE(GtranslatorDbTrans, gtranslator_db_trans, GTR_TYPE_DB_BASE)
+
+
+struct _GtranslatorDbTransPrivate
+{
+
+};
+
+static void
+gtranslator_db_trans_init (GtranslatorDbTrans *db_trans)
+{
+	//db_trans->priv = GTR_DB_TRANS_GET_PRIVATE (db_trans);
+	
+	gtranslator_db_base_create_dabatase (GTR_DB_BASE (db_trans),
+					     _("translations.db"),
+					     DB_RECNO);
+}
+
+static void
+gtranslator_db_trans_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_db_trans_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_db_trans_class_init (GtranslatorDbTransClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	//g_type_class_add_private (klass, sizeof (GtranslatorDbTransPrivate));
+
+	object_class->finalize = gtranslator_db_trans_finalize;
+}
+
+/**
+ * gtranslator_db_trans_new:
+ * 
+ * Creates a new #GtranslatorDbTrans object.
+ * 
+ * Returns: a newly #GtranslatorDbTrans object
+ */
+GtranslatorDbTrans *
+gtranslator_db_trans_new ()
+{
+	GtranslatorDbTrans *db_trans;
+
+	db_trans = g_object_new (GTR_TYPE_DB_TRANS, NULL);
+	
+	return db_trans;
+}
+
+/**
+ * gtranslator_db_trans_write_string:
+ * @db_trans: a #GtranslatorDbTrans
+ * @translation: string to be stored in the database
+ * @key: the index record in the database to be modified
+ * 
+ * Writes @translation in the database and returns the new key index.
+ *
+ * Returns: if @index is 0 then returns the new index, else returns @index
+ */
+db_recno_t
+gtranslator_db_trans_write_string (GtranslatorDbTrans *db_trans,
+				   const gchar *translation,
+				   db_recno_t key)
+{
+	gchar *array[2];
+	db_recno_t toret;
+	
+	array[0] = g_strdup (translation);
+	array[1] = NULL;
+	
+	toret = gtranslator_db_trans_write (db_trans, array, key);
+	
+	g_free (array[0]);
+	
+	return toret;
+}
+
+/**
+ * gtranslator_db_trans_write:
+ * @db_trans: a #GtranslatorDbTrans
+ * @translations: array of translations
+ * @index: the index record in the database to be modified
+ *
+ * Writes @translations in the database and returns the new key index.
+ *
+ * Returns: if @index is 0 then returns the new index, else returns @index
+ */
+db_recno_t
+gtranslator_db_trans_write (GtranslatorDbTrans *db_trans,
+			    gchar **translations,
+			    db_recno_t index)
+{
+	DBT key, data;
+	gsize bufLen;
+	gsize i;
+	gint error = 0;
+	gsize len;
+	gint trans_len;
+	
+	trans_len = g_strv_length (translations);
+	
+	/*
+	 * Firstly we get buffer length to store:
+	 * - In the first position the number of strings
+	 * - then we store for each string: the length of the string
+	 *   and the string.
+	 * Graphic: (trans_len)(string_len)----->(string_len)----->.....
+	 * ----> = string data
+	 */
+	for (bufLen = 0, i = 0; i < trans_len; i++)
+	{
+		len = strlen (translations[i]);
+		bufLen += sizeof (len) + len;
+	}
+	bufLen += sizeof (trans_len);
+	
+	/*
+	 * Now we create the buffer with the length I've got in the previous
+	 * iteration and I store in that buffer what I said before.
+	 */
+	u_int8_t *p, buf[bufLen];
+	
+	p = &buf[0];
+	memcpy (p, &trans_len, sizeof (trans_len));
+	p += sizeof (trans_len);
+	
+	for (i = 0; i < g_strv_length (translations); i++)
+	{
+		len = strlen (translations[i]);
+		memcpy (p, &len, sizeof (len));
+		p += sizeof (len);
+		memcpy (p, translations[i], len);
+		p += len;
+	}
+	
+	/*
+	 * Storing the buffer with the length in the that and after that
+	 * we try to store it in the database.
+	 * If there is a problem we show it.
+	 */
+	memset (&key, 0, sizeof (key));
+	memset (&data, 0, sizeof (data));
+	data.data = buf;
+	data.size = bufLen;
+	
+	if (index == 0)
+	{
+		error = gtranslator_db_base_put (GTR_DB_BASE (db_trans),
+						 &key, &data, DB_APPEND);
+	}
+	else
+	{
+		key.data = &index;
+		key.size = sizeof (index);
+
+		error = gtranslator_db_base_put (GTR_DB_BASE (db_trans),
+						 &key, &data, 0);
+	}
+
+	if (error != 0)
+	{
+		gtranslator_db_base_show_error (GTR_DB_BASE (db_trans), error);
+		return 0;
+	}    
+	return (index == 0) ? *((db_recno_t*)key.data) : index;
+}
+
+/**
+ * gtranslator_db_trans_read:
+ * @db_trans: a #GtranslatorDbTrans
+ * @index: the index record in the database
+ *
+ * Retrieves translations stored under given @index. Returns an #GPtrArray of
+ * translations or NULL if the key is absent.
+ * The caller must free the #GPtrArray.
+ */
+GPtrArray *
+gtranslator_db_trans_read (GtranslatorDbTrans *db_trans,
+			   db_recno_t index)
+{
+	DBT key, data;
+	gint error;
+	GPtrArray *gparray;
+	gint bufLen;
+	u_int8_t *p;
+	u_int8_t *buf;
+	gint i =0;
+
+	memset (&key, 0, sizeof (key));
+	memset (&data, 0, sizeof (data));
+	key.data = &index;
+	key.size = sizeof (index);
+	
+	/*
+	 * We get the data from the key
+	 */
+	error = gtranslator_db_base_get (GTR_DB_BASE (db_trans),
+					 &key, &data);
+	if (error != 0)
+	{
+		gtranslator_db_base_show_error (GTR_DB_BASE (db_trans), error);
+		return NULL;
+	}
+	
+	/*
+	 * Once we have the data we have to parse the byte array
+	 * and store it in our GPtrArray
+	 */
+	gparray = g_ptr_array_new ();
+	
+	buf = data.data;
+	
+	p = &buf[0];
+	memcpy (&bufLen, p, sizeof (bufLen));
+	p += sizeof (bufLen);
+	
+	while (i < bufLen)
+	{
+		gsize len;
+		gchar *data;
+		
+		memcpy (&len, p, sizeof (len));
+		p += sizeof (len);
+		
+		data = g_malloc (len+1);
+		memcpy (data, p, len);
+		p += len;
+		data[len] = '\0';
+
+		g_ptr_array_add (gparray, (gpointer)data);
+		
+		i++;
+	}
+	
+	g_ptr_array_add (gparray, NULL);
+	
+	return gparray;
+}

Added: trunk/src/translation-memory/berkeley/db-trans.h
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-trans.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DB_TRANS_H__
+#define __DB_TRANS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "db-base.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_DB_TRANS		(gtranslator_db_trans_get_type ())
+#define GTR_DB_TRANS(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_DB_TRANS, GtranslatorDbTrans))
+#define GTR_DB_TRANS_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_DB_TRANS, GtranslatorDbTransClass))
+#define GTR_IS_DB_TRANS(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_DB_TRANS))
+#define GTR_IS_DB_TRANS_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_DB_TRANS))
+#define GTR_DB_TRANS_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_DB_TRANS, GtranslatorDbTransClass))
+
+/* Private structure type */
+typedef struct _GtranslatorDbTransPrivate	GtranslatorDbTransPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorDbTrans		GtranslatorDbTrans;
+
+struct _GtranslatorDbTrans
+{
+	GtranslatorDbBase parent_instance;
+	
+	/*< private > */
+	GtranslatorDbTransPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorDbTransClass	GtranslatorDbTransClass;
+
+struct _GtranslatorDbTransClass
+{
+	GtranslatorDbBaseClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_db_trans_get_type	      (void) G_GNUC_CONST;
+
+GType		 gtranslator_db_trans_register_type   (GTypeModule * module);
+
+GtranslatorDbTrans *gtranslator_db_trans_new	      (void);
+
+db_recno_t       gtranslator_db_trans_write_string    (GtranslatorDbTrans *db_trans,
+						       const gchar *translation,
+						       db_recno_t key);
+
+db_recno_t       gtranslator_db_trans_write           (GtranslatorDbTrans *db_trans,
+						       gchar **translations,
+						       db_recno_t index);	
+			    
+GPtrArray       *gtranslator_db_trans_read            (GtranslatorDbTrans *db_trans,
+						       db_recno_t index);
+
+G_END_DECLS
+
+#endif /* __DB_TRANS_H__ */
+
+

Added: trunk/src/translation-memory/berkeley/db-words.c
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-words.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ *     Based in poedit transmem.cpp file:
+ *     Copyright (C) 2001-2007 Vaclav Slavik
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "db-words.h"
+#include "db-keys.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#define GTR_DB_WORDS_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+						 (object),		       \
+						 GTR_TYPE_DB_WORDS,     \
+						 GtranslatorDbWordsPrivate))
+
+G_DEFINE_TYPE(GtranslatorDbWords, gtranslator_db_words, GTR_TYPE_DB_BASE)
+
+
+struct _GtranslatorDbWordsPrivate
+{
+
+};
+
+static void
+gtranslator_db_words_init (GtranslatorDbWords *db_words)
+{
+	//db_words->priv = GTR_DB_WORDS_GET_PRIVATE (db_words);
+	
+	gtranslator_db_base_create_dabatase (GTR_DB_BASE (db_words),
+					     _("words.db"),
+					     DB_HASH);
+}
+
+static void
+gtranslator_db_words_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (gtranslator_db_words_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_db_words_class_init (GtranslatorDbWordsClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	//g_type_class_add_private (klass, sizeof (GtranslatorDbWordsPrivate));
+
+	object_class->finalize = gtranslator_db_words_finalize;
+}
+
+GtranslatorDbWords *
+gtranslator_db_words_new ()
+{
+	GtranslatorDbWords *db_words;
+
+	db_words = g_object_new (GTR_TYPE_DB_WORDS, NULL);
+	
+	return db_words;
+}
+
+gboolean
+gtranslator_db_words_append (GtranslatorDbWords *db_words,
+			     const gchar *word,
+			     guint sentence_size,
+			     db_recno_t value)
+{
+	// VS: there is a dirty trick: it is always true that 'value' is 
+	//     greater than all values already present in the db, so we may
+	//     append it to the end of list while still keeping the list sorted.
+	//     This is important because it allows us to efficiently merge
+	//     these lists when looking up inexact translations...
+	
+	DBT key, data;
+	gsize len;
+	gsize buf_len;
+	GtranslatorDbKeys *keys;
+	db_recno_t *value_buf = NULL;
+	gint error = 0;
+	
+	/*
+	 * (sentence_size)(len)(word)
+	 */
+	len = strlen (word);
+	buf_len = sizeof (sentence_size) + sizeof (len) + len;
+	
+	//g_warning ("DEBUG: Append: %d|%d|%d|%s", sizeof (sentence_size), sizeof (len), len, word);
+	
+	//FIXME: use glib
+	u_int8_t *p, buf[buf_len];
+	
+	p = &buf[0];
+	memcpy (p, &sentence_size, sizeof (sentence_size));
+	p += sizeof (sentence_size);
+	memcpy (p, &len, sizeof (len));
+	p += sizeof (len);
+	memcpy (p, word, len);
+	
+	memset(&key, 0, sizeof(key));
+	memset(&data, 0, sizeof(data));
+	key.data = buf;
+	key.size = buf_len;
+	
+	keys = gtranslator_db_words_read (db_words, word, sentence_size);
+	if (keys == NULL)
+	{
+		data.data = &value;
+		data.size = sizeof(value);
+	}
+	else
+	{
+		gsize count = gtranslator_db_keys_get_count (keys);
+		db_recno_t *list = gtranslator_db_keys_get_list (keys);
+		
+		value_buf = g_new (db_recno_t, count + 1);
+		memcpy(value_buf, list, count * sizeof (db_recno_t));
+		value_buf[count] = value;
+		data.data = value_buf;
+		data.size = (count + 1) * sizeof(db_recno_t);
+		
+		g_object_unref (keys);
+	}
+
+	error = gtranslator_db_base_put (GTR_DB_BASE (db_words),
+					 &key,
+					 &data,
+					 0);
+	g_free (value_buf);
+	
+	if (error != 0)
+	{
+		gtranslator_db_base_show_error (GTR_DB_BASE (db_words), error);
+		return FALSE;
+	} 
+
+	return TRUE;
+}
+
+GtranslatorDbKeys *
+gtranslator_db_words_read (GtranslatorDbWords *db_words,
+			   const gchar *word,
+			   guint sentence_size)
+{
+	DBT key, data;
+	gsize len;
+	gsize buf_len;
+	GtranslatorDbKeys *keys;
+	gint error = 0;
+	
+	/*
+	 * (sentence_size)(len)(word)
+	 */
+	len = strlen (word);
+	buf_len = sizeof (sentence_size) + sizeof (len) + len;
+	//g_warning ("DEBUG: Read: %d|%d|%d|%s", sizeof (sentence_size), sizeof (len), len, word);
+	/*
+	 * Here we recreate the key and then with that key we get the list
+	 * of keys
+	 */
+	//FIXME: use glib
+	u_int8_t *p, buf[buf_len];
+	
+	p = &buf[0];
+	memcpy (p, &sentence_size, sizeof (sentence_size));
+	p += sizeof (sentence_size);
+	memcpy (p, &len, sizeof (len));
+	p += sizeof (len);
+	memcpy (p, word, len);
+	
+	memset (&key, 0, sizeof (key));
+	memset (&data, 0, sizeof (data));
+	key.data = buf;
+	key.size = buf_len;
+	
+	error = gtranslator_db_base_get (GTR_DB_BASE (db_words),
+					 &key,
+					 &data);
+	if (error != 0)
+	{
+		gtranslator_db_base_show_error (GTR_DB_BASE (db_words), error);
+		return NULL;
+	}
+	
+	keys = gtranslator_db_keys_new (&data);
+	
+	return keys;
+}

Added: trunk/src/translation-memory/berkeley/db-words.h
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/berkeley/db-words.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DB_WORDS_H__
+#define __DB_WORDS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "db-base.h"
+#include "db-keys.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_DB_WORDS		(gtranslator_db_words_get_type ())
+#define GTR_DB_WORDS(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_DB_WORDS, GtranslatorDbWords))
+#define GTR_DB_WORDS_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_DB_WORDS, GtranslatorDbWordsClass))
+#define GTR_IS_DB_WORDS(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_DB_WORDS))
+#define GTR_IS_DB_WORDS_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_DB_WORDS))
+#define GTR_DB_WORDS_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_DB_WORDS, GtranslatorDbWordsClass))
+
+/* Private structure type */
+typedef struct _GtranslatorDbWordsPrivate	GtranslatorDbWordsPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorDbWords		GtranslatorDbWords;
+
+struct _GtranslatorDbWords
+{
+	GtranslatorDbBase parent_instance;
+	
+	/*< private > */
+	GtranslatorDbWordsPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorDbWordsClass	GtranslatorDbWordsClass;
+
+struct _GtranslatorDbWordsClass
+{
+	GtranslatorDbBaseClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_db_words_get_type	      (void) G_GNUC_CONST;
+
+GType		 gtranslator_db_words_register_type   (GTypeModule * module);
+
+GtranslatorDbWords *gtranslator_db_words_new	      (void);
+
+gboolean         gtranslator_db_words_append          (GtranslatorDbWords *db_words,
+						       const gchar *word,
+						       guint sentence_size,
+						       db_recno_t value);
+						       
+GtranslatorDbKeys *gtranslator_db_words_read          (GtranslatorDbWords *db_words,
+						       const gchar *word,
+						       guint sentence_size);
+
+G_END_DECLS
+
+#endif /* __DB_WORDS_H__ */

Added: trunk/src/translation-memory/translation-memory-ui.c
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/translation-memory-ui.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2008
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "application.h"
+#include "po.h"
+#include "prefs-manager.h"
+#include "translation-memory.h"
+#include "translation-memory-ui.h"
+#include "tab.h"
+#include "window.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#define MAX_ELEMENTS 10
+
+#define GTR_TRANSLATION_MEMORY_UI_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
+							(object),	               \
+							GTR_TYPE_TRANSLATION_MEMORY_UI,	       \
+							GtranslatorTranslationMemoryUiPrivate))
+
+G_DEFINE_TYPE(GtranslatorTranslationMemoryUi, gtranslator_translation_memory_ui, GTK_TYPE_SCROLLED_WINDOW)
+
+struct _GtranslatorTranslationMemoryUiPrivate
+{
+        GtkWidget *tree_view;
+	GtranslatorTab *tab;
+	
+	gchar **tm_list;
+};
+
+enum {
+  SHORTCUT_COLUMN,
+  LEVEL_COLUMN,
+  STRING_COLUMN,
+  N_COLUMNS
+};
+
+static void
+tree_view_size_cb (GtkWidget     *widget,
+		   GtkAllocation *allocation,
+		   gpointer user_data);
+
+static void                
+on_activate_item_cb (GtkMenuItem *menuitem,
+		     GtranslatorTranslationMemoryUi *tm_ui)
+{
+  GtranslatorView *view;
+  GtkTextBuffer *buffer;
+  GtranslatorPo *po;
+  GList *current_msg = NULL;
+  GtranslatorMsg *msg;
+  gint index;
+  GtranslatorWindow *window;
+
+  window = gtranslator_application_get_active_window (GTR_APP);
+  
+  view = gtranslator_window_get_active_view (window);
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  /* Possible this hack is not going to work with all languages neither, we
+     are supposing the integer at the end of the string */
+  index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), "option"));
+
+  po = gtranslator_tab_get_po (tm_ui->priv->tab);
+  current_msg = gtranslator_po_get_current_message (po);
+
+  msg = GTR_MSG (current_msg->data);
+  
+  gtranslator_msg_set_msgstr (msg, tm_ui->priv->tm_list[index-1]);
+
+  gtk_text_buffer_begin_user_action (buffer);
+  gtk_text_buffer_set_text (buffer,
+			    tm_ui->priv->tm_list[index-1],
+			    -1);
+  gtk_text_buffer_end_user_action(buffer);
+
+  gtranslator_po_set_state (po, GTR_PO_STATE_MODIFIED);
+}
+
+static void
+free_list (gpointer data,
+	   gpointer useless)
+{
+	GtranslatorTranslationMemoryMatch *match = (GtranslatorTranslationMemoryMatch *)data;
+	
+	g_free (match->match);
+	g_free (match);
+}
+
+static void
+showed_message_cb (GtranslatorTab *tab,
+		   GtranslatorMsg *msg,
+		   GtranslatorTranslationMemoryUi *tm_ui)
+{
+  GtranslatorTranslationMemory *tm;
+  GtkListStore *model;
+  GtkTreeIter iter;
+  GtkTreeViewColumn *level_column;
+  const gchar *msgid;
+  gint i = 1;
+  gint j = 1;
+  gint k = 0;
+  GList *tm_list = NULL;
+  GList *l = NULL;
+  GList *renderers_list = NULL;
+  GtkWidget *tm_item;
+  GtkWidget *tm_menu;
+  GtkWidget *items_menu;
+  GtranslatorWindow *window;
+  GtkUIManager *manager;
+  gchar *item_name;
+
+  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (tm_ui->priv->tree_view)));
+  
+  window = gtranslator_application_get_active_window (GTR_APP);
+  tm_menu = gtranslator_window_get_tm_menu (window);
+
+  if (!gtranslator_prefs_manager_get_show_tm_options () && gtranslator_msg_is_translated (msg)
+      && !gtranslator_msg_is_fuzzy (msg)) {
+    gtk_widget_set_sensitive (tm_menu, FALSE);
+    gtk_list_store_clear (model);
+    return;    
+  }else {  
+    g_signal_connect (tm_ui->priv->tree_view,
+		      "size_allocate",
+		      G_CALLBACK (tree_view_size_cb),
+		      tm_ui->priv->tree_view);
+    
+    msgid = gtranslator_msg_get_msgid (msg);
+    
+    tm = GTR_TRANSLATION_MEMORY (gtranslator_application_get_translation_memory (GTR_APP));
+    
+    tm_list = gtranslator_translation_memory_lookup (tm, msgid);
+
+    if (tm_list == NULL) {
+      gtk_widget_set_sensitive (tm_menu, FALSE);
+    } else {
+      gtk_widget_set_sensitive (tm_menu, TRUE);
+    }
+    
+    gtk_list_store_clear (model);
+
+    g_strfreev (tm_ui->priv->tm_list);
+    tm_ui->priv->tm_list = g_new (gchar *, MAX_ELEMENTS + 1);
+    
+    for (l = tm_list; l; l = l->next) {
+      GtranslatorTranslationMemoryMatch *match;
+      match = (GtranslatorTranslationMemoryMatch *)l->data;
+      tm_ui->priv->tm_list[i-1] = g_strdup (match->match);       
+      level_column = gtk_tree_view_get_column (GTK_TREE_VIEW (tm_ui->priv->tree_view), 0);
+      renderers_list = gtk_tree_view_column_get_cell_renderers (level_column);
+      
+      g_object_set (renderers_list->data,
+		    "accel-mods", GDK_CONTROL_MASK,
+		    NULL);
+      g_list_free (renderers_list);
+      
+      gtk_list_store_append (model, &iter);
+      gtk_list_store_set (model,
+			  &iter,
+			  SHORTCUT_COLUMN,
+			  GDK_0+k,
+			  STRING_COLUMN,
+			  match->match,
+			  LEVEL_COLUMN,
+			  match->level,
+			  -1);
+      i++;
+      k++;
+      if (k == MAX_ELEMENTS)
+        break;
+    }
+
+    /* Ensure last element is NULL */
+    tm_ui->priv->tm_list[i-1] = NULL;
+
+    /* MenuBar stuff */
+    
+    items_menu = gtk_menu_new();
+    
+    manager = gtranslator_window_get_ui_manager (window);
+    
+    gtk_menu_set_accel_group (GTK_MENU (items_menu),
+			      gtk_ui_manager_get_accel_group(manager));
+    
+    do{
+      gchar *accel_path;
+      
+      item_name = g_strdup_printf (_("Insert Option n %d"), j);
+      
+      tm_item = gtk_menu_item_new_with_label (item_name);
+      g_object_set_data (G_OBJECT (tm_item), "option", GINT_TO_POINTER (j));
+      gtk_widget_show (tm_item);
+      
+      accel_path = g_strdup_printf ("<Gtranslator-sheet>/Edit/_Translation Memory/%s", item_name);
+      
+      gtk_menu_item_set_accel_path (GTK_MENU_ITEM (tm_item), accel_path);
+      gtk_accel_map_add_entry (accel_path, GDK_0+(j-1), GDK_CONTROL_MASK);
+      
+      g_free (accel_path);
+      g_free (item_name);
+      
+      g_signal_connect (tm_item, "activate",
+			G_CALLBACK (on_activate_item_cb),
+			tm_ui);
+      
+      gtk_menu_shell_append (GTK_MENU_SHELL (items_menu), tm_item);
+    
+      j++;
+      if (j > MAX_ELEMENTS)
+	break;
+
+    }while ((tm_list = g_list_next (tm_list)));
+    
+    gtk_menu_item_set_submenu (GTK_MENU_ITEM (tm_menu), items_menu);
+
+    /* Freeing the list */
+    g_list_foreach (tm_list, (GFunc)free_list, NULL);
+    g_list_free (tm_list);
+  }
+}
+
+static void
+tree_view_size_cb (GtkWidget     *widget,
+		   GtkAllocation *allocation,
+		   gpointer       user_data)
+{
+        GtkTreeView *treeview;
+	GtkTreeViewColumn *column;
+	GList *renderers_list = NULL;
+	gint size;
+
+	treeview = GTK_TREE_VIEW (user_data);	
+     
+	column = gtk_tree_view_get_column (treeview, 2);
+	renderers_list = gtk_tree_view_column_get_cell_renderers (column);
+
+	size = gtk_tree_view_column_get_width (column);
+
+	g_object_set (renderers_list->data,
+		      "wrap-width", size-10,
+		      NULL);
+	
+	g_list_free (renderers_list);
+}
+
+
+static void
+gtranslator_translation_memory_ui_draw(GtranslatorTranslationMemoryUi *tm_ui)
+{
+	GtranslatorTranslationMemoryUiPrivate *priv = tm_ui->priv;
+	GtkListStore *model;
+	GtkCellRenderer *level_renderer, *string_renderer, *shortcut_renderer;
+	GtkTreeViewColumn *shortcut, *string, *level;
+
+	priv->tree_view = gtk_tree_view_new();
+	gtk_widget_show (priv->tree_view);
+	
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(tm_ui),
+				       GTK_POLICY_AUTOMATIC,
+				       GTK_POLICY_AUTOMATIC);
+
+	model = gtk_list_store_new (N_COLUMNS, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING);
+	gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), GTK_TREE_MODEL (model));
+
+	shortcut_renderer = gtk_cell_renderer_accel_new ();
+	shortcut = gtk_tree_view_column_new_with_attributes ("Shortcut",
+							     shortcut_renderer,
+							     "accel-key", SHORTCUT_COLUMN,
+							     NULL);
+	g_object_set (shortcut_renderer,
+		      "width", 80,
+		      NULL);
+	
+	gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), shortcut);
+
+	level_renderer = gtk_cell_renderer_progress_new ();
+	level = gtk_tree_view_column_new_with_attributes ("Level",
+							  level_renderer,
+							  "value", LEVEL_COLUMN,
+							  NULL);
+	g_object_set (level_renderer,
+		      "width", 80,
+		      NULL);
+	
+	gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), level);
+	
+	string_renderer = gtk_cell_renderer_text_new ();
+	string = gtk_tree_view_column_new_with_attributes ("String",
+							   string_renderer,
+							   "text", STRING_COLUMN,
+							   NULL);
+	gtk_tree_view_column_set_sizing (string,
+					 GTK_TREE_VIEW_COLUMN_FIXED);
+
+	g_object_set (string_renderer,
+		      "ypad", 0,
+		      "xpad", 5,
+		      "yalign", 0.0,
+		      "wrap-mode", PANGO_WRAP_WORD_CHAR,
+		      NULL);
+
+	gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), string);
+}
+
+static void
+gtranslator_translation_memory_ui_init (GtranslatorTranslationMemoryUi *tm_ui)
+{
+	tm_ui->priv = GTR_TRANSLATION_MEMORY_UI_GET_PRIVATE (tm_ui);
+	tm_ui->priv->tm_list = NULL;
+	
+	gtranslator_translation_memory_ui_draw (tm_ui);
+}
+
+static void
+gtranslator_translation_memory_ui_finalize (GObject *object)
+{
+	GtranslatorTranslationMemoryUi *tm_ui = GTR_TRANSLATION_MEMORY_UI (object);
+	
+	g_strfreev (tm_ui->priv->tm_list);
+	
+	G_OBJECT_CLASS (gtranslator_translation_memory_ui_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_translation_memory_ui_class_init (GtranslatorTranslationMemoryUiClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorTranslationMemoryUiPrivate));
+
+	object_class->finalize = gtranslator_translation_memory_ui_finalize;
+}
+
+GtkWidget *
+gtranslator_translation_memory_ui_new (GtkWidget *tab)
+{
+	GtranslatorTranslationMemoryUi *tm_ui;
+	tm_ui = g_object_new (GTR_TYPE_TRANSLATION_MEMORY_UI, NULL);
+	
+	tm_ui->priv->tab = GTR_TAB(tab);
+	g_signal_connect(tab,
+			 "showed-message",
+			 G_CALLBACK(showed_message_cb),
+			 tm_ui);
+	
+	/* Scrolledwindow needs to be realized to add a widget */
+	gtk_container_add (GTK_CONTAINER(tm_ui),
+			   tm_ui->priv->tree_view);
+	
+	return GTK_WIDGET(tm_ui);
+}

Added: trunk/src/translation-memory/translation-memory-ui.h
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/translation-memory-ui.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008  
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TRANSLATION_MEMORY_UI_H__
+#define __TRANSLATION_MEMORY_UI_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_TRANSLATION_MEMORY_UI	        (gtranslator_translation_memory_ui_get_type ())
+#define GTR_TRANSLATION_MEMORY_UI(o)	        (G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_TRANSLATION_MEMORY_UI, GtranslatorTranslationMemoryUi))
+#define GTR_TRANSLATION_MEMORY_UI_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_TRANSLATION_MEMORY_UI, GtranslatorTranslationMemoryUiClass))
+#define GTR_IS_TRANSLATION_MEMORY_UI(o)	        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_TRANSLATION_MEMORY_UI))  
+#define GTR_IS_TRANSLATION_MEMORY_UI_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_TRANSLATION_MEMORY_UI))
+#define GTR_TRANSLATION_MEMORY_UI_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_TRANSLATION_MEMORY_UI, GtranslatorTranslationMemoryUiClass))
+
+/* Private structure type */
+typedef struct _GtranslatorTranslationMemoryUiPrivate	GtranslatorTranslationMemoryUiPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorTranslationMemoryUi		GtranslatorTranslationMemoryUi;
+
+struct _GtranslatorTranslationMemoryUi
+{
+        GtkScrolledWindow parent_instance;
+	
+	/*< private > */
+	GtranslatorTranslationMemoryUiPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorTranslationMemoryUiClass	GtranslatorTranslationMemoryUiClass;
+
+struct _GtranslatorTranslationMemoryUiClass
+{
+        GtkScrolledWindowClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_translation_memory_ui_get_type	   (void) G_GNUC_CONST;
+
+GType		 gtranslator_translation_memory_ui_register_type   (GTypeModule * module);
+
+GtkWidget	*gtranslator_translation_memory_ui_new	           (GtkWidget *tab);
+
+G_END_DECLS
+
+#endif /* __TRANSLATION_MEMORY_UI_H__ */

Added: trunk/src/translation-memory/translation-memory.c
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/translation-memory.c	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "translation-memory.h"
+
+/**
+ * gtranslator_translation_memory_store:
+ * @obj: a #GtranslatorTranslationMemory
+ * @original: the untranslated text
+ * @translation: the @original text translated
+ *
+ * Stores the @original and @translation strings in the database.
+ */
+gboolean
+gtranslator_translation_memory_store (GtranslatorTranslationMemory *obj,
+				      const gchar *original,
+				      const gchar *translation)
+{
+	g_return_val_if_fail (GTR_IS_TRANSLATION_MEMORY (obj), FALSE);
+	return GTR_TRANSLATION_MEMORY_GET_IFACE (obj)->store (obj, original, translation);
+}
+
+/* Default implementation */
+static gboolean
+gtranslator_translation_memory_store_default (GtranslatorTranslationMemory *obj,
+					      const gchar *original,
+					      const gchar *translation)
+{
+	g_return_val_if_reached (FALSE);
+}
+
+/**
+ * gtranslator_translation_memory_lookup:
+ * @obj: a #GtranslatorTranslationMemory
+ * @phrase: the unstranslated text to search for translations.
+ *
+ * Looks for the @phrase in the database and gets a list of the #GtranslatorTranslationMemoryMatch.
+ *
+ * Returns: a list of #GtranslatorTranslationMemoryMatch.
+ */
+GList *
+gtranslator_translation_memory_lookup (GtranslatorTranslationMemory *obj,
+				       const gchar *phrase)
+{
+	g_return_val_if_fail (GTR_IS_TRANSLATION_MEMORY (obj), 0);
+	return GTR_TRANSLATION_MEMORY_GET_IFACE (obj)->lookup (obj, phrase);
+}
+
+/* Default implementation */
+static GList *
+gtranslator_translation_memory_lookup_default (GtranslatorTranslationMemory *obj,
+					       const gchar *phrase)
+{
+	g_return_val_if_reached (0);
+}
+
+/**
+ * gtranslator_translation_memory_set_max_omits:
+ * @omits: the number of omits
+ *
+ * Sets the number of omits used in the search.
+ */
+void
+gtranslator_translation_memory_set_max_omits (GtranslatorTranslationMemory *obj,
+					      gsize omits)
+{
+	g_return_if_fail (GTR_IS_TRANSLATION_MEMORY (obj));
+	GTR_TRANSLATION_MEMORY_GET_IFACE (obj)->set_max_omits (obj, omits);
+}
+
+/* Default implementation */
+static void
+gtranslator_translation_memory_set_max_omits_default (GtranslatorTranslationMemory *obj,
+						      gsize omits)
+{
+	g_return_if_reached ();
+}
+
+/**
+ * gtranslator_translation_memory_set_max_delta:
+ * @delta: the difference in the length of strings
+ *
+ * Sets the difference in the length of string for searching in the database.
+ */
+void
+gtranslator_translation_memory_set_max_delta (GtranslatorTranslationMemory *obj,
+					      gsize delta)
+{
+	g_return_if_fail (GTR_IS_TRANSLATION_MEMORY (obj));
+	GTR_TRANSLATION_MEMORY_GET_IFACE (obj)->set_max_delta (obj, delta);
+}
+
+/* Default implementation */
+static void
+gtranslator_translation_memory_set_max_delta_default (GtranslatorTranslationMemory *obj,
+						      gsize omits)
+{
+	g_return_if_reached ();
+}
+
+/**
+ * gtranslator_translation_memory_set_max_items:
+ * @items: the max item to return in lookup
+ *
+ * Sets the number of item to return in gtranslator_translation_memory_lookup().
+ */
+void
+gtranslator_translation_memory_set_max_items (GtranslatorTranslationMemory *obj,
+					      gint items)
+{
+	g_return_if_fail (GTR_IS_TRANSLATION_MEMORY (obj));
+	GTR_TRANSLATION_MEMORY_GET_IFACE (obj)->set_max_items (obj, items);
+}
+
+/* Default implementation */
+static void
+gtranslator_translation_memory_set_max_items_default (GtranslatorTranslationMemory *obj,
+						      gint items)
+{
+	g_return_if_reached ();
+}
+
+static void
+gtranslator_translation_memory_base_init (GtranslatorTranslationMemoryIface* klass)
+{
+	static gboolean initialized = FALSE;
+
+	klass->store = gtranslator_translation_memory_store_default;
+	klass->lookup = gtranslator_translation_memory_lookup_default;
+	klass->set_max_omits = gtranslator_translation_memory_set_max_omits_default;
+	klass->set_max_delta = gtranslator_translation_memory_set_max_delta_default;
+	klass->set_max_items = gtranslator_translation_memory_set_max_items_default;
+	
+	if (!initialized) {
+
+		initialized = TRUE;
+	}
+}
+
+GType
+gtranslator_translation_memory_get_type (void)
+{
+	static GType type = 0;
+	if (!type) {
+		static const GTypeInfo info = {
+			sizeof (GtranslatorTranslationMemoryIface),
+			(GBaseInitFunc) gtranslator_translation_memory_base_init,
+			NULL, 
+			NULL,
+			NULL,
+			NULL,
+			0,
+			0,
+			NULL
+		};
+		type = g_type_register_static (G_TYPE_INTERFACE, "GtranslatorTranslationMemory", &info, 0);
+		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+	}
+	return type;			
+}

Added: trunk/src/translation-memory/translation-memory.h
==============================================================================
--- (empty file)
+++ trunk/src/translation-memory/translation-memory.h	Tue Sep 16 07:58:13 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008  Ignacio Casal Quinteiro <nacho resa gmail com>
+ * 
+ *     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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GTR_TRANSLATION_MEMORY_H_
+#define _GTR_TRANSLATION_MEMORY_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_TRANSLATION_MEMORY (gtranslator_translation_memory_get_type ())
+#define GTR_TRANSLATION_MEMORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTR_TYPE_TRANSLATION_MEMORY, GtranslatorTranslationMemory))
+#define GTR_IS_TRANSLATION_MEMORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTR_TYPE_TRANSLATION_MEMORY))
+#define GTR_TRANSLATION_MEMORY_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTR_TYPE_TRANSLATION_MEMORY, GtranslatorTranslationMemoryIface))
+
+typedef struct _GtranslatorTranslationMemory GtranslatorTranslationMemory;
+typedef struct _GtranslatorTranslationMemoryIface GtranslatorTranslationMemoryIface;
+
+struct _GtranslatorTranslationMemoryIface {
+	GTypeInterface g_iface;
+	
+
+	gboolean (*store) (GtranslatorTranslationMemory *obj,
+			   const gchar *original,
+			   const gchar *translation);
+	GList * (*lookup) (GtranslatorTranslationMemory *obj,
+			   const gchar *phrase);
+	void (*set_max_omits) (GtranslatorTranslationMemory *obj,
+			       gsize omits);
+	void (*set_max_delta) (GtranslatorTranslationMemory *obj,
+			       gsize delta);
+	void (*set_max_items) (GtranslatorTranslationMemory *obj,
+			       gint items);
+};
+
+typedef struct _GtranslatorTranslationMemoryMatch GtranslatorTranslationMemoryMatch;
+struct _GtranslatorTranslationMemoryMatch {
+	gchar *match;
+	gint level;
+};
+
+GType  gtranslator_translation_memory_get_type            (void);
+
+gboolean   gtranslator_translation_memory_store           (GtranslatorTranslationMemory *obj,
+							   const gchar *original,
+							   const gchar *translation);
+						       
+GList *   gtranslator_translation_memory_lookup           (GtranslatorTranslationMemory *obj,
+							   const gchar *phrase);
+
+void      gtranslator_translation_memory_set_max_omits    (GtranslatorTranslationMemory *obj,
+							   gsize omits);
+
+void      gtranslator_translation_memory_set_max_delta    (GtranslatorTranslationMemory *obj,
+							   gsize delta);
+
+void      gtranslator_translation_memory_set_max_items    (GtranslatorTranslationMemory *obj,
+							   gint items);
+
+G_END_DECLS
+
+#endif

Modified: trunk/src/utils.c
==============================================================================
--- trunk/src/utils.c	(original)
+++ trunk/src/utils.c	Tue Sep 16 07:58:13 2008
@@ -30,6 +30,128 @@
 #include <glade/glade.h>
 #include <gtk/gtk.h>
 
+static const gchar * badwords[]= 
+{
+	"a",
+	//"all",
+	"an",
+	//"are",
+	//"can",
+	//"for",
+	//"from",
+	"have",
+	//"it",
+	//"may",
+	//"not",
+	"of",
+	//"that",
+	"the",
+	//"this",
+	//"was",
+	"will",
+	//"with",
+	//"you",
+	//"your",
+	NULL
+};
+
+static gboolean
+check_good_word (const gchar *word, gchar **badwords)
+{
+	gboolean check = TRUE;
+	gchar *lower = g_utf8_strdown (word, -1);
+	gint i = 0;
+	
+	while (badwords[i] != NULL)
+	{
+		gchar *lower_collate = g_utf8_collate_key (lower, -1);
+		
+		if (strcmp (lower_collate, badwords[i]) == 0)
+		{
+			check = FALSE;
+			g_free (lower_collate);
+			break;
+		}
+		i++;
+		g_free (lower_collate);
+	}
+	return check;
+}
+
+/**
+ * gtranslator_utils_split_string_in_words:
+ * @string: the text to process
+ *
+ * Process a text and split it in words using pango.
+ * 
+ * Returns: an array of words of the processed text
+ */
+gchar **
+gtranslator_utils_split_string_in_words (const gchar *string)
+{
+	PangoLanguage *lang = pango_language_from_string ("en");
+	PangoLogAttr *attrs;
+	GPtrArray *array;
+	gint char_len;
+	gint i = 0;
+	gchar *s;
+	static gchar **badwords_collate = NULL;
+	
+	if (badwords_collate == NULL)
+	{
+		gint words_size = g_strv_length ((gchar **)badwords);
+		gint x = 0;
+		
+		badwords_collate = g_new0 (gchar *, words_size + 1);
+		
+		while (badwords[x] != NULL)
+		{
+			badwords_collate[x] = g_utf8_collate_key (badwords[x], -1);
+			x++;
+		}
+		badwords_collate[x] = NULL;
+	}
+
+	char_len = g_utf8_strlen (string, -1);
+	attrs = g_new (PangoLogAttr, char_len + 1);
+	
+	pango_get_log_attrs (string,
+			     strlen (string),
+			     -1,
+			     lang,
+			     attrs,
+			     char_len + 1);
+
+	array = g_ptr_array_new ();
+	
+	s = (gchar *)string;
+	while (i <= char_len)
+	{
+		gchar *start, *end;
+		
+		if (attrs[i].is_word_start)
+			start = s;
+		if (attrs[i].is_word_end)
+		{
+			gchar *word;
+			
+			end = s;
+			word = g_strndup (start, end - start);
+			
+			if (check_good_word (word, badwords_collate))
+				g_ptr_array_add (array, word);
+		}
+
+		i++;
+		s = g_utf8_next_char (s);
+	}
+	
+	g_free (attrs);
+	g_ptr_array_add (array, NULL);
+	
+	return (gchar **)g_ptr_array_free (array, FALSE);
+}
+
 xmlDocPtr 
 gtranslator_xml_new_doc (const gchar *name) 
 {
@@ -50,6 +172,15 @@
   return doc;
 }
 
+/**
+ * gtranslator_gtk_button_new_with_stock_icon:
+ * @label: the label of the button
+ * @stock_id: the id of the stock image
+ * 
+ * Convenience function to create a #GtkButton with a stock image.
+ * 
+ * Returns: a new #GtkButton
+ */
 GtkWidget *
 gtranslator_gtk_button_new_with_stock_icon (const gchar *label,
 				      const gchar *stock_id)
@@ -64,12 +195,22 @@
         return button;
 }
 
+/**
+ * gtranslator_utils_menu_position_under_widget:
+ * @menu: a #GtkMenu
+ * @x: the x position of the widget
+ * @y: the y position of the widget
+ * @push_in: 
+ * @user_data: the widget to get the position
+ * 
+ * It returns the position to popup a menu in a specific widget.
+ */
 void
 gtranslator_utils_menu_position_under_widget (GtkMenu  *menu,
-					gint     *x,
-					gint     *y,
-					gboolean *push_in,
-					gpointer  user_data)
+					      gint     *x,
+					      gint     *y,
+					      gboolean *push_in,
+					      gpointer  user_data)
 {
 	GtkWidget *w = GTK_WIDGET (user_data);
 	GtkRequisition requisition;
@@ -91,12 +232,22 @@
 	*push_in = TRUE;
 }
 
+/**
+ * gtranslator_utils_menu_position_under_widget:
+ * @menu: a #GtkMenu
+ * @x: the x position of the widget
+ * @y: the y position of the widget
+ * @push_in: 
+ * @user_data: the widget to get the position
+ * 
+ * It returns the position to popup a menu in a TreeView.
+ */
 void
 gtranslator_utils_menu_position_under_tree_view (GtkMenu  *menu,
-					   gint     *x,
-					   gint     *y,
-					   gboolean *push_in,
-					   gpointer  user_data)
+						 gint     *x,
+						 gint     *y,
+						 gboolean *push_in,
+						 gpointer  user_data)
 {
 	GtkTreeView *tree = GTK_TREE_VIEW (user_data);
 	GtkTreeModel *model;
@@ -155,7 +306,7 @@
  * of error it returns FALSE and sets error_widget to a GtkLabel containing
  * the error message to display.
  *
- * Returns FALSE if an error occurs, TRUE on success.
+ * Returns: FALSE if an error occurs, TRUE on success.
  */
 gboolean
 gtranslator_utils_get_glade_widgets (const gchar *filename,
@@ -309,7 +460,6 @@
 /**
  * gtranslator_utils_drop_get_uris:
  * @selection_data: the #GtkSelectionData from drag_data_received
- * @info: the info from drag_data_received
  *
  * Create a list of valid uri's from a uri-list drop.
  * 
@@ -317,31 +467,27 @@
  *		 were no valid uris. g_strfreev should be used when the 
  *		 string array is no longer used
  */
-gchar **
-gtranslator_utils_drop_get_uris (GtkSelectionData *selection_data)
+GSList *
+gtranslator_utils_drop_get_locations (GtkSelectionData *selection_data)
 {
 	gchar **uris;
 	gint i;
-	gint p = 0;
-	gchar **uri_list;
+	GSList *locations = NULL;
 
 	uris = g_uri_list_extract_uris ((gchar *) selection_data->data);
-	uri_list = g_new0(gchar *, g_strv_length (uris) + 1);
 
 	for (i = 0; uris[i] != NULL; i++)
 	{
+		GFile *file;
 		/* Silently ignore malformed URI/filename */
 		if (gtranslator_utils_is_valid_uri (uris[i]))
-			uri_list[p++] = g_strdup (uris[i]);
-	}
-
-	if (*uri_list == NULL)
-	{
-		g_free(uri_list);
-		return NULL;
+		{
+			file = g_file_new_for_uri (uris[i]);
+			locations = g_slist_prepend (locations, file);
+		}
 	}
 
-	return uri_list;
+	return locations;
 }
 
 gchar *
@@ -516,11 +662,20 @@
 	return ret;
 }
 
+/**
+ * gtranslator_utils_activate_url:
+ * @dialog: a #GtkAboutDialog
+ * @url: the url to show
+ * @data: useless data variable
+ * 
+ * Shows the corresponding @url in the default browser.
+ */
 void
 gtranslator_utils_activate_url (GtkAboutDialog *dialog,
 				const gchar *url,
 				gpointer data)
 {
+	//FIXME: gtk_url_show deprecates this func.
 	gchar *open[3];
 
 	if (g_find_program_in_path ("xdg-open"))
@@ -541,6 +696,48 @@
 			     NULL, NULL, NULL);
 }
 
+/**
+ * gtranslator_utils_activate_email:
+ * @dialog: a #GtkAboutDialog
+ * @email: the email to show
+ * @data: useless data variable
+ * 
+ * Shows the corresponding @email in the default mailer.
+ */
+void
+gtranslator_utils_activate_email (GtkAboutDialog *dialog,
+				  const gchar *email,
+				  gpointer data)
+{
+	//FIXME: gtk_url_show deprecates this func.
+	gchar *open[3];
+
+	if (g_find_program_in_path ("xdg-email"))
+	{
+		open[0] = "xdg-email";
+	}
+	else return;
+	
+	open[1] = (gchar *)email;
+	open[2] = NULL;
+					
+	gdk_spawn_on_screen (gdk_screen_get_default (),
+			     NULL,
+			     open,
+			     NULL,
+			     G_SPAWN_SEARCH_PATH,
+			     NULL,
+			     NULL, NULL, NULL);
+}
+
+/**
+ * gtranslator_utils_help_display:
+ * @parent: a #GtkWindow
+ * @doc_id: the name of the type of doc
+ * @file_name: the name of the doc
+ * 
+ * Shows the help for an specific document in the default help browser.
+ */
 void
 gtranslator_utils_help_display (GtkWindow   *parent,
 				const gchar *doc_id,
@@ -606,6 +803,13 @@
 	g_free (command);
 }
 
+/**
+ * gtranslator_utils_get_user_config_dir:
+ * 
+ * Returns the default config dir for gtranslator.
+ * 
+ * Returns: the config dir for gtranslator.
+ */
 gchar *
 gtranslator_utils_get_user_config_dir (void)
 {
@@ -613,3 +817,107 @@
 				 "gtranslator",
 				 NULL);
 }
+
+gchar *gtranslator_utils_get_current_date (void)
+{
+  time_t now;
+  struct tm *now_here;
+  gchar *date = g_malloc (11);
+  
+  now = time(NULL);
+  now_here = localtime(&now);
+  strftime(date, 11, "%Y-%m-%d", now_here);
+
+  return date;
+}
+
+gchar *gtranslator_utils_get_current_time (void)
+{
+  time_t now;
+  struct tm *now_here;
+  gchar *t = g_malloc (11);
+
+  now = time(NULL);
+  now_here = localtime(&now);
+  strftime(t, 11, "%H:%M%z", now_here);
+ 
+  return t;
+}
+
+gchar *gtranslator_utils_get_current_year (void)
+{
+  time_t now;
+  struct tm *now_here;
+  gchar *year=g_malloc (5);
+
+  now = time(NULL);
+  now_here = localtime(&now);
+  strftime(year, 5, "%Y", now_here);
+
+  return year;
+}
+
+/**
+ * gtranslator_utils_scan_dir:
+ * @dir: the dir to parse
+ * @list: the list where to store the GFiles
+ * @po_name: the name of the specific po file to search or NULL.
+ *
+ * Scans the directory and subdirectories of @dir looking for filenames remained
+ * with .po or files that matches @po_name. The contents of @list must be freed with
+ * g_slist_foreach (list, (GFunc)g_object_unref, NULL).
+ */
+void
+gtranslator_utils_scan_dir (GFile *dir,
+			    GSList **list,
+			    const gchar *po_name)
+{
+	GFileInfo *info;
+	GError *error;
+	GFile *file;
+	GFileEnumerator *enumerator;
+
+	error = NULL;
+	enumerator = g_file_enumerate_children (dir,
+						G_FILE_ATTRIBUTE_STANDARD_NAME,
+						G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+						NULL,
+						&error);
+	if (enumerator) 
+	{
+		error = NULL;
+		
+		while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL) 
+		{
+			const gchar *name;
+			gchar *filename;
+			
+			name = g_file_info_get_name (info);
+			file = g_file_get_child (dir, name);
+
+			if (po_name != NULL)
+			{
+				if (g_str_has_suffix (po_name, ".po"))
+					filename = g_strdup (po_name);
+				else 
+					filename = g_strconcat (po_name, ".po", NULL);
+			}
+			else
+				filename = g_strdup (".po");
+			
+			if (g_str_has_suffix (name, filename))
+				*list = g_slist_prepend (*list, file);
+			g_free (filename);
+
+			gtranslator_utils_scan_dir (file, list, po_name);
+			g_object_unref (info);
+		}
+		g_file_enumerator_close (enumerator, NULL, NULL);
+		g_object_unref (enumerator);
+		
+		if (error)
+		{
+			g_warning (error->message);
+		}
+	}
+}
\ No newline at end of file

Modified: trunk/src/utils.h
==============================================================================
--- trunk/src/utils.h	(original)
+++ trunk/src/utils.h	Tue Sep 16 07:58:13 2008
@@ -25,6 +25,9 @@
 #include <gtk/gtkaboutdialog.h>
 #include <gtk/gtkwindow.h>
 #include <libxml/tree.h>
+#include <gio/gio.h>
+
+gchar **       gtranslator_utils_split_string_in_words (const gchar *string);
 
 xmlDocPtr      gtranslator_xml_new_doc (const gchar *name);
 
@@ -51,7 +54,7 @@
 						       const gchar *widget_name,
 						       ...)G_GNUC_NULL_TERMINATED;
 
-gchar        **gtranslator_utils_drop_get_uris        (GtkSelectionData *selection_data);
+GSList        *gtranslator_utils_drop_get_locations   (GtkSelectionData *selection_data);
 
 gchar         *gtranslator_utils_escape_search_text   (const gchar* text);
 
@@ -65,6 +68,10 @@
 void           gtranslator_utils_activate_url         (GtkAboutDialog *dialog,
 						       const gchar *url,
 						       gpointer data);
+
+void           gtranslator_utils_activate_email       (GtkAboutDialog *dialog,
+						       const gchar *email,
+						       gpointer data);
 						       
 void           gtranslator_utils_help_display         (GtkWindow   *parent,
 						       const gchar *doc_id,
@@ -72,4 +79,14 @@
 						       
 gchar         *gtranslator_utils_get_user_config_dir  (void);
 
+gchar         *gtranslator_utils_get_current_date (void);
+
+gchar         *gtranslator_utils_get_current_time (void);
+
+gchar         *gtranslator_utils_get_current_year (void);
+
+void           gtranslator_utils_scan_dir              (GFile *dir,
+							GSList **list,
+							const gchar *po_name);
+
 #endif

Modified: trunk/src/view.c
==============================================================================
--- trunk/src/view.c	(original)
+++ trunk/src/view.c	Tue Sep 16 07:58:13 2008
@@ -40,19 +40,12 @@
 #include <gtksourceview/gtksourcelanguagemanager.h>
 #include <gtksourceview/gtksourceiter.h>
 #include <gtksourceview/gtksourcebuffer.h>
+#include <gtksourceview/gtksourcestyleschememanager.h>
 
-//#undef HAVE_GTKSPELL
 #ifdef HAVE_GTKSPELL
 #include <gtkspell/gtkspell.h>
 #endif
 
-#undef HAVE_SPELL_CHECK
-#ifdef HAVE_SPELL_CHECK
-#include <gtkspellcheck/client.h>
-#include <gtkspellcheck/manager.h>
-#include <gtkspellcheck/textviewclient.h>
-#endif
-
 #define GTR_VIEW_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
 						 	(object),	\
 						 	GTR_TYPE_VIEW,     \
@@ -70,11 +63,6 @@
 #ifdef HAVE_GTKSPELL
 	GtkSpell *spell;
 #endif
-	
-#ifdef HAVE_SPELL_CHECK
-	GtkSpellCheckClient *client;
-	GtkSpellCheckManager *manager;
-#endif
 };
 
 
@@ -101,19 +89,6 @@
 	}
 }
 #endif
-
-#ifdef HAVE_SPELL_CHECK
-static void
-gtranslator_attach_spellcheck(GtranslatorView *view)
-{
-	view->priv->client = GTK_SPELL_CHECK_CLIENT(gtk_spell_check_text_view_client_new(GTK_TEXT_VIEW(view)));
-	view->priv->manager = gtk_spell_check_manager_new(NULL, TRUE);
-	
-	gtk_spell_check_manager_attach(view->priv->manager,
-				       view->priv->client);
-}
-#endif
-
 	       
 static void
 gtranslator_view_init (GtranslatorView *view)
@@ -137,7 +112,7 @@
 	    ++temp)
 		g_ptr_array_add(dirs, g_strdup(*temp));
 		
-	g_ptr_array_add(dirs, g_strdup(DATADIR));
+	g_ptr_array_add(dirs, g_strdup(PKGDATADIR));
 	g_ptr_array_add(dirs, NULL);
 	langs = (gchar **)g_ptr_array_free(dirs, FALSE);
 
@@ -176,6 +151,11 @@
 	{
 		gtranslator_view_set_font (view, TRUE, NULL);
 	}
+	
+	/*
+	 * Set scheme color according to preferences
+	 */
+	gtranslator_view_reload_scheme_color (view);
 }
 
 static void
@@ -194,17 +174,32 @@
 	object_class->finalize = gtranslator_view_finalize;
 }
 
+/**
+ * gtranslator_view_new:
+ *
+ * Creates a new #GtranslatorView. An empty default buffer will be created for you.
+ * 
+ * Returns: a new #GtranslatorView
+ */
 GtkWidget *
 gtranslator_view_new (void)
 {
 	GtkWidget *view;
 	
 	view = GTK_WIDGET (g_object_new (GTR_TYPE_VIEW, NULL));
-	gtk_widget_show_all(view);
 	return view;
 }
 
-
+/**
+ * gtranslator_view_get_selected_text:
+ * @view: a #GtranslatorView
+ * @selected_text: it stores the text selected in the #GtranslatorView
+ * @len: it stores the length of the @selected_text
+ *
+ * Gets the selected text region of the #GtranslatorView
+ *
+ * Returns: TRUE if the @selected_text was got correctly.
+ */
 gboolean
 gtranslator_view_get_selected_text (GtranslatorView *view,
 				    gchar         **selected_text,
@@ -251,13 +246,6 @@
 #ifdef HAVE_GTKSPELL
 		gtranslator_attach_gtkspell(view);
 #endif
-#ifdef HAVE_SPELL_CHECK
-		if(!view->priv->manager)
-			gtranslator_attach_spellcheck(view);
-		else
-			gtk_spell_check_manager_set_active(view->priv->manager,
-							   TRUE);
-#endif
 	}
 	else
 	{
@@ -266,12 +254,6 @@
 			return;
 		gtkspell_detach(view->priv->spell);
 #endif
-#ifdef HAVE_SPELL_CHECK
-		if(!view->priv->manager)
-			return;
-		gtk_spell_check_manager_set_active(view->priv->manager,
-						   FALSE);
-#endif
 	}
 }
 
@@ -300,6 +282,13 @@
 	gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
+/**
+ * gtranslator_view_cut_clipboard:
+ * @view: a #GtranslatorView
+ *
+ * Copies the currently-selected text to a clipboard,
+ * then deletes said text if it's editable.
+ */
 void
 gtranslator_view_cut_clipboard (GtranslatorView *view)
 {
@@ -328,6 +317,12 @@
 				      0.0);
 }
 
+/**
+ * gtranslator_view_copy_clipboard:
+ * @view: a #GtranslatorView
+ *
+ * Copies the currently-selected text to a clipboard.
+ */
 void
 gtranslator_view_copy_clipboard (GtranslatorView *view)
 {
@@ -347,6 +342,13 @@
 	/* on copy do not scroll, we are already on screen */
 }
 
+/**
+ * gtranslator_view_cut_clipboard:
+ * @view: a #GtranslatorView
+ *
+ * Pastes the contents of a clipboard at the insertion point,
+ * or at override_location.
+ */
 void
 gtranslator_view_paste_clipboard (GtranslatorView *view)
 {
@@ -407,8 +409,13 @@
 }
 
 
-/*
- * Search funcs
+/**
+ * gtranslator_view_set_search_text:
+ * @view: a #GtranslatorView
+ * @text: the text to set for searching
+ * @flags: a #GtranslatorSearchFlags
+ *
+ * Stores the text to search for in the @view with some specific @flags.
  */
 void
 gtranslator_view_set_search_text (GtranslatorView *view,
@@ -469,14 +476,21 @@
 					&begin,
 					&end);
 	}*/
-	
-	if (notify)
-		g_object_notify (G_OBJECT (doc), "can-search-again");
 }
 
+/**
+ * gtranslator_view_get_search_text:
+ * @view: a #GtranslatorView
+ * @flags: the #GtranslatorSearchFlags of the stored text.
+ * 
+ * Returns the text to search for it and the #GtranslatorSearchFlags of that
+ * text.
+ * 
+ * Returns: the text to search for it.
+ */
 gchar *
 gtranslator_view_get_search_text (GtranslatorView *view,
-				guint         *flags)
+				  guint         *flags)
 {
 	g_return_val_if_fail (GTR_IS_VIEW (view), NULL);
 
@@ -486,6 +500,12 @@
 	return gtranslator_utils_escape_search_text (view->priv->search_text);
 }
 
+/**
+ * gtranslator_view_get_can_search_again:
+ * @view: a #GtranslatorView
+ * 
+ * Returns: TRUE if it can search again
+ */
 gboolean
 gtranslator_view_get_can_search_again (GtranslatorView *view)
 {
@@ -495,8 +515,24 @@
 	        (*view->priv->search_text != '\0'));
 }
 
+/**
+ * gtranslator_view_search_forward:
+ * @view: a #GtranslatorView
+ * @start: start of search 
+ * @end: bound for the search, or %NULL for the end of the buffer
+ * @match_start: return location for start of match, or %NULL
+ * @match_end: return location for end of match, or %NULL
+ * 
+ * Searches forward for str. Any match is returned by setting match_start to the
+ * first character of the match and match_end to the first character after the match.
+ * The search will not continue past limit.
+ * Note that a search is a linear or O(n) operation, so you may wish to use limit
+ * to avoid locking up your UI on large buffers. 
+ * 
+ * Returns: whether a match was found
+ */
 gboolean
-gtranslator_view_search_forward (GtranslatorView     *view,
+gtranslator_view_search_forward (GtranslatorView   *view,
 				 const GtkTextIter *start,
 				 const GtkTextIter *end,
 				 GtkTextIter       *match_start,
@@ -567,9 +603,25 @@
 	
 	return found;			    
 }
-						 
+
+/**
+ * gtranslator_view_search_backward:
+ * @view: a #GtranslatorView
+ * @start: start of search 
+ * @end: bound for the search, or %NULL for the end of the buffer
+ * @match_start: return location for start of match, or %NULL
+ * @match_end: return location for end of match, or %NULL
+ * 
+ * Searches backward for str. Any match is returned by setting match_start to the
+ * first character of the match and match_end to the first character after the match.
+ * The search will not continue past limit.
+ * Note that a search is a linear or O(n) operation, so you may wish to use limit
+ * to avoid locking up your UI on large buffers. 
+ * 
+ * Returns: whether a match was found
+ */
 gboolean
-gtranslator_view_search_backward (GtranslatorView     *view,
+gtranslator_view_search_backward (GtranslatorView   *view,
 				  const GtkTextIter *start,
 				  const GtkTextIter *end,
 				  GtkTextIter       *match_start,
@@ -641,6 +693,18 @@
 	return found;		      
 }
 
+/**
+ * gtranslator_view_replace_all:
+ * @view: a #GtranslatorView
+ * @find: the text to find
+ * @replace: the text to replace @find
+ * @flags: a #GtranslatorSearchFlags
+ * 
+ * Replaces all matches of @find with @replace and returns the number of 
+ * replacements.
+ * 
+ * Returns: the number of replacements made it.
+ */
 gint 
 gtranslator_view_replace_all (GtranslatorView     *view,
 			      const gchar         *find, 
@@ -744,3 +808,27 @@
 
 	return cont;
 }
+
+/**
+ * gtranslator_view_reload_scheme_color:
+ * @view: a #GtranslatorView
+ *
+ * Reloads the gtksourceview scheme color. Neccessary when the scheme color 
+ * changes.
+ */
+void
+gtranslator_view_reload_scheme_color (GtranslatorView *view)
+{
+	GtkSourceBuffer *buf;
+	GtkSourceStyleScheme *scheme;
+	GtkSourceStyleSchemeManager *manager;
+	const gchar *scheme_id;
+	
+	buf = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
+	manager = gtk_source_style_scheme_manager_get_default ();
+	
+	scheme_id = gtranslator_prefs_manager_get_scheme_color ();
+	scheme = gtk_source_style_scheme_manager_get_scheme (manager, scheme_id);
+	
+	gtk_source_buffer_set_style_scheme (buf, scheme);
+}
\ No newline at end of file

Modified: trunk/src/view.h
==============================================================================
--- trunk/src/view.h	(original)
+++ trunk/src/view.h	Tue Sep 16 07:58:13 2008
@@ -108,6 +108,8 @@
 gchar           *gtranslator_view_get_search_text        (GtranslatorView *view,
 							  guint         *flags);
 
+void             gtranslator_view_reload_scheme_color    (GtranslatorView *view);
+
 
 /* Search macros */
 #define GTR_SEARCH_IS_DONT_SET_FLAGS(sflags) ((sflags & GTR_SEARCH_DONT_SET_FLAGS) != 0)

Modified: trunk/src/window.c
==============================================================================
--- trunk/src/window.c	(original)
+++ trunk/src/window.c	Tue Sep 16 07:58:13 2008
@@ -46,6 +46,11 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
+#define GTR_STOCK_FUZZY_NEXT "gtranslator-fuzzy-next"
+#define GTR_STOCK_FUZZY_PREV "gtranslator-fuzzy-prev"
+#define GTR_STOCK_UNTRANS_NEXT "gtranslator-untranslated-next"
+#define GTR_STOCK_UNTRANS_PREV "gtranslator-untranslated-prev"
+
 #define GTR_WINDOW_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
 					 (object),	\
 					 GTR_TYPE_WINDOW,     \
@@ -74,12 +79,12 @@
 	GHashTable *widgets;
 	
 	GtkWidget *statusbar;
-	guint generic_message_cid;
-	guint tip_message_cid;
 		
 	GtkUIManager *ui_manager;
 	GtkRecentManager *recent_manager;
 	GtkWidget *recent_menu;
+
+        GtkWidget *tm_menu;
 	
 	gint            width;
         gint            height; 
@@ -108,9 +113,6 @@
 	{ "FileOpen", GTK_STOCK_OPEN, NULL, "<control>O",
 	  N_("Open a PO file"),
 	  G_CALLBACK (gtranslator_open_file_dialog) },
-	{ "FileOpenUri", NULL, N_("Open _Location..."), NULL,
-	  N_("Open a PO file from a given URI"), NULL},
-	//  G_CALLBACK (gtranslator_open_uri_dialog) },
 	{ "FileRecentFiles", NULL, N_("_Recent Files"), NULL,
 	  NULL, NULL },
 	{ "FileQuitWindow", GTK_STOCK_QUIT, NULL, "<control>Q", 
@@ -128,7 +130,7 @@
 		
 	/* Help menu */
 	{ "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL,
-	  NULL },
+	  G_CALLBACK (gtranslator_cmd_help_contents) },
 	{ "HelpAbout", GTK_STOCK_ABOUT, NULL, NULL, NULL,
 	  G_CALLBACK (gtranslator_about_dialog) },
 };
@@ -168,8 +170,8 @@
 	  N_("Paste the contents of the clipboard"),
 	  G_CALLBACK (gtranslator_actions_edit_paste) },
 	{ "EditClear", GTK_STOCK_CLEAR, NULL, NULL,
-	  N_("Clear the selected translation"), NULL},
-	//  G_CALLBACK (gtranslator_selection_clear) },
+	  N_("Clear the selected translation"),
+	  G_CALLBACK (gtranslator_actions_edit_clear) },
 	{ "EditHeader", GTK_STOCK_PROPERTIES, N_("_Header..."), NULL, NULL,
 	  G_CALLBACK (gtranslator_actions_edit_header) },
 	{ "EditComment", GTK_STOCK_INDEX, N_("C_omment..."), NULL,
@@ -181,11 +183,19 @@
 	{ "EditFuzzy", NULL, N_("Toggle _Fuzzy Status"), "<control>U",
 	  N_("Toggle fuzzy status of a message"),
 	  G_CALLBACK (gtranslator_message_status_toggle_fuzzy) },
-	
+	{ "EditTranslationMemory", NULL, N_("_Translation Memory"), NULL, NULL, NULL},
+
+
 	/* View menu */
-	{ "ViewSidePane", NULL, N_("Side _Pane"), "F9",
+	{ "ViewContext", NULL, N_("_Context"), "<control>J",
+	  N_("Show the Context panel"),
+	  G_CALLBACK (gtranslator_actions_view_context) },
+	{ "ViewTranslationMemory", NULL, N_("_Translation Memory"), "<control>K",
+	  N_("Show the Translation Memory panel"),
+	  G_CALLBACK (gtranslator_actions_view_translation_memory) },
+	/*{ "ViewSidePane", NULL, N_("Side _Pane"), "F9",
 	  N_("Show or hide the side pane in the current window"),
-	  NULL },
+	  NULL },*/
 	
 	/* Bookmarks menu */
 	/*{ "BookmarksAdd", GTK_STOCK_ADD, N_("_Add Bookmark"), "<control>D",
@@ -219,32 +229,38 @@
 	{ "GoLast", GTK_STOCK_GOTO_LAST, NULL, NULL,
           N_("Go to the last message"),
           G_CALLBACK (gtranslator_message_go_to_last) },
-	{ "GoJumpTo", GTK_STOCK_JUMP_TO, NULL, NULL,
-          N_("Go to specified message number"), NULL},
-          //G_CALLBACK (gtranslator_go_to_dialog) },
-	{ "GoNextFuzzy", GTK_STOCK_GO_FORWARD, N_("Next Fuz_zy"),
+	{ "GoNextFuzzy", GTR_STOCK_FUZZY_NEXT, N_("Next Fuz_zy"),
 	  "<control>Page_Down", N_("Go to the next fuzzy message"),
           G_CALLBACK (gtranslator_message_go_to_next_fuzzy) },
-	{ "GoPreviousFuzzy", GTK_STOCK_GO_BACK, N_("Previous Fuzz_y"),
+	{ "GoPreviousFuzzy", GTR_STOCK_FUZZY_PREV, N_("Previous Fuzz_y"),
 	  "<control>Page_Up", N_("Go to the previous fuzzy message"),
           G_CALLBACK (gtranslator_message_go_to_prev_fuzzy) },
-	{ "GoNextUntranslated", GTK_STOCK_GO_FORWARD, N_("Next _Untranslated"),
+	{ "GoNextUntranslated", GTR_STOCK_UNTRANS_NEXT, N_("Next _Untranslated"),
 	  "<alt>Page_Down", N_("Go to the next untranslated message"),
           G_CALLBACK (gtranslator_message_go_to_next_untranslated) },
-	{ "GoPreviousUntranslated", GTK_STOCK_GO_BACK, N_("Previ_ous Untranslated"),
+	{ "GoPreviousUntranslated", GTR_STOCK_UNTRANS_PREV, N_("Previ_ous Untranslated"),
 	  "<alt>Page_Up", N_("Go to the previous untranslated message"),
           G_CALLBACK (gtranslator_message_go_to_prev_untranslated) },
+	{ "GoNextFuzzyUntranslated", GTK_STOCK_GO_FORWARD, N_("Next Fu_zzy or Untranslated"),
+	  "<control><shift>Page_Down", N_("Go to the next fuzzy or untranslated message"),
+          G_CALLBACK (gtranslator_message_go_to_next_fuzzy_or_untranslated) },
+	{ "GoPreviousFuzzyUntranslated", GTK_STOCK_GO_BACK, N_("Pre_vious Fuzzy or Untranslated"),
+	  "<control><shift>Page_Up", N_("Go to the previous fuzzy or untranslated message"),
+          G_CALLBACK (gtranslator_message_go_to_prev_fuzzy_or_untranslated) },
+	{ "GoJump", GTK_STOCK_JUMP_TO, NULL,
+	  "<control>G", N_("Jumps to a specific message"),
+          G_CALLBACK (gtranslator_message_jump) },
 
 	/* Search menu*/
 	{ "SearchFind", GTK_STOCK_FIND, NULL, "<control>F",
 	  N_("Search for text"),
 	  G_CALLBACK(_gtranslator_actions_search_find) },
-	{ "SearchFindNext", NULL, N_("Find Ne_xt"), NULL,
+	/*{ "SearchFindNext", NULL, N_("Find Ne_xt"), NULL,
 	  N_("Search forward for the same text"), NULL},
 	 // G_CALLBACK (gtranslator_find) },
 	{ "SearchFindPrevious", NULL, N_("Find _Previous"), NULL,
 	  N_("Search backward for the same text"), NULL},
-	 // G_CALLBACK (gtranslator_find) },
+	 // G_CALLBACK (gtranslator_find) },*/
 	{ "SearchReplace", GTK_STOCK_FIND_AND_REPLACE, NULL, "<control>H",
 	  N_("Search for and replace text"),
 	  G_CALLBACK (_gtranslator_actions_search_replace) },
@@ -334,7 +350,7 @@
 	{
 		gchar *filename;
 		
-		filename = g_build_filename (DATADIR"/layout.xml", NULL);
+		filename = g_build_filename (PKGDATADIR"/layout.xml", NULL);
 		//DEBUG_PRINT ("Layout = %s", filename);
 		if (!gdl_dock_layout_load_from_file (window->priv->layout_manager,
 						     filename))
@@ -599,6 +615,16 @@
 					     "GoPreviousUntranslated");
 	gtk_action_set_sensitive (action, 
 				  gtranslator_po_get_prev_untrans(po) != NULL);
+	
+	action = gtk_action_group_get_action(window->priv->action_group,
+					     "GoNextFuzzyUntranslated");
+	gtk_action_set_sensitive (action, 
+				  gtranslator_po_get_next_fuzzy_or_untrans (po) != NULL);
+	
+	action = gtk_action_group_get_action(window->priv->action_group,
+					     "GoPreviousFuzzyUntranslated");
+	gtk_action_set_sensitive (action, 
+				  gtranslator_po_get_prev_fuzzy_or_untrans (po) != NULL);
 }
 
 static void
@@ -746,28 +772,6 @@
 	return GTR_WINDOW (target_window);
 }
 
-static void
-load_uris_from_drop (GtranslatorWindow  *window,
-		     gchar       **uri_list)
-{
-	GSList *uris = NULL;
-	gint i;
-	
-	if (uri_list == NULL)
-		return;
-	
-	for (i = 0; uri_list[i] != NULL; ++i)
-	{
-		uris = g_slist_prepend (uris, uri_list[i]);
-	}
-
-	uris = g_slist_reverse (uris);
-	gtranslator_actions_load_uris (window,
-				      uris);
-
-	g_slist_free (uris);
-}
-
 /* Handle drops on the GtranslatorWindow */
 static void
 drag_data_received_cb (GtkWidget        *widget,
@@ -780,7 +784,7 @@
 		       gpointer          data)
 {
 	GtranslatorWindow *window;
-	gchar **uri_list;
+	GSList *locations;
 
 	window = get_drop_window (widget);
 	
@@ -789,9 +793,11 @@
 
 	if (info == TARGET_URI_LIST)
 	{
-		uri_list = gtranslator_utils_drop_get_uris(selection_data);
-		load_uris_from_drop (window, uri_list);
-		g_strfreev (uri_list);
+		locations = gtranslator_utils_drop_get_locations (selection_data);
+		gtranslator_actions_load_locations (window, locations);
+		
+		g_slist_foreach (locations, (GFunc)g_object_unref, NULL);
+		g_slist_free (locations);
 	}
 }
 
@@ -812,6 +818,42 @@
 }
 
 static void
+set_window_title (GtranslatorWindow *window,
+		  gboolean with_path)
+{
+  GtranslatorPo *po;
+  GtranslatorPoState state;
+  GtranslatorTab *active_tab;
+  GFile *file;
+  gchar *title;
+  
+  if (with_path)
+    {
+      po = gtranslator_tab_get_po (GTR_TAB (gtranslator_window_get_active_tab (window)));
+      active_tab = gtranslator_window_get_active_tab (window);
+      state = gtranslator_po_get_state (gtranslator_tab_get_po(active_tab));
+      po = gtranslator_tab_get_po (active_tab);
+      file = gtranslator_po_get_location (po);
+      
+      /*
+       * Translators: The title of the window when there is only one tab
+       */
+      title = g_strdup_printf (_("gtranslator - %s"), g_file_get_path (file));
+      if (state == GTR_PO_STATE_MODIFIED)
+	title = g_strdup_printf (_("gtranslator - *%s"), g_file_get_path (file));
+      else
+	title = g_strdup_printf (_("gtranslator - %s"), g_file_get_path (file));
+      
+      g_object_unref (file);
+    }
+  else
+    title = g_strdup (_("gtranslator"));
+  
+  gtk_window_set_title (GTK_WINDOW (window), title);
+  g_free (title);
+}
+
+static void
 notebook_switch_page(GtkNotebook *nb,
 		     GtkNotebookPage *page,
 		     gint page_num,
@@ -821,11 +863,21 @@
 	GList *msg;
 	GtranslatorView *view;
 	GtranslatorPo *po;
+	gint n_pages;
 	
 	tab = GTR_TAB (gtk_notebook_get_nth_page (nb, page_num));
 	if (tab == window->priv->active_tab)
 		return;
 	
+	/*
+	 * Set the window title
+	 */
+	n_pages = gtk_notebook_get_n_pages (nb);
+	if (n_pages == 1)
+		set_window_title (window, TRUE);
+	else
+		set_window_title (window, FALSE);
+	
 	window->priv->active_tab = tab;
 	view = gtranslator_tab_get_active_view (tab);
 	
@@ -845,13 +897,31 @@
 }
 
 static void
+notebook_page_removed (GtkNotebook *notebook,
+		       GtkWidget   *child,
+		       guint        page_num,
+		       GtranslatorWindow *window)
+{
+	gint n_pages;
+	
+	/*
+	 * Set the window title
+	 */
+	n_pages = gtk_notebook_get_n_pages (notebook);
+	if (n_pages == 1)
+		set_window_title (window, TRUE);
+	else
+		set_window_title (window, FALSE);
+}
+
+static void
 notebook_tab_close_request (GtranslatorNotebook *notebook,
 			    GtranslatorTab      *tab,
 			    GtranslatorWindow     *window)
 {
 	/* Note: we are destroying the tab before the default handler
 	 * seems to be ok, but we need to keep an eye on this. */
-	gtranslator_file_close (NULL, window);
+	gtranslator_close_tab (tab, window);
 	
 	gtranslator_plugins_engine_update_plugins_ui (gtranslator_plugins_engine_get_default (),
 						      window, FALSE);
@@ -907,9 +977,27 @@
 sync_state (GtranslatorPo    *po,
 	    GParamSpec  *pspec,
 	    GtranslatorWindow *window)
-{	
-	set_sensitive_according_to_tab (window,
-					gtranslator_tab_get_from_document (po));
+{
+  int n_pages = 0;
+
+  set_sensitive_according_to_tab (window,
+				  gtranslator_tab_get_from_document (po));
+  n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK(window->priv->notebook));
+
+  if (n_pages == 1)
+    set_window_title (window, TRUE);
+}
+
+static void
+showed_message_cb (GtranslatorTab *tab,
+		   GtranslatorMsg *msg,
+		   GtranslatorWindow *window)
+{
+	g_return_if_fail (GTR_IS_TAB (tab));
+	
+	gtranslator_window_update_statusbar_message_count (tab, msg, window);
+	
+	set_sensitive_according_to_message (window, gtranslator_tab_get_po (tab));
 }
 
 static void
@@ -921,9 +1009,19 @@
 	GList *views;
 	GtranslatorTab *tab = GTR_TAB(child);
 	GtkTextBuffer *buffer;
+	gint n_pages;
 	
 	g_return_if_fail(GTR_IS_TAB(tab));
 	
+	/*
+	 * Set the window title
+	 */
+	n_pages = gtk_notebook_get_n_pages (notebook);
+	if (n_pages == 1)
+		set_window_title (window, TRUE);
+	else
+		set_window_title (window, FALSE);
+	
 	views = gtranslator_tab_get_all_views(tab, FALSE, TRUE);
 	
 	while(views)
@@ -955,7 +1053,7 @@
 				window);
 	g_signal_connect_after (child,
 				"showed_message",
-				G_CALLBACK(gtranslator_window_update_statusbar_message_count),
+				G_CALLBACK(showed_message_cb),
 				window);
 				
 	g_signal_connect (gtranslator_tab_get_po (tab), 
@@ -969,21 +1067,14 @@
 
 void
 gtranslator_recent_add (GtranslatorWindow *window,
-			const gchar *path,
+			GFile *location,
 			gchar *project_id)
 {
 	GtkRecentData *recent_data;
 	gchar *uri;
 	GError *error = NULL;
 
-	uri = g_filename_to_uri (path, NULL, &error);
-	if (error)
-	{	
-		g_warning ("Could not convert uri \"%s\" to a local path: %s",
-			   uri, error->message);
-		g_error_free (error);
-		return;
-	}
+	uri = g_file_get_uri (location);
 
 	recent_data = g_slice_new (GtkRecentData);
 
@@ -1005,7 +1096,6 @@
 	g_free (uri);
 	g_free (recent_data->app_exec);
 	g_slice_free (GtkRecentData, recent_data);
-
 }
 
 void
@@ -1039,45 +1129,21 @@
 gtranslator_recent_chooser_item_activated_cb (GtkRecentChooser *chooser,
 					      GtranslatorWindow *window)
 {
-	gchar *uri, *path;
+	gchar *uri;
 	GError *error = NULL;
 	GtkWidget *dialog;
+	GSList *list = NULL;
+	GFile *location;
 
 	uri = gtk_recent_chooser_get_current_uri (chooser);
-
-	path = g_filename_from_uri (uri, NULL, NULL);
-	if (error)
-	{
-		g_warning ("Could not convert uri \"%s\" to a local path: %s",
-			   uri, error->message);
-		g_error_free (error);
-		return;
-	}
-	
-	/*
-	 * FIXME: We have to detect if the file is already opened
-	 * If it is we should display a warning dialog.
-	 */
-	gtranslator_open (path, window, &error);
-	if(error)
-	{
-		/*
-		 * We have to show the error in a dialog
-		 */
-		dialog = gtk_message_dialog_new(GTK_WINDOW(window),          
-						GTK_DIALOG_DESTROY_WITH_PARENT,
-						GTK_MESSAGE_ERROR,
-						GTK_BUTTONS_CLOSE,
-						error->message);
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (dialog);
-
-		if(error->code == GTR_PO_ERROR_FILENAME)
-			gtranslator_recent_remove (window, path);
-	}
-
+	location = g_file_new_for_uri (uri);
 	g_free (uri);
-	g_free (path);
+	
+	list = g_slist_prepend (list, location);
+	
+	gtranslator_actions_load_locations (window, list);
+	g_slist_foreach (list, (GFunc)g_object_unref, NULL);
+	g_slist_free (list);
 }
 
 static GtkWidget *
@@ -1159,6 +1225,63 @@
 }
 
 static void
+menu_item_select_cb (GtkMenuItem *proxy,
+		     GtranslatorWindow *window)
+{
+	GtkAction *action;
+	char *message;
+
+	action = g_object_get_data (G_OBJECT (proxy),  "gtk-action");
+	g_return_if_fail (action != NULL);
+
+	g_object_get (G_OBJECT (action), "tooltip", &message, NULL);
+	if (message)
+	{
+		gtranslator_statusbar_push_default (GTR_STATUSBAR (window->priv->statusbar),
+						    message);
+		g_free (message);
+	}
+}
+
+static void
+menu_item_deselect_cb (GtkMenuItem *proxy,
+                       GtranslatorWindow *window)
+{
+	gtranslator_statusbar_pop_default (GTR_STATUSBAR (window->priv->statusbar));
+}
+
+static void
+connect_proxy_cb (GtkUIManager *manager,
+                  GtkAction *action,
+                  GtkWidget *proxy,
+                  GtranslatorWindow *window)
+{
+	if (GTK_IS_MENU_ITEM (proxy))
+	{
+		g_signal_connect (proxy, "select",
+				  G_CALLBACK (menu_item_select_cb), window);
+		g_signal_connect (proxy, "deselect",
+				  G_CALLBACK (menu_item_deselect_cb), window);
+	}
+}
+
+static void
+disconnect_proxy_cb (GtkUIManager *manager,
+                     GtkAction *action,
+                     GtkWidget *proxy,
+                     GtranslatorWindow *window)
+{
+	if (GTK_IS_MENU_ITEM (proxy))
+	{
+		g_signal_handlers_disconnect_by_func
+			(proxy, G_CALLBACK (menu_item_select_cb), window);
+		g_signal_handlers_disconnect_by_func
+			(proxy, G_CALLBACK (menu_item_deselect_cb), window);
+	}
+}
+
+
+static void
 side_pane_visibility_changed (GtkWidget		*side_pane,
 			      GtranslatorWindow *window)
 {
@@ -1184,7 +1307,8 @@
 	GError *error = NULL;
 	GtkWidget *dockbar;
 	GtkWidget *hbox_dock;
-	
+	GtkWidget *tm_widget;
+
 	GtranslatorWindowPrivate *priv = window->priv;
 	
 	/*
@@ -1222,12 +1346,22 @@
 
 
 	if (!gtk_ui_manager_add_ui_from_file (priv->ui_manager,
-					      DATADIR"/gtranslator-ui.xml",
+					      PKGDATADIR"/gtranslator-ui.xml",
 					      &error)) {
 		g_warning ("building menus failed: %s", error->message);
 		g_error_free (error);
 	}
 	
+	/* show tooltips in the statusbar */
+	g_signal_connect (priv->ui_manager,
+			  "connect_proxy",
+			  G_CALLBACK (connect_proxy_cb),
+			  window);
+	g_signal_connect (priv->ui_manager,
+			  "disconnect_proxy",
+			  G_CALLBACK (disconnect_proxy_cb),
+			  window);
+	
 	priv->menubar =	 gtk_ui_manager_get_widget (priv->ui_manager,
 							   "/MainMenu");
 	gtk_box_pack_start (GTK_BOX (priv->main_box),
@@ -1250,6 +1384,11 @@
 					    "/MainMenu/FileMenu/FileRecentFilesMenu");
 	gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), priv->recent_menu);
 	
+	/*
+	 * Translation Memory
+	 */
+	priv->tm_menu= gtk_ui_manager_get_widget (priv->ui_manager,
+					       "/MainMenu/EditMenu/EditTranslationMemory");   
 
 	/*
 	 * Toolbar
@@ -1302,6 +1441,8 @@
 			 G_CALLBACK(notebook_switch_page), window);
 	g_signal_connect(priv->notebook, "page-added",
 			 G_CALLBACK(notebook_tab_added), window);
+	g_signal_connect (priv->notebook, "page-removed",
+			  G_CALLBACK (notebook_page_removed), window);
 	g_signal_connect (priv->notebook,
 			  "tab_close_request",
 			  G_CALLBACK (notebook_tab_close_request),
@@ -1318,11 +1459,6 @@
 	 */
 	window->priv->statusbar = gtranslator_statusbar_new ();
 
-	window->priv->generic_message_cid = gtk_statusbar_get_context_id
-		(GTK_STATUSBAR (window->priv->statusbar), "generic_message");
-	window->priv->tip_message_cid = gtk_statusbar_get_context_id
-		(GTK_STATUSBAR (window->priv->statusbar), "tip_message");
-
 	gtk_box_pack_end (GTK_BOX (hbox),
 			  window->priv->statusbar,
 			  TRUE, 
@@ -1516,26 +1652,53 @@
 
 /***************************** Public funcs ***********************************/
 
+/**
+ * gtranslator_window_create_tab:
+ * @window: a #GtranslatorWindow
+ * @po: a #GtranslatorPo
+ * 
+ * Adds a new #GtranslatorTab to the #GtranslatorNotebook and returns the
+ * #GtranslatorTab.
+ * 
+ * Returns: a new #GtranslatorTab object
+ */
 GtranslatorTab *
 gtranslator_window_create_tab(GtranslatorWindow *window,
 			      GtranslatorPo *po)
 {
 	GtranslatorTab *tab;
-	
+
 	tab = gtranslator_tab_new(po);
 	gtk_widget_show(GTK_WIDGET(tab));
-	
+
 	gtranslator_notebook_add_page(GTR_NOTEBOOK(window->priv->notebook),
 				      tab);
+
 	return tab;
 }
 
+/**
+ * gtranslator_window_get_active_tab:
+ * @window: a #GtranslatorWindow
+ * 
+ * Gets the active #GtranslatorTab of the @window.
+ *
+ * Returns: the active #GtranslatorTab of the @window.
+ */
 GtranslatorTab *
 gtranslator_window_get_active_tab(GtranslatorWindow *window)
 {
 	return gtranslator_notebook_get_page(GTR_NOTEBOOK(window->priv->notebook));
 }
 
+/**
+ * gtranslator_window_get_all_tabs:
+ * @window: a #GtranslatorWindow
+ *
+ * Gets a list of all tabs in the @window or NULL if there is no tab opened.
+ *
+ * Returns: a list of all tabs in the @window or NULL if there is no tab opened.
+ */
 GList *
 gtranslator_window_get_all_tabs(GtranslatorWindow *window)
 {
@@ -1555,6 +1718,16 @@
 	return toret;
 }
 
+/**
+ * gtranslator_window_get_header_from_active_tab:
+ * @window: a #GtranslatorWindow
+ *
+ * Gets the #GtranslatorHeader of the #GtranslatorPo of in the active
+ * #GtranslatorTab.
+ *
+ * Returns: the #GtranslatorHeader of the #GtranslatorPo of in the active
+ * #GtranslatorTab
+ */
 GtranslatorHeader *
 gtranslator_window_get_header_from_active_tab(GtranslatorWindow *window)
 {
@@ -1574,18 +1747,42 @@
 	return header;	
 }
 
+/**
+ * gtranslator_window_get_notebook:
+ * @window: a #GtranslatorWindow
+ * 
+ * Gets the main #GtranslatorNotebook of the @window.
+ *
+ * Returns: the #GtranslatorNotebook of the @window
+ */
 GtranslatorNotebook *
 gtranslator_window_get_notebook(GtranslatorWindow *window)
 {
 	return GTR_NOTEBOOK(window->priv->notebook);
 }
 
+/**
+ * gtranslator_window_get_statusbar:
+ * @window: a #GtranslatorWindow
+ *
+ * Gets the statusbar widget of the window.
+ *
+ * Returns: the statusbar widget of the window
+ */
 GtkWidget *
 gtranslator_window_get_statusbar(GtranslatorWindow *window)
 {
 	return window->priv->statusbar;
 }
 
+/**
+ * gtranslator_window_get_ui_manager:
+ * @window: a #GtranslatorWindow
+ *
+ * Gets the #GtkUIManager of the window.
+ *
+ * Returns: the #GtkUIManager of the @window
+ */
 GtkUIManager *
 gtranslator_window_get_ui_manager(GtranslatorWindow *window)
 {
@@ -1596,7 +1793,10 @@
  * gtranslator_window_get_active_view:
  * @window: a #GtranslationWindow
  *
- * Return value: the active translation view in the #GtranslationWindow or
+ * Gets the active translation view in the #GtranslationWindow or
+ * NULL if there is not tab opened.
+ *
+ * Returns: the active translation view in the #GtranslationWindow or
  * NULL if there is not tab opened.
  **/
 GtranslatorView *
@@ -1649,6 +1849,18 @@
 	return views;
 }
 
+/**
+ * gtranslator_window_add_widget:
+ * @window: a #GtranslatorWindow
+ * @widget: the widget to add in the window
+ * @name: the name of the widged
+ * @title: the title
+ * @stock_id: the stock id for the icon
+ * @placement: a #GtranslatorWindowPlacement
+ *
+ * Adds a new widget to the @window in the placement you prefer with and 
+ * specific name, title and icon you want.
+ */
 void
 gtranslator_window_add_widget (GtranslatorWindow *window,
 			       GtkWidget *widget,
@@ -1663,6 +1875,13 @@
 			 placement, FALSE, NULL);
 }
 
+/**
+ * gtranslator_window_remove_widget:
+ * @window: a #GtranslatorWindow
+ * @widget: the widget to remove
+ *
+ * Removes from the @window the @widget if it exists.
+ */
 void
 gtranslator_window_remove_widget (GtranslatorWindow *window,
 				  GtkWidget *widget)
@@ -1671,6 +1890,14 @@
 	remove_widget (window, widget, NULL);
 }
 
+/**
+ * _gtranslator_window_get_layout_manager:
+ * @window: a #GtranslatorWindow
+ * 
+ * Gets the GDL layout manager of the window.
+ * 
+ * Returns: the GDL layout manager of the window.
+ */
 GObject *
 _gtranslator_window_get_layout_manager (GtranslatorWindow *window)
 {
@@ -1679,39 +1906,53 @@
 	return G_OBJECT (window->priv->layout_manager);
 }
 
+/**
+ * gtranslator_window_get_tab_from_uri:
+ * @window: a #GtranslatorWindow
+ * @location: the GFile of the po file of the #GtranslatorTab
+ *
+ * Gets the #GtranslatorTab of the #GtranslatorWindows that matches with the
+ * @location.
+ *
+ * Returns: the #GtranslatorTab which @location matches with its po file.
+ */
 GtkWidget *
-gtranslator_window_get_tab_from_uri (GtranslatorWindow *window,
-				     const gchar *uri)
+gtranslator_window_get_tab_from_location (GtranslatorWindow *window,
+					  GFile *location)
 {
-	GList *tabs;
+	GList *tabs, *l;
 	GtranslatorPo *po;
-	const gchar *po_uri;
+	GFile *po_location;
 	
 	g_return_if_fail (GTR_IS_WINDOW (window));
-	
-	gchar *good_uri = g_filename_from_uri (uri, NULL, NULL);
 
 	tabs = gtranslator_window_get_all_tabs (window);
 	
-	while (tabs != NULL)
+	for (l = tabs; l != NULL; l = g_list_next (l))
 	{
-		po = gtranslator_tab_get_po (GTR_TAB (tabs->data));
+		po = gtranslator_tab_get_po (GTR_TAB (l->data));
 		
-		po_uri = gtranslator_po_get_filename (po);
-	
-		if (g_utf8_collate (good_uri, po_uri) == 0)
+		po_location = gtranslator_po_get_location (po);
+
+		if (g_file_equal (location, po_location) == TRUE)
 		{
-			g_free (good_uri);
-			return tabs->data;
+			g_object_unref (po_location);
+			
+			return l->data;
 		}
-		
-		tabs = tabs->next;
+		g_object_unref (po_location);
 	}
 	
-	g_free (good_uri);
 	return NULL;
 }
 
+/**
+ * gtranslator_window_set_active_tab:
+ * @window: a #GtranslatorWindow
+ * @tab: a #GtranslatorTab
+ *
+ * Sets the active tab for the @window.
+ */
 void
 gtranslator_window_set_active_tab (GtranslatorWindow *window,
 				   GtkWidget *tab)
@@ -1725,6 +1966,14 @@
 				       page);
 }
 
+/**
+ * _gtranslator_window_close_tab:
+ * @window: a #GtranslatorWindow
+ * @tab: a #GtranslatorTab
+ *
+ * Closes the opened @tab of the @window and sets the right sensitivity of the
+ * widgets.
+ */
 void
 _gtranslator_window_close_tab (GtranslatorWindow *window,
 			       GtranslatorTab *tab)
@@ -1736,7 +1985,13 @@
 	i = gtk_notebook_page_num (GTK_NOTEBOOK (window->priv->notebook),
 				   GTK_WIDGET (tab));
 	if (i != -1)
-		gtk_notebook_remove_page (GTK_NOTEBOOK (window->priv->notebook), i);
+		gtranslator_notebook_remove_page (GTR_NOTEBOOK (window->priv->notebook), i);
 	
 	set_sensitive_according_to_window (window);
 }
+
+GtkWidget
+*gtranslator_window_get_tm_menu (GtranslatorWindow *window)
+{
+        return window->priv->tm_menu;
+}

Modified: trunk/src/window.h
==============================================================================
--- trunk/src/window.h	(original)
+++ trunk/src/window.h	Tue Sep 16 07:58:13 2008
@@ -122,8 +122,9 @@
 GObject *        _gtranslator_window_get_layout_manager
 						      (GtranslatorWindow *window);
 
-GtkWidget        *gtranslator_window_get_tab_from_uri (GtranslatorWindow *window,
-						       const gchar *uri);
+GtkWidget        *gtranslator_window_get_tab_from_location
+						      (GtranslatorWindow *window,
+						       GFile *location);
 
 void              gtranslator_window_set_active_tab   (GtranslatorWindow *window,
 						       GtkWidget *tab);
@@ -131,6 +132,8 @@
 void             _gtranslator_window_close_tab        (GtranslatorWindow *window,
 						       GtranslatorTab *tab);
 
+GtkWidget        *gtranslator_window_get_tm_menu      (GtranslatorWindow *window);
+
 G_END_DECLS
 
 #endif /* __WINDOW_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]