gtranslator r3602 - in trunk: . data plugins plugins/subversion src
- From: icq svn gnome org
- To: svn-commits-list gnome org
- Subject: gtranslator r3602 - in trunk: . data plugins plugins/subversion src
- Date: Mon, 22 Sep 2008 09:38:40 +0000 (UTC)
Author: icq
Date: Mon Sep 22 09:38:40 2008
New Revision: 3602
URL: http://svn.gnome.org/viewvc/gtranslator?rev=3602&view=rev
Log:
Merge subversion branch into the master branch to implement the subversion plugin
Added:
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-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
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/data/gtranslator-ui.xml
trunk/plugins/Makefile.am
trunk/src/main.c
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Mon Sep 22 09:38:40 2008
@@ -252,6 +252,222 @@
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,
+ [ --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,
+ [[ --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,
+ [[ --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,
+ [ --disable-plugin-subversion Disable subversion support in Anjuta.],
+ [ 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 ------------------------------------
+
+ APR_CONFIGS="apr-config /usr/local/apr/bin/apr-config/ apr-1-config "
+ AC_ARG_WITH(apr-config,
+ [[ --with-apr-config=FILE Use the given path to apr-config when determining
+ APR configuration; defaults to "apr-config"]],
+ [
+ if test "$withval" != "yes" -a "$withval" != ""; then
+ APR_CONFIGS=$withval
+ fi
+ ])
+ AC_MSG_CHECKING([for APR])
+ APR_CONFIG=""
+ for VALUE in $APR_CONFIGS ; do
+ if $VALUE --cflags > /dev/null 2>&1 ; then
+ APR_CONFIG=$VALUE
+ break
+ fi
+ done
+ test $VALUE && APR_CONFIG=$VALUE
+ if test $APR_CONFIG ; then
+ AC_MSG_RESULT([found])
+ APR_CFLAGS="`$APR_CONFIG --cflags` `$APR_CONFIG --cppflags`"
+ APR_INCLUDE="`$APR_CONFIG --includes`"
+ APR_LIBS="`$APR_CONFIG --link-ld --libs`"
+ else
+ AC_MSG_RESULT([not found])
+ dnl AC_MSG_ERROR([APR is required. Try --with-apr-config.])
+ fi
+
+ dnl -----------------------------------------
+ dnl APR util. Required by subversion (devel)
+ dnl------------------------------------------
+
+ APU_CONFIGS="apu-config /usr/local/apr/bin/apu-config apu-1-config"
+ AC_ARG_WITH(apu-config,
+ [[ --with-apu-config=FILE Use the given path to apu-config when determining
+ APR util configuration; defaults to "apu-config"]],
+ [
+ if test "$withval" != "yes" -a "$withval" != ""; then
+ APU_CONFIGS=$withval
+ fi
+ ])
+ AC_MSG_CHECKING([for APR util])
+ APU_CONFIG=""
+ for VALUE in $APU_CONFIGS ; do
+ if $VALUE --includes > /dev/null 2>&1 ; then
+ APU_CONFIG=$VALUE
+ break
+ fi
+ done
+ if test $APU_CONFIG ; then
+ AC_MSG_RESULT([found])
+ APR_INCLUDE="$APR_INCLUDE `$APU_CONFIG --includes`"
+ APR_LIBS="$APR_LIBS `$APU_CONFIG --link-ld --libs`"
+ else
+ AC_MSG_RESULT([not found])
+ fi
+
+ dnl -----------------------------------------
+ dnl NEON. Required by subversion (devel)
+ dnl------------------------------------------
+
+ dnl Check for neon. It is required by subversion libs, but for
+ dnl for some strange reason it's not in it's dependencies.
+ dnl subversion plugin will be disabled if neon (devel) is not
+ dnl installed, even if subversion (devel) is installed.
+
+ NEON_CONFIGS="neon-config"
+ AC_ARG_WITH(neon-config,
+ [[ --with-neon-config=FILE Use the given path to neon-config when determining
+ Neon configuration; defaults to "neon-config"]],
+ [
+ if test "$withval" != "yes" -a "$withval" != ""; then
+ NEON_CONFIGS=$withval
+ fi
+ ])
+ AC_MSG_CHECKING([for Neon])
+ NEON_CONFIG=""
+ for VALUE in $NEON_CONFIGS ; do
+ if $VALUE --cflags > /dev/null 2>&1 ; then
+ NEON_CONFIG=$VALUE
+ break
+ fi
+ done
+ if test $NEON_CONFIG ; then
+ AC_MSG_RESULT([found])
+ else
+ AC_MSG_RESULT([not found])
+ SVN_INCLUDE=""
+ SVN_LIB=""
+ fi
+fi
+
+dnl ------------------------------------------
+dnl Finally prepare subversion build flags
+dnl ------------------------------------------
+
+if test -n "$SVN_INCLUDE" ; then
+ SVN_INCLUDE="-I$SVN_INCLUDE $APR_INCLUDE"
+ if test x != "x$SVN_LIB" ; then
+ SVN_LIB="-L$SVN_LIB $APR_LIBS -lsvn_client-1 -lsvn_subr-1"
+ else
+ SVN_LIB="$APR_LIBS -lsvn_client-1 -lsvn_subr-1"
+ fi
+ SVN_CFLAGS="$APR_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.
@@ -304,6 +520,7 @@
plugins/insert-tags/Makefile
plugins/open-tran/Makefile
plugins/source-view/Makefile
+plugins/subversion/Makefile
src/Makefile
src/dialogs/Makefile
src/toolbareditor/Makefile
@@ -325,7 +542,18 @@
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.0.2); http://subversion.org"
+fi
+echo "
------------------------------------------------------------------
-- For suggestions, problems & bug reports for gtranslator please
use http://bugzilla.gnome.org/enter_bug.cgi?product=gtranslator
Modified: trunk/data/gtranslator-ui.xml
==============================================================================
--- trunk/data/gtranslator-ui.xml (original)
+++ trunk/data/gtranslator-ui.xml Mon Sep 22 09:38:40 2008
@@ -80,6 +80,10 @@
<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/plugins/Makefile.am
==============================================================================
--- trunk/plugins/Makefile.am (original)
+++ trunk/plugins/Makefile.am Mon Sep 22 09:38:40 2008
@@ -15,3 +15,7 @@
if USE_DICTIONARY
SUBDIRS += dictionary
endif
+
+if BUILD_SVN
+SUBDIRS += subversion
+endif
Added: trunk/plugins/subversion/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/Makefile.am Mon Sep 22 09:38:40 2008
@@ -0,0 +1,96 @@
+# 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
+
+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 = $(plugin_in_files)
+
+CLEANFILES = $(plugin_DATA) $(BUILT_SOURCES)
+DISTCLEANFILES = $(plugin_DATA)
+
Added: trunk/plugins/subversion/async-command.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/async-command.c Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 2008
@@ -0,0 +1,701 @@
+/*
+ * 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;
+
+ /* Setting up */
+ dlg->priv->window = window;
+ tab = gtranslator_window_get_active_tab (window);
+ po = gtranslator_tab_get_po (tab);
+ g_free (dlg->priv->dirname);
+ dlg->priv->dirname = g_path_get_dirname (gtranslator_po_get_filename (po));
+
+ 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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;
+ const gchar *filename;
+ GtranslatorTab *tab;
+ GtranslatorPo *po;
+
+ g_return_if_fail (GTR_IS_WINDOW (window));
+
+ tab = gtranslator_window_get_active_tab (window);
+ po = gtranslator_tab_get_po (tab);
+ filename = gtranslator_po_get_filename (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_strdup (filename);
+ 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 2008
@@ -0,0 +1,39 @@
+/*** BEGIN file-header ***/
+#include "gtranslator-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 Mon Sep 22 09:38:40 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-plugin.c
==============================================================================
--- (empty file)
+++ trunk/plugins/subversion/subversion-plugin.c Mon Sep 22 09:38:40 2008
@@ -0,0 +1,465 @@
+/*
+ * 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;
+
+ tab = gtranslator_window_get_active_tab (window);
+ po = gtranslator_tab_get_po (tab);
+
+ add_command = svn_add_command_new ((gchar *)gtranslator_po_get_filename (po),
+ FALSE,
+ FALSE);
+
+ 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_("_Subversion") }
+};
+
+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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 2008
@@ -0,0 +1,165 @@
+/*
+ * 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];
+ static gint i = 0;
+ i++;
+
+ 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,
+ sizeof (buffer),
+ 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;
+
+ 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);
+
+ //FIXME: Is missing the date
+ changelog_entry = g_strdup_printf ("date %s <%s>\n"
+ "\n\t %s\n\n", name, email,
+ log);
+ g_free (log);
+ //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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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"><b>Realm:</b></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"><b>Username:</b></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"><b>Password:</b></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="yes">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="yes">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"><b>Realm:</b></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="yes">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="yes">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"><b>Log Message:</b></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"><b>Select files to Commit:</b></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="yes">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="yes">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="yes">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="yes">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"><b>Directory to update:</b></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"><b>Information:</b></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="yes">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="yes">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"><b>Diff program:</b></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="yes">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="yes">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"><b>Diff options:</b></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="yes">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="yes">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="yes">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"><b>Directory to checkout:</b></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="yes">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"><b>Subversion URL:</b></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"><b>Information:</b></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="yes">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="yes">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 Mon Sep 22 09:38:40 2008
@@ -0,0 +1,8 @@
+[Gtranslator Plugin]
+Module=subversion
+IAge=2
+_Name=Subversion
+_Description=A Subversion client plugin based on libsvn.
+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 Mon Sep 22 09:38:40 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 (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 Mon Sep 22 09:38:40 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 (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 Mon Sep 22 09:38:40 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 (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 Mon Sep 22 09:38:40 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 (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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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, 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, 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 (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 Mon Sep 22 09:38:40 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, 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, gchar *path);
+
+/* Static methods */
+svn_opt_revision_t *svn_command_get_revision (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 Mon Sep 22 09:38:40 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, 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 Mon Sep 22 09:38:40 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, 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 Mon Sep 22 09:38:40 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 (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 Mon Sep 22 09:38:40 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 (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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 (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 Mon Sep 22 09:38:40 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 (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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 (gchar *path, 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 Mon Sep 22 09:38:40 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 (gchar *path, 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 Mon Sep 22 09:38:40 2008
@@ -0,0 +1,324 @@
+/*
+ * 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 *dirname;
+ gchar *dir;
+ GFile *file;
+
+ tab = gtranslator_window_get_active_tab (dlg->priv->window);
+ po = gtranslator_tab_get_po (tab);
+ dirname = g_path_get_dirname (gtranslator_po_get_filename (po));
+
+ dir = g_build_filename (dirname, "../", NULL);
+ g_free (dirname);
+
+ file = g_file_new_for_path (dir);
+ g_free (dir);
+ 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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 Mon Sep 22 09:38:40 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/src/main.c
==============================================================================
--- trunk/src/main.c (original)
+++ trunk/src/main.c Mon Sep 22 09:38:40 2008
@@ -129,6 +129,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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]