gtranslator r3448 - in branches/GOBJECT_WORK: . data src src/dialogs src/plugin-system



Author: sdeburca
Date: Sun Jan 13 08:12:00 2008
New Revision: 3448
URL: http://svn.gnome.org/viewvc/gtranslator?rev=3448&view=rev

Log:
2008-01-13  SeÃn de BÃrca  <sdeburca svn gnome org>

    * data/Makefile.am:
    * data/gtranslator.pc.in:
    * src/dialogs/Makefile.am:
    * src/dialogs/preferences-dialog.{c,glade}:
    * src/plugin-system/:
    * src/Makefile.am:
    * src/application.{c,h}:
    * src/main.c:
    * src/utils_gui.{c,h}:
    * INSTALL:
    * configure.ac:
        Add plugin functionality, by Ignacio Casal Quinteiro with some help
        from myself.


Added:
   branches/GOBJECT_WORK/data/gtranslator.pc.in
   branches/GOBJECT_WORK/src/plugin-system/
   branches/GOBJECT_WORK/src/plugin-system/Makefile.am
   branches/GOBJECT_WORK/src/plugin-system/module.c
   branches/GOBJECT_WORK/src/plugin-system/module.h
   branches/GOBJECT_WORK/src/plugin-system/plugin-info-priv.h
   branches/GOBJECT_WORK/src/plugin-system/plugin-info.c
   branches/GOBJECT_WORK/src/plugin-system/plugin-info.h
   branches/GOBJECT_WORK/src/plugin-system/plugin-manager.c
   branches/GOBJECT_WORK/src/plugin-system/plugin-manager.h
   branches/GOBJECT_WORK/src/plugin-system/plugin.c
   branches/GOBJECT_WORK/src/plugin-system/plugin.h
   branches/GOBJECT_WORK/src/plugin-system/plugins-engine.c
   branches/GOBJECT_WORK/src/plugin-system/plugins-engine.h
   branches/GOBJECT_WORK/src/plugin-system/update-from-gedit.sh
Modified:
   branches/GOBJECT_WORK/ChangeLog
   branches/GOBJECT_WORK/INSTALL
   branches/GOBJECT_WORK/configure.ac
   branches/GOBJECT_WORK/data/Makefile.am
   branches/GOBJECT_WORK/src/Makefile.am
   branches/GOBJECT_WORK/src/application.c
   branches/GOBJECT_WORK/src/application.h
   branches/GOBJECT_WORK/src/dialogs/Makefile.am
   branches/GOBJECT_WORK/src/dialogs/preferences-dialog.c
   branches/GOBJECT_WORK/src/dialogs/preferences-dialog.glade
   branches/GOBJECT_WORK/src/main.c
   branches/GOBJECT_WORK/src/utils_gui.c
   branches/GOBJECT_WORK/src/utils_gui.h

Modified: branches/GOBJECT_WORK/INSTALL
==============================================================================
--- branches/GOBJECT_WORK/INSTALL	(original)
+++ branches/GOBJECT_WORK/INSTALL	Sun Jan 13 08:12:00 2008
@@ -1,38 +1,54 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
 Basic Installation
 ==================
 
-   These are generic installation instructions.
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
 those values to create a `Makefile' in each directory of the package.
 It may also create one or more `.h' files containing system-dependent
 definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, a file
-`config.cache' that saves the results of its tests to speed up
-reconfiguring, and a file `config.log' containing compiler output
-(useful mainly for debugging `configure').
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
 
    If you need to do unusual things to compile the package, please try
 to figure out how `configure' could check whether to do them, and mail
 diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If at some point `config.cache'
-contains results you don't want to keep, you may remove or edit it.
-
-   The file `configure.in' is used to create `configure' by a program
-called `autoconf'.  You only need `configure.in' if you want to change
-it or regenerate `configure' using a newer version of `autoconf'.
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
 
 The simplest way to compile this package is:
 
   1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.  If you're
-     using `csh' on an old version of System V, you might need to type
-     `sh ./configure' instead to prevent `csh' from trying to execute
-     `configure' itself.
+     `./configure' to configure the package for your system.
 
-     Running `configure' takes awhile.  While running, it prints some
-     messages telling which features it is checking for.
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
 
   2. Type `make' to compile the package.
 
@@ -54,49 +70,49 @@
 Compilers and Options
 =====================
 
-   Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  You can give `configure'
-initial values for variables by setting them in the environment.  Using
-a Bourne-compatible shell, you can do that on the command line like
-this:
-     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
 
-Or on systems that have the `env' program, you can do it like this:
-     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+   *Note Defining Variables::, for more details.
 
 Compiling For Multiple Architectures
 ====================================
 
-   You can compile the package for more than one kind of computer at the
+You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+own directory.  To do this, you can use GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
 the `configure' script.  `configure' automatically checks for the
 source code in the directory that `configure' is in and in `..'.
 
-   If you have to use a `make' that does not supports the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory.  After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
 
 Installation Names
 ==================
 
-   By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
 
    You can specify separate installation prefixes for
 architecture-specific files and architecture-independent files.  If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
 
    In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
+options like `--bindir=DIR' to specify different values for particular
 kinds of files.  Run `configure --help' for a list of the directories
 you can set and what kinds of files go in them.
 
@@ -107,7 +123,7 @@
 Optional Features
 =================
 
-   Some packages pay attention to `--enable-FEATURE' options to
+Some packages pay attention to `--enable-FEATURE' options to
 `configure', where FEATURE indicates an optional part of the package.
 They may also pay attention to `--with-PACKAGE' options, where PACKAGE
 is something like `gnu-as' or `x' (for the X Window System).  The
@@ -122,48 +138,86 @@
 Specifying the System Type
 ==========================
 
-   There may be some features `configure' can not figure out
-automatically, but needs to determine by the type of host the package
-will run on.  Usually `configure' can figure that out, but if it prints
-a message saying it can not guess the host type, give it the
-`--host=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name with three fields:
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
      CPU-COMPANY-SYSTEM
 
-See the file `config.sub' for the possible values of each field.  If
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
 `config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
+need to know the machine type.
 
-   If you are building compiler tools for cross-compiling, you can also
-use the `--target=TYPE' option to select the type of system they will
-produce code for and the `--build=TYPE' option to select the type of
-system on which you are compiling the package.
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
 
 Sharing Defaults
 ================
 
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
 `configure' looks for `PREFIX/share/config.site' if it exists, then
 `PREFIX/etc/config.site' if it exists.  Or, you can set the
 `CONFIG_SITE' environment variable to the location of the site script.
 A warning: not all `configure' scripts look for a site script.
 
-Operation Controls
+Defining Variables
 ==================
 
-   `configure' recognizes the following options to control how it
-operates.
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
 
-`--cache-file=FILE'
-     Use and save the results of the tests in FILE instead of
-     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
-     debugging `configure'.
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
 
 `--help'
+`-h'
      Print a summary of the options to `configure', and exit.
 
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
 `--quiet'
 `--silent'
 `-q'
@@ -175,8 +229,6 @@
      Look for the package's source code in directory DIR.  Usually
      `configure' can determine that directory automatically.
 
-`--version'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
 
-`configure' also accepts some other, not widely useful, options.

Modified: branches/GOBJECT_WORK/configure.ac
==============================================================================
--- branches/GOBJECT_WORK/configure.ac	(original)
+++ branches/GOBJECT_WORK/configure.ac	Sun Jan 13 08:12:00 2008
@@ -10,6 +10,9 @@
 AC_CONFIG_SRCDIR(src/main.c)
 AM_CONFIG_HEADER(config.h)
 
+GTR_API_VERSION=2.0
+AC_SUBST(GTR_API_VERSION)
+
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 AM_MAINTAINER_MODE
 
@@ -183,6 +186,7 @@
 Makefile
 gtranslator.spec
 data/Makefile
+data/gtranslator.pc
 data/desktop/Makefile
 data/desktop/gtranslator.desktop.in
 data/mime/Makefile
@@ -200,6 +204,7 @@
 src/toolbareditor/Makefile
 src/charmap/Makefile
 src/alternatelanguage/Makefile
+src/plugin-system/Makefile
 ])
 
 dnl ------------------------------------------------------------------

Modified: branches/GOBJECT_WORK/data/Makefile.am
==============================================================================
--- branches/GOBJECT_WORK/data/Makefile.am	(original)
+++ branches/GOBJECT_WORK/data/Makefile.am	Sun Jan 13 08:12:00 2008
@@ -5,6 +5,12 @@
 	mime \
 	scripts
 
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gtranslator- GTR_API_VERSION@.pc
+
+gtranslator- GTR_API_VERSION@.pc: gtranslator.pc
+	cp gtranslator.pc gtranslator- GTR_API_VERSION@.pc
+
 uidir = $(pkgdatadir)
 ui_DATA = \
 		gtranslator-ui.xml \
@@ -12,4 +18,8 @@
 		po.lang
 
 EXTRA_DIST = \
-		$(ui_DATA)
+		$(ui_DATA) \
+		gtranslator.pc.in
+
+CLEANFILES =	 			\
+		$(pkgconfig_DATA)

Added: branches/GOBJECT_WORK/data/gtranslator.pc.in
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/data/gtranslator.pc.in	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,20 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: gtranslator
+Description: gtranslator
+Requires: libgnomeui-2.0 libglade-2.0 gtksourceview-2.0
+Version: @VERSION@
+Cflags: -I${includedir}/gtranslator- GTR_API_VERSION@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: gtranslator
+Description: gtranslator
+Requires: libgnomeui-2.0 libglade-2.0 gtksourceview-2.0
+Version: @VERSION@
+Cflags: -I${includedir}/gtranslator- GTR_API_VERSION@

Modified: branches/GOBJECT_WORK/src/Makefile.am
==============================================================================
--- branches/GOBJECT_WORK/src/Makefile.am	(original)
+++ branches/GOBJECT_WORK/src/Makefile.am	Sun Jan 13 08:12:00 2008
@@ -5,7 +5,10 @@
 SUBDIRS = toolbareditor \
 	  dialogs \
 	  charmap \
-	  alternatelanguage
+	  alternatelanguage \
+	  plugin-system
+
+noinst_LTLIBRARIES = libgtranslator.la
 
 INCLUDES = \
 	-I$(top_srcdir)						\
@@ -14,6 +17,7 @@
 	-I$(top_srcdir)/src/toolbareditor			\
 	-I$(top_srcdir)/src/charmap				\
 	-I$(top_srcdir)/src/alternatelanguage			\
+	-I$(top_srcdir)/src/plugin-system			\
 	-DGNOMELOCALEDIR=\""$(prefix)/${DATADIRNAME}/locale"\"	\
 	-DPREFIX=\""$(prefix)"\"                                \
 	-DSYSCONFDIR=\""$(sysconfdir)"\"                        \
@@ -33,6 +37,14 @@
 #	gtranslator-auto-learn \
 #	gtranslator-export-learn-buffer
 
+gtranslator_SOURCES = main.c
+
+gtranslator_LDADD = libgtranslator.la $(GTRANSLATOR_LIBS) $(GTKSPELL_LIBS) $(INTLLIBS)
+
+gtranslator_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
+
+libgtranslator_la_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
+
 BUILT_SOURCES =                         \
         gtranslator-marshal.h  \
         gtranslator-marshal.c	\
@@ -56,13 +68,17 @@
 	view.h \
 	window.h
 
-gtranslator_SOURCES = \
+headerdir = $(prefix)/include/gtranslator- GTR_API_VERSION@/gtranslator
+
+header_DATA = \
+	$(INST_H_FILES)
+
+libgtranslator_la_SOURCES = \
 	$(BUILT_SOURCES) \
 	application.c \
 	compile.h \
 	draw-spaces.c draw-spaces.h \
 	languages.c languages.h \
-	main.c \
 	message-area.c \
 	message-table.c \
 	nautilus-string.c \
@@ -99,18 +115,14 @@
 	comment.c \
 	$(INST_H_FILES) 
 
-gtranslator_LDADD = \
-	$(top_srcdir)/src/dialogs/libdialogs.la \
-	$(top_srcdir)/src/toolbareditor/libtoolbareditor.la \
-	$(top_srcdir)/src/charmap/libcharmap.la \
-	$(top_srcdir)/src/alternatelanguage/libalternatelang.la \
-	$(INTLLIBS) \
+libgtranslator_la_LIBADD = \
 	$(GTRANSLATOR_LIBS) \
-	$(GTKSPELL_LIBS)
+	dialogs/libdialogs.la \
+	toolbareditor/libtoolbareditor.la \
+	charmap/libcharmap.la \
+	alternatelanguage/libalternatelang.la \
+	plugin-system/libpluginsystem.la 
 	
-gtranslator_LDFLAGS = \
-	-Wall
-
 #gtranslator_auto_learn_SOURCES = \
 #	auto-learn.c
 #	

Modified: branches/GOBJECT_WORK/src/application.c
==============================================================================
--- branches/GOBJECT_WORK/src/application.c	(original)
+++ branches/GOBJECT_WORK/src/application.c	Sun Jan 13 08:12:00 2008
@@ -41,6 +41,7 @@
 
 struct _GtranslatorApplicationPrivate
 {
+	GList *windows;
 	GtranslatorWindow *active_window;
 	
 	gchar *toolbars_file;
@@ -163,6 +164,8 @@
 	application->priv = GTR_APPLICATION_GET_PRIVATE (application);
 	priv = application->priv;
 	
+	priv->windows = NULL;
+	
 	gtranslator_init_session(application);
 	
 	priv->toolbars_model = egg_toolbars_model_new ();
@@ -208,7 +211,7 @@
 }
 
 GtranslatorApplication *
-gtranslator_application_get_instance (void)
+gtranslator_application_get_default (void)
 {
 	static GtranslatorApplication *instance = NULL;
 	
@@ -318,3 +321,15 @@
 {
 	return GTR_WINDOW(app->priv->active_window);
 }
+
+const GList *
+gtranslator_application_get_windows (GtranslatorApplication *app)
+{
+	g_return_val_if_fail (GTR_IS_APPLICATION (app), NULL);
+
+	if(!app->priv->windows)
+		app->priv->windows = g_list_prepend(app->priv->windows, app->priv->active_window);
+		
+	return app->priv->windows;
+}
+

Modified: branches/GOBJECT_WORK/src/application.h
==============================================================================
--- branches/GOBJECT_WORK/src/application.h	(original)
+++ branches/GOBJECT_WORK/src/application.h	Sun Jan 13 08:12:00 2008
@@ -38,7 +38,7 @@
 #define GTR_IS_APPLICATION_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_APPLICATION))
 #define GTR_APPLICATION_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_APPLIAPPLICATION, GtranslatorApplicationClass))
 
-#define GTR_APP			        (gtranslator_application_get_instance())
+#define GTR_APP			        (gtranslator_application_get_default())
 
 /* Private structure type */
 typedef struct _GtranslatorApplicationPrivate	GtranslatorApplicationPrivate;
@@ -70,7 +70,7 @@
  * Public methods
  */
 GType		         gtranslator_application_get_type	   (void) G_GNUC_CONST;
-GtranslatorApplication	*gtranslator_application_get_instance	           (void);
+GtranslatorApplication	*gtranslator_application_get_default	           (void);
 
 
 EggToolbarsModel *gtranslator_application_get_toolbars_model  (GtranslatorApplication   *application);
@@ -85,6 +85,9 @@
 
 GtranslatorWindow *gtranslator_application_get_active_window  (GtranslatorApplication * app);
 
+const GList *
+gtranslator_application_get_windows (GtranslatorApplication *app);
+
 G_END_DECLS
 
 #endif /* __APPLICATION_H__ */

Modified: branches/GOBJECT_WORK/src/dialogs/Makefile.am
==============================================================================
--- branches/GOBJECT_WORK/src/dialogs/Makefile.am	(original)
+++ branches/GOBJECT_WORK/src/dialogs/Makefile.am	Sun Jan 13 08:12:00 2008
@@ -3,6 +3,7 @@
         -I$(top_builddir)                                       \
         -I$(top_srcdir)/src                                     \
         -I$(top_builddir)/src                                   \
+	-I$(top_srcdir)/src/plugin-system			\
 	-DDATADIR=\""$(pkgdatadir)"\"				\
 	-DPIXMAPSDIR=\""$(datadir)"/pixmaps/gtranslator\"	\
         $(GTRANSLATOR_CFLAGS)                                   \

Modified: branches/GOBJECT_WORK/src/dialogs/preferences-dialog.c
==============================================================================
--- branches/GOBJECT_WORK/src/dialogs/preferences-dialog.c	(original)
+++ branches/GOBJECT_WORK/src/dialogs/preferences-dialog.c	Sun Jan 13 08:12:00 2008
@@ -23,6 +23,7 @@
 #include "preferences-dialog.h"
 #include "prefs-manager.h"
 #include "utils_gui.h"
+#include "plugin-manager.h"
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -82,6 +83,9 @@
 	/*Inteface*/
 	GtkWidget *left_radiobutton;
 	GtkWidget *right_radiobutton;
+	
+	/*Plugins*/
+	GtkWidget *plugins_box;
 };
 
 /***************Files pages****************/
@@ -499,6 +503,23 @@
 			 dlg);
 }
 
+static void
+setup_plugin_pages(GtranslatorPreferencesDialog *dlg)
+{
+	GtkWidget *page_content;
+
+	page_content = gtranslator_plugin_manager_new ();
+	g_return_if_fail (page_content != NULL);
+
+	gtk_box_pack_start (GTK_BOX (dlg->priv->plugins_box),
+			    page_content,
+			    TRUE,
+			    TRUE,
+			    0);
+
+	gtk_widget_show_all (page_content);
+}
+
 
 static void
 dialog_response_handler (GtkDialog *dlg, 
@@ -583,6 +604,8 @@
 						  
 		"left_radiobutton", &dlg->priv->left_radiobutton,
 		"right_radiobutton", &dlg->priv->right_radiobutton,
+		
+		"plugins_box", &dlg->priv->plugins_box,
 		NULL);
 	
 	if(!ret)
@@ -605,6 +628,7 @@
 	setup_editor_pages(dlg);
 	setup_po_header_pages(dlg);
 	setup_interface_pages(dlg);
+	setup_plugin_pages(dlg);
 }
 
 static void

Modified: branches/GOBJECT_WORK/src/dialogs/preferences-dialog.glade
==============================================================================
--- branches/GOBJECT_WORK/src/dialogs/preferences-dialog.glade	(original)
+++ branches/GOBJECT_WORK/src/dialogs/preferences-dialog.glade	Sun Jan 13 08:12:00 2008
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.0 on Fri Dec 21 21:48:57 2007 -->
+<!--Generated with glade3 3.4.0 on Sat Jan 12 17:11:29 2008 -->
 <glade-interface>
   <widget class="GtkDialog" id="preferences_dialog">
     <property name="border_width">5</property>
@@ -534,29 +534,15 @@
                             <property name="column_spacing">6</property>
                             <property name="row_spacing">6</property>
                             <child>
-                              <widget class="GtkLabel" id="label28">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Name:</property>
-                                <property name="use_underline">True</property>
-                                <property name="mnemonic_widget">name_entry</property>
-                              </widget>
-                              <packing>
-                                <property name="x_options">GTK_FILL</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkLabel" id="label29">
+                              <widget class="GtkEntry" id="email_entry">
                                 <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Email:</property>
-                                <property name="use_underline">True</property>
-                                <property name="mnemonic_widget">email_entry</property>
+                                <property name="can_focus">True</property>
                               </widget>
                               <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
                                 <property name="top_attach">1</property>
                                 <property name="bottom_attach">2</property>
-                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
@@ -570,15 +556,29 @@
                               </packing>
                             </child>
                             <child>
-                              <widget class="GtkEntry" id="email_entry">
+                              <widget class="GtkLabel" id="label29">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">_Email:</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">email_entry</property>
                               </widget>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
                                 <property name="top_attach">1</property>
                                 <property name="bottom_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkLabel" id="label28">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">_Name:</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">name_entry</property>
+                              </widget>
+                              <packing>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                           </widget>
@@ -638,69 +638,99 @@
                                 <property name="column_spacing">6</property>
                                 <property name="row_spacing">6</property>
                                 <child>
-                                  <widget class="GtkSpinButton" id="number_plurals_spinbutton">
+                                  <widget class="GtkComboBoxEntry" id="encoding_combobox">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="adjustment">2 1 10 1 10 10</property>
+                                    <child internal-child="entry">
+                                      <widget class="GtkEntry" id="encoding_comboentry">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                      </widget>
+                                    </child>
                                   </widget>
                                   <packing>
                                     <property name="left_attach">1</property>
                                     <property name="right_attach">2</property>
-                                    <property name="top_attach">5</property>
-                                    <property name="bottom_attach">6</property>
+                                    <property name="top_attach">3</property>
+                                    <property name="bottom_attach">4</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkLabel" id="number_plurals_label">
+                                  <widget class="GtkComboBoxEntry" id="team_email_combobox">
                                     <property name="visible">True</property>
-                                    <property name="xalign">0</property>
-                                    <property name="label" translatable="yes">Number of pl_urals:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">number_plurals_spinbutton</property>
+                                    <child internal-child="entry">
+                                      <widget class="GtkEntry" id="team_email_comboentry">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                      </widget>
+                                    </child>
                                   </widget>
                                   <packing>
-                                    <property name="top_attach">5</property>
-                                    <property name="bottom_attach">6</property>
-                                    <property name="x_options">GTK_FILL</property>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="top_attach">4</property>
+                                    <property name="bottom_attach">5</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkLabel" id="label34">
+                                  <widget class="GtkComboBoxEntry" id="charset_combobox">
                                     <property name="visible">True</property>
-                                    <property name="xalign">0</property>
-                                    <property name="label" translatable="yes">_Language:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">language_combobox</property>
+                                    <child internal-child="entry">
+                                      <widget class="GtkEntry" id="charset_comboentry">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                      </widget>
+                                    </child>
                                   </widget>
                                   <packing>
-                                    <property name="x_options">GTK_FILL</property>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="top_attach">2</property>
+                                    <property name="bottom_attach">3</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkLabel" id="label35">
+                                  <widget class="GtkComboBoxEntry" id="langcode_combobox">
                                     <property name="visible">True</property>
-                                    <property name="xalign">0</property>
-                                    <property name="label" translatable="yes">Language _code:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">langcode_combobox</property>
+                                    <child internal-child="entry">
+                                      <widget class="GtkEntry" id="langcode_comboentry">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                      </widget>
+                                    </child>
                                   </widget>
                                   <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
                                     <property name="top_attach">1</property>
                                     <property name="bottom_attach">2</property>
-                                    <property name="x_options">GTK_FILL</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkLabel" id="label37">
+                                  <widget class="GtkComboBoxEntry" id="language_combobox">
+                                    <property name="visible">True</property>
+                                    <child internal-child="entry">
+                                      <widget class="GtkEntry" id="language_comboentry">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                      </widget>
+                                    </child>
+                                  </widget>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkLabel" id="label39">
                                     <property name="visible">True</property>
                                     <property name="xalign">0</property>
-                                    <property name="label" translatable="yes">Character _set:</property>
+                                    <property name="label" translatable="yes">_Team email:</property>
                                     <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">charset_combobox</property>
+                                    <property name="mnemonic_widget">team_email_combobox</property>
                                   </widget>
                                   <packing>
-                                    <property name="top_attach">2</property>
-                                    <property name="bottom_attach">3</property>
+                                    <property name="top_attach">4</property>
+                                    <property name="bottom_attach">5</property>
                                     <property name="x_options">GTK_FILL</property>
                                   </packing>
                                 </child>
@@ -719,100 +749,70 @@
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkLabel" id="label39">
+                                  <widget class="GtkLabel" id="label37">
                                     <property name="visible">True</property>
                                     <property name="xalign">0</property>
-                                    <property name="label" translatable="yes">_Team email:</property>
+                                    <property name="label" translatable="yes">Character _set:</property>
                                     <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">team_email_combobox</property>
+                                    <property name="mnemonic_widget">charset_combobox</property>
                                   </widget>
                                   <packing>
-                                    <property name="top_attach">4</property>
-                                    <property name="bottom_attach">5</property>
+                                    <property name="top_attach">2</property>
+                                    <property name="bottom_attach">3</property>
                                     <property name="x_options">GTK_FILL</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkComboBoxEntry" id="language_combobox">
-                                    <property name="visible">True</property>
-                                    <child internal-child="entry">
-                                      <widget class="GtkEntry" id="language_comboentry">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                      </widget>
-                                    </child>
-                                  </widget>
-                                  <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkComboBoxEntry" id="langcode_combobox">
+                                  <widget class="GtkLabel" id="label35">
                                     <property name="visible">True</property>
-                                    <child internal-child="entry">
-                                      <widget class="GtkEntry" id="langcode_comboentry">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                      </widget>
-                                    </child>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Language _code:</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">langcode_combobox</property>
                                   </widget>
                                   <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
                                     <property name="top_attach">1</property>
                                     <property name="bottom_attach">2</property>
+                                    <property name="x_options">GTK_FILL</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkComboBoxEntry" id="charset_combobox">
+                                  <widget class="GtkLabel" id="label34">
                                     <property name="visible">True</property>
-                                    <child internal-child="entry">
-                                      <widget class="GtkEntry" id="charset_comboentry">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                      </widget>
-                                    </child>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">_Language:</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">language_combobox</property>
                                   </widget>
                                   <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
-                                    <property name="top_attach">2</property>
-                                    <property name="bottom_attach">3</property>
+                                    <property name="x_options">GTK_FILL</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkComboBoxEntry" id="team_email_combobox">
+                                  <widget class="GtkLabel" id="number_plurals_label">
                                     <property name="visible">True</property>
-                                    <child internal-child="entry">
-                                      <widget class="GtkEntry" id="team_email_comboentry">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                      </widget>
-                                    </child>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Number of pl_urals:</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">number_plurals_spinbutton</property>
                                   </widget>
                                   <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
-                                    <property name="top_attach">4</property>
-                                    <property name="bottom_attach">5</property>
+                                    <property name="top_attach">5</property>
+                                    <property name="bottom_attach">6</property>
+                                    <property name="x_options">GTK_FILL</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <widget class="GtkComboBoxEntry" id="encoding_combobox">
+                                  <widget class="GtkSpinButton" id="number_plurals_spinbutton">
                                     <property name="visible">True</property>
-                                    <child internal-child="entry">
-                                      <widget class="GtkEntry" id="encoding_comboentry">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                      </widget>
-                                    </child>
+                                    <property name="can_focus">True</property>
+                                    <property name="adjustment">2 1 10 1 10 10</property>
                                   </widget>
                                   <packing>
                                     <property name="left_attach">1</property>
                                     <property name="right_attach">2</property>
-                                    <property name="top_attach">3</property>
-                                    <property name="bottom_attach">4</property>
+                                    <property name="top_attach">5</property>
+                                    <property name="bottom_attach">6</property>
                                   </packing>
                                 </child>
                               </widget>
@@ -964,6 +964,29 @@
                 <property name="tab_fill">False</property>
               </packing>
             </child>
+            <child>
+              <widget class="GtkVBox" id="plugins_box">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label12">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Plugins</property>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">4</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
           </widget>
           <packing>
             <property name="position">1</property>

Modified: branches/GOBJECT_WORK/src/main.c
==============================================================================
--- branches/GOBJECT_WORK/src/main.c	(original)
+++ branches/GOBJECT_WORK/src/main.c	Sun Jan 13 08:12:00 2008
@@ -28,6 +28,7 @@
 
 #include "application.h"
 #include "prefs-manager-app.h"
+#include "plugins-engine.h"
 
 #include <locale.h>
 #include <glib.h>
@@ -45,6 +46,7 @@
 {
 	GError *error = NULL;
 	GnomeProgram *program;
+	GtranslatorPluginsEngine *engine;
 	
 	/*
 	 * Initialize gettext.
@@ -90,7 +92,15 @@
 		g_clear_error(&error);
 	}
 	
+	/*
+	 * Init preferences manager
+	 */
 	gtranslator_prefs_manager_app_init();
+	
+	/*
+	 * Init plugin engine
+	 */
+	engine = gtranslator_plugins_engine_get_default ();
 
 	/* 
 	 * Create the main app-window. 

Added: branches/GOBJECT_WORK/src/plugin-system/Makefile.am
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/Makefile.am	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,49 @@
+INCLUDES =                                                      \
+        -I$(top_srcdir)                                         \
+        -I$(top_builddir)                                       \
+        -I$(top_srcdir)/src                                     \
+        -I$(top_builddir)/src                                   \
+	-I$(top_srcdir)/src/toolbareditor			\
+	-I$(headerdir)						\
+	-DPIXMAPSDIR=\""$(datadir)"/pixmaps/gtranslator\"       \
+	-DGTR_PLUGINDIR=\""$(libdir)/gtranslator/plugins"\"	\
+        $(GTRANSLATOR_CFLAGS)                                   \
+        $(WARN_CFLAGS)                                          \
+        $(DISABLE_DEPRECATED_CFLAGS)
+
+noinst_LTLIBRARIES = \
+	libpluginsystem.la
+
+INST_H_FILES = \
+	plugin.h
+
+headerdir = $(prefix)/include/gtranslator- GTR_API_VERSION@/gtranslator
+
+header_DATA = \
+	$(INST_H_FILES)	
+
+libpluginsystem_la_SOURCES = \
+	$(INST_H_FILES) \
+	module.h \
+	module.c \
+	plugin-info-priv.h \
+	plugin-info.c \
+	plugin-info.h \
+	plugin.c \
+	plugin-manager.c \
+	plugin-manager.h \
+	plugins-engine.c \
+	plugins-engine.h
+
+libpluginsystem_la_CFLAGS = \
+	$(GTRANSLATOR_CFLAGS)			\
+	$(WARN_CFLAGS)				\
+	$(DISABLE_DEPRECATED)			\
+	-DCURSOR_DIR=\"$(pkgdatadir)\"		\
+	$(AM_CFLAGS)
+
+libpluginsystem_la_LDFLAGS = \
+	-export-dynamic
+
+EXTRA_DIST = $(pixmaps__DATA)
+

Added: branches/GOBJECT_WORK/src/plugin-system/module.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/module.c	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,228 @@
+/*
+ * module.c
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2005 - Paolo Maggi 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+ 
+/* This is a modified version of ephy-module.c from Epiphany source code.
+ * Here the original copyright assignment:
+ *
+ *  Copyright (C) 2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003, 2004 Christian Persch
+ *
+ */
+
+/*
+ * Modified by the gtranslator Team, 2005. See the AUTHORS file for a 
+ * list of people on the gtranslator Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: module.c 5367 2006-12-17 14:29:49Z pborelli $
+ */
+
+#include "config.h"
+
+#include "module.h"
+//#include "gtranslator-debug.h"
+
+#include <gmodule.h>
+
+typedef struct _GtranslatorModuleClass GtranslatorModuleClass;
+
+struct _GtranslatorModuleClass
+{
+	GTypeModuleClass parent_class;
+};
+
+struct _GtranslatorModule
+{
+	GTypeModule parent_instance;
+
+	GModule *library;
+
+	gchar *path;
+	GType type;
+};
+
+typedef GType (*GtranslatorModuleRegisterFunc) (GTypeModule *);
+
+static void gtranslator_module_init		(GtranslatorModule *action);
+static void gtranslator_module_class_init	(GtranslatorModuleClass *class);
+
+static GObjectClass *parent_class = NULL;
+
+GType
+gtranslator_module_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0))
+	{
+		static const GTypeInfo type_info =
+		{
+			sizeof (GtranslatorModuleClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gtranslator_module_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			sizeof (GtranslatorModule),
+			0, /* n_preallocs */
+			(GInstanceInitFunc) gtranslator_module_init,
+		};
+
+		type = g_type_register_static (G_TYPE_TYPE_MODULE,
+					       "GtranslatorModule",
+					       &type_info, 0);
+	}
+
+	return type;
+}
+
+static gboolean
+gtranslator_module_load (GTypeModule *gmodule)
+{
+	GtranslatorModule *module = GTR_MODULE (gmodule);
+	GtranslatorModuleRegisterFunc register_func;
+
+	g_warning( "Loading %s", module->path);
+
+	module->library = g_module_open (module->path, 0);
+
+	if (module->library == NULL)
+	{
+		g_warning (g_module_error());
+
+		return FALSE;
+	}
+
+	/* extract symbols from the lib */
+	if (!g_module_symbol (module->library, "register_gtranslator_plugin",
+			      (void *) &register_func))
+	{
+		g_warning (g_module_error());
+		g_module_close (module->library);
+
+		return FALSE;
+	}
+
+	/* symbol can still be NULL even though g_module_symbol
+	 * returned TRUE */
+	if (register_func == NULL)
+	{
+		g_warning ("Symbol 'register_gtranslator_plugin' should not be NULL");
+		g_module_close (module->library);
+
+		return FALSE;
+	}
+
+	module->type = register_func (gmodule);
+
+	if (module->type == 0)
+	{
+		g_warning ("Invalid gtranslator plugin contained by module %s", module->path);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+gtranslator_module_unload (GTypeModule *gmodule)
+{
+	GtranslatorModule *module = GTR_MODULE (gmodule);
+
+	g_warning( "Unloading %s", module->path);
+
+	g_module_close (module->library);
+
+	module->library = NULL;
+	module->type = 0;
+}
+
+const gchar *
+gtranslator_module_get_path (GtranslatorModule *module)
+{
+	g_return_val_if_fail (GTR_IS_MODULE (module), NULL);
+
+	return module->path;
+}
+
+GObject *
+gtranslator_module_new_object (GtranslatorModule *module)
+{
+	g_warning( "Creating object of type %s", g_type_name (module->type));
+
+	if (module->type == 0)
+	{
+		return NULL;
+	}
+
+	return g_object_new (module->type, NULL);
+}
+
+static void
+gtranslator_module_init (GtranslatorModule *module)
+{
+	g_warning( "GtranslatorModule %p initialising", module);
+}
+
+static void
+gtranslator_module_finalize (GObject *object)
+{
+	GtranslatorModule *module = GTR_MODULE (object);
+
+	g_warning( "GtranslatorModule %p finalising", module);
+
+	g_free (module->path);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gtranslator_module_class_init (GtranslatorModuleClass *class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (class);
+	GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
+
+	parent_class = (GObjectClass *) g_type_class_peek_parent (class);
+
+	object_class->finalize = gtranslator_module_finalize;
+
+	module_class->load = gtranslator_module_load;
+	module_class->unload = gtranslator_module_unload;
+}
+
+GtranslatorModule *
+gtranslator_module_new (const gchar *path)
+{
+	GtranslatorModule *result;
+
+	if (path == NULL || path[0] == '\0')
+	{
+		return NULL;
+	}
+
+	result = g_object_new (GTR_TYPE_MODULE, NULL);
+
+	g_type_module_set_name (G_TYPE_MODULE (result), path);
+	result->path = g_strdup (path);
+
+	return result;
+}

Added: branches/GOBJECT_WORK/src/plugin-system/module.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/module.h	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,65 @@
+/*
+ * module.h
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2005 - Paolo Maggi 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+ 
+/* This is a modified version of module.h from Epiphany source code.
+ * Here the original copyright assignment:
+ *
+ *  Copyright (C) 2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003, 2004 Christian Persch
+ *
+ */
+
+/*
+ * Modified by the gtranslator Team, 2005. See the AUTHORS file for a 
+ * list of people on the gtranslator Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: module.h 5263 2006-10-08 14:26:02Z pborelli $
+ */
+ 
+#ifndef GTR_MODULE_H
+#define GTR_MODULE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_MODULE		(gtranslator_module_get_type ())
+#define GTR_MODULE(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GTR_TYPE_MODULE, GtranslatorModule))
+#define GTR_MODULE_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GTR_TYPE_MODULE, GtranslatorModuleClass))
+#define GTR_IS_MODULE(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTR_TYPE_MODULE))
+#define GTR_IS_MODULE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((obj), GTR_TYPE_MODULE))
+#define GTR_MODULE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_MODULE, GtranslatorModuleClass))
+
+typedef struct _GtranslatorModule	GtranslatorModule;
+
+GType		 gtranslator_module_get_type		(void) G_GNUC_CONST;
+
+GtranslatorModule	*gtranslator_module_new		(const gchar *path);
+
+const gchar	*gtranslator_module_get_path		(GtranslatorModule *module);
+
+GObject		*gtranslator_module_new_object	(GtranslatorModule *module);
+
+G_END_DECLS
+
+#endif

Added: branches/GOBJECT_WORK/src/plugin-system/plugin-info-priv.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-info-priv.h	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,77 @@
+/*
+ * plugin-info-priv.h
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002-2005 - Paolo Maggi 
+ * Copyright (C) 2007 - Paolo Maggi, Steve FrÃcinaux
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+ 
+/*
+ * Modified by the gtranslator Team, 2002-2007. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id$
+ */
+
+#ifndef __GTR_PLUGIN_INFO_PRIV_H__
+#define __GTR_PLUGIN_INFO_PRIV_H__
+
+#include "plugin-info.h"
+#include "plugin.h"
+
+typedef enum
+{
+	GTR_PLUGIN_LOADER_C,
+	GTR_PLUGIN_LOADER_PY,
+} GtranslatorPluginLoader;
+
+struct _GtranslatorPluginInfo
+{
+	gint               refcount;
+
+	gchar             *file;
+
+	gchar             *module_name;
+	GtranslatorPluginLoader  loader;
+	GTypeModule       *module;
+	gchar            **dependencies;
+
+	gchar             *name;
+	gchar             *desc;
+	gchar             *icon_name;
+	gchar            **authors;
+	gchar             *copyright;
+	gchar             *website;
+
+	GtranslatorPlugin       *plugin;
+
+	gint               active : 1;
+
+	/* A plugin is unavailable if it is not possible to activate it
+	   due to an error loading the plugin module (e.g. for Python plugins
+	   when the interpreter has not been correctly initializated) */
+	gint               available : 1;
+};
+
+GtranslatorPluginInfo		*_gtranslator_plugin_info_new		(const gchar *file);
+void			 _gtranslator_plugin_info_ref		(GtranslatorPluginInfo *info);
+void			 _gtranslator_plugin_info_unref	(GtranslatorPluginInfo *info);
+
+
+#endif /* __GTR_PLUGIN_INFO_PRIV_H__ */

Added: branches/GOBJECT_WORK/src/plugin-system/plugin-info.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-info.c	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,372 @@
+/*
+ * plugin-info.c
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002-2005 - Paolo Maggi 
+ * Copyright (C) 2007 - Paolo Maggi, Steve FrÃcinaux
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+ 
+/*
+ * Modified by the gtranslator Team, 2002-2007. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <glib/gkeyfile.h>
+
+#include "plugin-info.h"
+#include "plugin-info-priv.h"
+//#include "gtranslator-debug.h"
+#include "plugin.h"
+
+void
+_gtranslator_plugin_info_ref (GtranslatorPluginInfo *info)
+{
+	g_atomic_int_inc (&info->refcount);
+}
+
+static GtranslatorPluginInfo *
+gtranslator_plugin_info_copy (GtranslatorPluginInfo *info)
+{
+	_gtranslator_plugin_info_ref (info);
+	return info;
+}
+
+void
+_gtranslator_plugin_info_unref (GtranslatorPluginInfo *info)
+{
+	if (!g_atomic_int_dec_and_test (&info->refcount))
+		return;
+
+	if (info->plugin != NULL)
+	{
+		g_warning( "Unref plugin %s", info->name);
+
+		g_object_unref (info->plugin);
+		
+		/* info->module must not be unref since it is not possible to finalize 
+		 * a type module */
+	}
+
+	g_free (info->file);
+	g_free (info->module_name);
+	g_strfreev (info->dependencies);
+	g_free (info->name);
+	g_free (info->desc);
+	g_free (info->icon_name);
+	g_free (info->website);
+	g_free (info->copyright);
+	g_strfreev (info->authors);
+
+	g_free (info);
+}
+
+/**
+ * gtranslator_plugin_info_get_type:
+ *
+ * Retrieves the #GType object which is associated with the #GtranslatorPluginInfo
+ * class.
+ *
+ * Return value: the GType associated with #GtranslatorPluginInfo.
+ **/
+GType
+gtranslator_plugin_info_get_type (void)
+{
+	static GType the_type = 0;
+
+	if (G_UNLIKELY (!the_type))
+		the_type = g_boxed_type_register_static (
+					"GtranslatorPluginInfo",
+					(GBoxedCopyFunc) gtranslator_plugin_info_copy,
+					(GBoxedFreeFunc) _gtranslator_plugin_info_unref);
+
+	return the_type;
+} 
+
+/**
+ * gtranslator_plugin_info_new:
+ * @filename: the filename where to read the plugin information
+ *
+ * Creates a new #GtranslatorPluginInfo from a file on the disk.
+ *
+ * Return value: a newly created #GtranslatorPluginInfo.
+ */
+GtranslatorPluginInfo *
+_gtranslator_plugin_info_new (const gchar *file)
+{
+	GtranslatorPluginInfo *info;
+	GKeyFile *plugin_file = NULL;
+	gchar *str;
+
+	g_return_val_if_fail (file != NULL, NULL);
+
+	g_warning( "Loading plugin: %s", file);
+
+	info = g_new0 (GtranslatorPluginInfo, 1);
+	info->refcount = 1;
+	info->file = g_strdup (file);
+
+	plugin_file = g_key_file_new ();
+	if (!g_key_file_load_from_file (plugin_file, file, G_KEY_FILE_NONE, NULL))
+	{
+		g_warning ("Bad plugin file: %s", file);
+		goto error;
+	}
+
+	if (!g_key_file_has_key (plugin_file,
+			   	 "Gtranslator Plugin",
+				 "IAge",
+				 NULL))
+	{
+		g_warning(
+				     "IAge key does not exist in file: %s", file);
+		goto error;
+	}
+	
+	/* Check IAge=2 */
+	if (g_key_file_get_integer (plugin_file,
+				    "Gtranslator Plugin",
+				    "IAge",
+				    NULL) != 2)
+	{
+		g_warning(
+				     "Wrong IAge in file: %s", file);
+		goto error;
+	}
+				    
+	/* Get module name */
+	str = g_key_file_get_string (plugin_file,
+				     "Gtranslator Plugin",
+				     "Module",
+				     NULL);
+
+	if ((str != NULL) && (*str != '\0'))
+	{
+		info->module_name = str;
+	}
+	else
+	{
+		g_warning ("Could not find 'Module' in %s", file);
+		goto error;
+	}
+
+	/* Get the dependency list */
+	info->dependencies = g_key_file_get_string_list (plugin_file,
+							 "Gtranslator Plugin",
+							 "Depends",
+							 NULL,
+							 NULL);
+	if (info->dependencies == NULL)
+	{
+		g_warning( "Could not find 'Depends' in %s", file);
+		info->dependencies = g_new0 (gchar *, 1);
+	}
+
+	/* Get the loader for this plugin */
+	str = g_key_file_get_string (plugin_file,
+				     "Gtranslator Plugin",
+				     "Loader",
+				     NULL);
+	if (str && strcmp(str, "python") == 0)
+	{
+		info->loader = GTR_PLUGIN_LOADER_PY;
+#ifndef ENABLE_PYTHON
+		g_warning ("Cannot load Python plugin '%s' since gtranslator was not "
+			   "compiled with Python support.", file);
+		goto error;
+#endif
+	}
+	else
+	{
+		info->loader = GTR_PLUGIN_LOADER_C;
+	}
+	g_free (str);
+
+	/* Get Name */
+	str = g_key_file_get_locale_string (plugin_file,
+					    "Gtranslator Plugin",
+					    "Name",
+					    NULL, NULL);
+	if (str)
+		info->name = str;
+	else
+	{
+		g_warning ("Could not find 'Name' in %s", file);
+		goto error;
+	}
+
+	/* Get Description */
+	str = g_key_file_get_locale_string (plugin_file,
+					    "Gtranslator Plugin",
+					    "Description",
+					    NULL, NULL);
+	if (str)
+		info->desc = str;
+	else
+		g_warning( "Could not find 'Description' in %s", file);
+
+	/* Get Icon */
+	str = g_key_file_get_locale_string (plugin_file,
+					    "Gtranslator Plugin",
+					    "Icon",
+					    NULL, NULL);
+	if (str)
+		info->icon_name = str;
+	else
+		g_warning( "Could not find 'Icon' in %s, using 'plugin'", file);
+	
+
+	/* Get Authors */
+	info->authors = g_key_file_get_string_list (plugin_file,
+						    "Gtranslator Plugin",
+						    "Authors",
+						    NULL,
+						    NULL);
+	if (info->authors == NULL)
+		g_warning( "Could not find 'Authors' in %s", file);
+
+
+	/* Get Copyright */
+	str = g_key_file_get_string (plugin_file,
+				     "Gtranslator Plugin",
+				     "Copyright",
+				     NULL);
+	if (str)
+		info->copyright = str;
+	else
+		g_warning( "Could not find 'Copyright' in %s", file);
+
+	/* Get Website */
+	str = g_key_file_get_string (plugin_file,
+				     "Gtranslator Plugin",
+				     "Website",
+				     NULL);
+	if (str)
+		info->website = str;
+	else
+		g_warning( "Could not find 'Website' in %s", file);
+		
+	g_key_file_free (plugin_file);
+	
+	/* If we know nothing about the availability of the plugin,
+	   set it as available */
+	info->available = TRUE;
+	
+	return info;
+
+error:
+	g_free (info->file);
+	g_free (info->module_name);
+	g_free (info->name);
+	g_free (info);
+	g_key_file_free (plugin_file);
+
+	return NULL;
+}
+
+gboolean
+gtranslator_plugin_info_is_active (GtranslatorPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, FALSE);
+
+	return info->available && info->active;
+}
+
+gboolean
+gtranslator_plugin_info_is_available (GtranslatorPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, FALSE);
+
+	return info->available != FALSE;
+}
+
+gboolean
+gtranslator_plugin_info_is_configurable (GtranslatorPluginInfo *info)
+{
+	g_warning( "Is '%s' configurable?", info->name);
+
+	g_return_val_if_fail (info != NULL, FALSE);
+
+	if (info->plugin == NULL || !info->active || !info->available)
+		return FALSE;
+
+	return gtranslator_plugin_is_configurable (info->plugin);
+}
+
+const gchar *
+gtranslator_plugin_info_get_name (GtranslatorPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+
+	return info->name;
+}
+
+const gchar *
+gtranslator_plugin_info_get_description (GtranslatorPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+
+	return info->desc;
+}
+
+const gchar *
+gtranslator_plugin_info_get_icon_name (GtranslatorPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+
+	/* use the plugin icon as a default if the plugin does not
+	   have its own */
+	if (info->icon_name != NULL && 
+	    gtk_icon_theme_has_icon (gtk_icon_theme_get_default (),
+				     info->icon_name))
+		return info->icon_name;
+	else
+		return "plugin";
+}
+
+const gchar **
+gtranslator_plugin_info_get_authors (GtranslatorPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, (const gchar **)NULL);
+
+	return (const gchar **) info->authors;
+}
+
+const gchar *
+gtranslator_plugin_info_get_website (GtranslatorPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+
+	return info->website;
+}
+
+const gchar *
+gtranslator_plugin_info_get_copyright (GtranslatorPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+
+	return info->copyright;
+}

Added: branches/GOBJECT_WORK/src/plugin-system/plugin-info.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-info.h	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,60 @@
+/*
+ * plugin-info.h
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002-2005 - Paolo Maggi 
+ * Copyright (C) 2007 - Paolo Maggi, Steve FrÃcinaux
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+/*
+ * Modified by the gtranslator Team, 2002-2007. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id$
+ */
+
+#ifndef __GTR_PLUGIN_INFO_H__
+#define __GTR_PLUGIN_INFO_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_PLUGIN_INFO			(gtranslator_plugin_info_get_type ())
+#define GTR_PLUGIN_INFO(obj)			((GtranslatorPluginInfo *) (obj))
+
+typedef struct _GtranslatorPluginInfo			GtranslatorPluginInfo;
+
+GType		 gtranslator_plugin_info_get_type		(void) G_GNUC_CONST;
+
+gboolean 	 gtranslator_plugin_info_is_active		(GtranslatorPluginInfo *info);
+gboolean 	 gtranslator_plugin_info_is_available		(GtranslatorPluginInfo *info);
+gboolean	 gtranslator_plugin_info_is_configurable	(GtranslatorPluginInfo *info);
+
+const gchar	*gtranslator_plugin_info_get_name		(GtranslatorPluginInfo *info);
+const gchar	*gtranslator_plugin_info_get_description	(GtranslatorPluginInfo *info);
+const gchar	*gtranslator_plugin_info_get_icon_name	(GtranslatorPluginInfo *info);
+const gchar    **gtranslator_plugin_info_get_authors		(GtranslatorPluginInfo *info);
+const gchar	*gtranslator_plugin_info_get_website		(GtranslatorPluginInfo *info);
+const gchar	*gtranslator_plugin_info_get_copyright	(GtranslatorPluginInfo *info);
+
+G_END_DECLS
+
+#endif /* __GTR_PLUGIN_INFO_H__ */
+

Added: branches/GOBJECT_WORK/src/plugin-system/plugin-manager.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-manager.c	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,889 @@
+/*
+ * plugin-manager.c
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002 Paolo Maggi and James Willcox
+ * Copyright (C) 2003-2006 Paolo Maggi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+
+/*
+ * Modified by the gtranslator Team, 1998-2006. See the AUTHORS file for a 
+ * list of people on the gtranslator Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: plugin-manager.c 6079 2008-01-12 20:18:55Z sdeburca $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <glade/glade-xml.h>
+
+#include "plugin-manager.h"
+#include "utils_gui.h"
+#include "plugins-engine.h"
+#include "plugin.h"
+//#include "gtranslator-debug.h"
+
+enum
+{
+	ACTIVE_COLUMN,
+	AVAILABLE_COLUMN,
+	INFO_COLUMN,
+	N_COLUMNS
+};
+
+#define PLUGIN_MANAGER_NAME_TITLE _("Plugin")
+#define PLUGIN_MANAGER_ACTIVE_TITLE _("Enabled")
+
+#define GTR_PLUGIN_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GTR_TYPE_PLUGIN_MANAGER, GtranslatorPluginManagerPrivate))
+
+struct _GtranslatorPluginManagerPrivate
+{
+	GtkWidget	*tree;
+
+	GtkWidget	*about_button;
+	GtkWidget	*configure_button;
+
+	GtranslatorPluginsEngine *engine;
+
+	GtkWidget 	*about;
+	
+	GtkWidget	*popup_menu;
+};
+
+G_DEFINE_TYPE(GtranslatorPluginManager, gtranslator_plugin_manager, GTK_TYPE_VBOX)
+
+static GtranslatorPluginInfo *plugin_manager_get_selected_plugin (GtranslatorPluginManager *pm); 
+static void plugin_manager_toggle_active (GtranslatorPluginManager *pm, GtkTreeIter *iter, GtkTreeModel *model);
+static void gtranslator_plugin_manager_finalize (GObject *object);
+
+static void 
+gtranslator_plugin_manager_class_init (GtranslatorPluginManagerClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gtranslator_plugin_manager_finalize;
+
+	g_type_class_add_private (object_class, sizeof (GtranslatorPluginManagerPrivate));
+}
+
+static void
+about_button_cb (GtkWidget          *button,
+		 GtranslatorPluginManager *pm)
+{
+	GtranslatorPluginInfo *info;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	info = plugin_manager_get_selected_plugin (pm);
+
+	g_return_if_fail (info != NULL);
+
+	/* if there is another about dialog already open destroy it */
+	if (pm->priv->about)
+		gtk_widget_destroy (pm->priv->about);
+
+	pm->priv->about = g_object_new (GTK_TYPE_ABOUT_DIALOG,
+		"name", gtranslator_plugin_info_get_name (info),
+		"copyright", gtranslator_plugin_info_get_copyright (info),
+		"authors", gtranslator_plugin_info_get_authors (info),
+		"comments", gtranslator_plugin_info_get_description (info),
+		"website", gtranslator_plugin_info_get_website (info),
+		"logo-icon-name", gtranslator_plugin_info_get_icon_name (info),
+		NULL);
+
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (pm->priv->about),
+					    TRUE);
+
+	g_signal_connect (pm->priv->about,
+			  "response",
+			  G_CALLBACK (gtk_widget_destroy),
+			  NULL);
+	g_signal_connect (pm->priv->about,
+			  "destroy",
+			  G_CALLBACK (gtk_widget_destroyed),
+			  &pm->priv->about);
+
+	gtk_window_set_transient_for (GTK_WINDOW (pm->priv->about),
+				      GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(pm))));
+	gtk_widget_show (pm->priv->about);
+}
+
+static void
+configure_button_cb (GtkWidget          *button,
+		     GtranslatorPluginManager *pm)
+{
+	GtranslatorPluginInfo *info;
+	GtkWindow *toplevel;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	info = plugin_manager_get_selected_plugin (pm);
+
+	g_return_if_fail (info != NULL);
+
+	g_warning( "Configuring: %s\n", 
+			     gtranslator_plugin_info_get_name (info));
+
+	toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(pm)));
+
+	gtranslator_plugins_engine_configure_plugin (pm->priv->engine,
+					       info, toplevel);
+
+	g_warning( "Done");	
+}
+
+static void
+plugin_manager_view_info_cell_cb (GtkTreeViewColumn *tree_column,
+				  GtkCellRenderer   *cell,
+				  GtkTreeModel      *tree_model,
+				  GtkTreeIter       *iter,
+				  gpointer           data)
+{
+	GtranslatorPluginInfo *info;
+	gchar *text;
+	
+	g_return_if_fail (tree_model != NULL);
+	g_return_if_fail (tree_column != NULL);
+
+	gtk_tree_model_get (tree_model, iter, INFO_COLUMN, &info, -1);
+
+	if (info == NULL)
+		return;
+
+	text = g_markup_printf_escaped ("<b>%s</b>\n%s",
+					gtranslator_plugin_info_get_name (info),
+					gtranslator_plugin_info_get_description (info));
+	g_object_set (G_OBJECT (cell),
+		      "markup", text,
+		      "sensitive", gtranslator_plugin_info_is_available (info),
+		      NULL);
+
+	g_free (text);
+}
+
+static void
+plugin_manager_view_icon_cell_cb (GtkTreeViewColumn *tree_column,
+				  GtkCellRenderer   *cell,
+				  GtkTreeModel      *tree_model,
+				  GtkTreeIter       *iter,
+				  gpointer           data)
+{
+	GtranslatorPluginInfo *info;
+	
+	g_return_if_fail (tree_model != NULL);
+	g_return_if_fail (tree_column != NULL);
+
+	gtk_tree_model_get (tree_model, iter, INFO_COLUMN, &info, -1);
+
+	if (info == NULL)
+		return;
+
+	g_object_set (G_OBJECT (cell),
+		      "icon-name", gtranslator_plugin_info_get_icon_name (info),
+		      "sensitive", gtranslator_plugin_info_is_available (info),
+		      NULL);
+}
+
+
+static void
+active_toggled_cb (GtkCellRendererToggle *cell,
+		   gchar                 *path_str,
+		   GtranslatorPluginManager    *pm)
+{
+	GtkTreeIter iter;
+	GtkTreePath *path;
+	GtkTreeModel *model;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	path = gtk_tree_path_new_from_string (path_str);
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
+	g_return_if_fail (model != NULL);
+
+	gtk_tree_model_get_iter (model, &iter, path);
+
+	if (&iter != NULL)
+		plugin_manager_toggle_active (pm, &iter, model);
+
+	gtk_tree_path_free (path);
+}
+
+static void
+cursor_changed_cb (GtkTreeView *view,
+		   gpointer     data)
+{
+	GtranslatorPluginManager *pm = data;
+	GtranslatorPluginInfo *info;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	info = plugin_manager_get_selected_plugin (pm);
+
+	gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->about_button),
+				  info != NULL);
+	gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->configure_button),
+				  (info != NULL) && 
+				   gtranslator_plugin_info_is_configurable (info));
+}
+
+static void
+row_activated_cb (GtkTreeView       *tree_view,
+		  GtkTreePath       *path,
+		  GtkTreeViewColumn *column,
+		  gpointer           data)
+{
+	GtranslatorPluginManager *pm = data;
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
+
+	g_return_if_fail (model != NULL);
+
+	gtk_tree_model_get_iter (model, &iter, path);
+
+	g_return_if_fail (&iter != NULL);
+
+	plugin_manager_toggle_active (pm, &iter, model);
+}
+
+static void
+plugin_manager_populate_lists (GtranslatorPluginManager *pm)
+{
+	const GList *plugins;
+	GtkListStore *model;
+	GtkTreeIter iter;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	plugins = gtranslator_plugins_engine_get_plugin_list (pm->priv->engine);
+
+	model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree)));
+
+	while (plugins)
+	{
+		GtranslatorPluginInfo *info;
+		info = (GtranslatorPluginInfo *)plugins->data;
+
+		gtk_list_store_append (model, &iter);
+		gtk_list_store_set (model, &iter,
+				    ACTIVE_COLUMN, gtranslator_plugin_info_is_active (info),
+				    AVAILABLE_COLUMN, gtranslator_plugin_info_is_available (info),
+				    INFO_COLUMN, info,
+				    -1);
+
+		plugins = plugins->next;
+	}
+
+	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter))
+	{
+		GtkTreeSelection *selection;
+		GtranslatorPluginInfo* info;
+
+		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
+		g_return_if_fail (selection != NULL);
+		
+		gtk_tree_selection_select_iter (selection, &iter);
+
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+				    INFO_COLUMN, &info, -1);
+
+		gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->configure_button),
+					  gtranslator_plugin_info_is_configurable (info));
+	}
+}
+
+static gboolean
+plugin_manager_set_active (GtranslatorPluginManager *pm,
+			   GtkTreeIter        *iter,
+			   GtkTreeModel       *model,
+			   gboolean            active)
+{
+	GtranslatorPluginInfo *info;
+	gboolean res = TRUE;
+	
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	gtk_tree_model_get (model, iter, INFO_COLUMN, &info, -1);
+
+	g_return_val_if_fail (info != NULL, FALSE);
+
+	if (active)
+	{
+		/* activate the plugin */
+		if (!gtranslator_plugins_engine_activate_plugin (pm->priv->engine, info)) {
+			g_warning( "Could not activate %s.\n", 
+					     gtranslator_plugin_info_get_name (info));
+
+			res = FALSE;
+		}
+	}
+	else
+	{
+		/* deactivate the plugin */
+		if (!gtranslator_plugins_engine_deactivate_plugin (pm->priv->engine, info)) {
+			g_warning( "Could not deactivate %s.\n", 
+					     gtranslator_plugin_info_get_name (info));
+
+			res = FALSE;
+		}
+	}
+
+	return res;
+}
+
+static void
+plugin_manager_toggle_active (GtranslatorPluginManager *pm,
+			      GtkTreeIter        *iter,
+			      GtkTreeModel       *model)
+{
+	gboolean active;
+	
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	gtk_tree_model_get (model, iter, ACTIVE_COLUMN, &active, -1);
+
+	active ^= 1;
+
+	plugin_manager_set_active (pm, iter, model, active);
+}
+
+static GtranslatorPluginInfo *
+plugin_manager_get_selected_plugin (GtranslatorPluginManager *pm)
+{
+	GtranslatorPluginInfo *info = NULL;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
+	g_return_val_if_fail (model != NULL, NULL);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
+	g_return_val_if_fail (selection != NULL, NULL);
+
+	if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+	{
+		gtk_tree_model_get (model, &iter, INFO_COLUMN, &info, -1);
+	}
+	
+	return info;
+}
+
+static void
+plugin_manager_set_active_all (GtranslatorPluginManager *pm,
+			       gboolean            active)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
+
+	g_return_if_fail (model != NULL);
+
+	gtk_tree_model_get_iter_first (model, &iter);
+
+	do {
+		plugin_manager_set_active (pm, &iter, model, active);
+	}
+	while (gtk_tree_model_iter_next (model, &iter));
+}
+
+/* Callback used as the interactive search comparison function */
+static gboolean
+name_search_cb (GtkTreeModel *model,
+		gint          column,
+		const gchar  *key,
+		GtkTreeIter  *iter,
+		gpointer      data)
+{
+	GtranslatorPluginInfo *info;
+	gchar *normalized_string;
+	gchar *normalized_key;
+	gchar *case_normalized_string;
+	gchar *case_normalized_key;
+	gint key_len;
+	gboolean retval;
+
+	gtk_tree_model_get (model, iter, INFO_COLUMN, &info, -1);
+	if (!info)
+		return FALSE;
+
+	normalized_string = g_utf8_normalize (gtranslator_plugin_info_get_name (info), -1, G_NORMALIZE_ALL);
+	normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
+	case_normalized_string = g_utf8_casefold (normalized_string, -1);
+	case_normalized_key = g_utf8_casefold (normalized_key, -1);
+
+	key_len = strlen (case_normalized_key);
+
+	/* Oddly enough, this callback must return whether to stop the search
+	 * because we found a match, not whether we actually matched.
+	 */
+	retval = (strncmp (case_normalized_key, case_normalized_string, key_len) != 0);
+
+	g_free (normalized_key);
+	g_free (normalized_string);
+	g_free (case_normalized_key);
+	g_free (case_normalized_string);
+
+	return retval;
+}
+
+static void
+enable_plugin_menu_cb (GtkMenu            *menu,
+		       GtranslatorPluginManager *pm)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
+	g_return_if_fail (model != NULL);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
+	g_return_if_fail (selection != NULL);
+
+	if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+		plugin_manager_toggle_active (pm, &iter, model);
+}
+
+static void
+enable_all_menu_cb (GtkMenu            *menu,
+		    GtranslatorPluginManager *pm)
+{
+	plugin_manager_set_active_all (pm, TRUE);
+}
+
+static void
+disable_all_menu_cb (GtkMenu            *menu,
+		     GtranslatorPluginManager *pm)
+{
+	plugin_manager_set_active_all (pm, FALSE);
+}
+
+static GtkWidget *
+create_tree_popup_menu (GtranslatorPluginManager *pm)
+{
+	GtkWidget *menu;
+	GtkWidget *item;
+	GtkWidget *image;
+	GtranslatorPluginInfo *info;
+
+	info = plugin_manager_get_selected_plugin (pm);
+
+	menu = gtk_menu_new ();
+
+	item = gtk_image_menu_item_new_with_mnemonic (_("_About"));
+	image = gtk_image_new_from_stock (GTK_STOCK_ABOUT,
+					  GTK_ICON_SIZE_MENU);
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+	g_signal_connect (item, "activate",
+			  G_CALLBACK (about_button_cb), pm);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+	item = gtk_image_menu_item_new_with_mnemonic (_("C_onfigure"));
+	image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES,
+					  GTK_ICON_SIZE_MENU);
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+	g_signal_connect (item, "activate",
+			  G_CALLBACK (configure_button_cb), pm);
+	gtk_widget_set_sensitive (item, gtranslator_plugin_info_is_configurable (info));
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+	item = gtk_check_menu_item_new_with_mnemonic (_("A_ctivate"));
+	gtk_widget_set_sensitive (item, gtranslator_plugin_info_is_available (info));
+	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
+					gtranslator_plugin_info_is_active (info));
+	g_signal_connect (item, "toggled",
+			  G_CALLBACK (enable_plugin_menu_cb), pm);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+	item = gtk_separator_menu_item_new ();
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+	item = gtk_menu_item_new_with_mnemonic (_("Ac_tivate All"));
+	g_signal_connect (item, "activate",
+			  G_CALLBACK (enable_all_menu_cb), pm);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+	item = gtk_menu_item_new_with_mnemonic (_("_Deactivate All"));
+	g_signal_connect (item, "activate",
+			  G_CALLBACK (disable_all_menu_cb), pm);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+	
+	gtk_widget_show_all (menu);
+	
+	return menu;
+}
+
+static void
+tree_popup_menu_detach (GtranslatorPluginManager *pm,
+			GtkMenu            *menu)
+{
+	pm->priv->popup_menu = NULL;
+}
+
+static void
+show_tree_popup_menu (GtkTreeView        *tree,
+		      GtranslatorPluginManager *pm,
+		      GdkEventButton     *event)
+{
+	if (pm->priv->popup_menu)
+		gtk_widget_destroy (pm->priv->popup_menu);
+
+	pm->priv->popup_menu = create_tree_popup_menu (pm);
+	
+	gtk_menu_attach_to_widget (GTK_MENU (pm->priv->popup_menu),
+				   GTK_WIDGET (pm),
+				   (GtkMenuDetachFunc) tree_popup_menu_detach);
+
+	if (event != NULL)
+	{
+		gtk_menu_popup (GTK_MENU (pm->priv->popup_menu), NULL, NULL,
+				NULL, NULL,
+				event->button, event->time);
+	}
+	else
+	{
+		gtk_menu_popup (GTK_MENU (pm->priv->popup_menu), NULL, NULL,
+				gtranslator_utils_menu_position_under_tree_view, tree,
+				0, gtk_get_current_event_time ());
+
+		gtk_menu_shell_select_first (GTK_MENU_SHELL (pm->priv->popup_menu),
+					     FALSE);
+	}
+}
+
+static gboolean
+button_press_event_cb (GtkWidget          *tree,
+		       GdkEventButton     *event,
+		       GtranslatorPluginManager *pm)
+{
+	/* We want the treeview selection to be updated before showing the menu.
+	 * This code is evil, thanks to Federico Mena Quintero's black magic.
+	 * See: http://mail.gnome.org/archives/gtk-devel-list/2006-February/msg00168.html
+	 * FIXME: Let's remove it asap.
+	 */
+
+	static gboolean in_press = FALSE;
+	gboolean handled;
+
+	if (in_press)
+		return FALSE; /* we re-entered */
+
+	if (GDK_BUTTON_PRESS != event->type || 3 != event->button)
+		return FALSE; /* let the normal handler run */
+
+	in_press = TRUE;
+	handled = gtk_widget_event (tree, (GdkEvent *) event);
+	in_press = FALSE;
+
+	if (!handled)
+		return FALSE;
+		
+	/* The selection is fully updated by now */
+	show_tree_popup_menu (GTK_TREE_VIEW (tree), pm, event);
+	return TRUE;
+}
+
+static gboolean
+popup_menu_cb (GtkTreeView        *tree,
+	       GtranslatorPluginManager *pm)
+{
+	show_tree_popup_menu (tree, pm, NULL);
+	return TRUE;
+}
+
+static gint 
+model_name_sort_func (GtkTreeModel *model,
+		      GtkTreeIter  *iter1,
+		      GtkTreeIter  *iter2,
+		      gpointer      user_data)
+{
+	GtranslatorPluginInfo *info1, *info2;
+	
+	gtk_tree_model_get (model, iter1, INFO_COLUMN, &info1, -1);
+	gtk_tree_model_get (model, iter2, INFO_COLUMN, &info2, -1);
+
+	return g_utf8_collate (gtranslator_plugin_info_get_name (info1),
+			       gtranslator_plugin_info_get_name (info2));
+}
+
+static void
+plugin_manager_construct_tree (GtranslatorPluginManager *pm)
+{
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *cell;
+	GtkListStore *model;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	model = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, GTR_TYPE_PLUGIN_INFO);
+
+	gtk_tree_view_set_model (GTK_TREE_VIEW (pm->priv->tree),
+				 GTK_TREE_MODEL (model));
+	g_object_unref (model);
+
+	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (pm->priv->tree), TRUE);
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (pm->priv->tree), FALSE);
+
+	/* first column */
+	cell = gtk_cell_renderer_toggle_new ();
+	g_object_set (cell, "xpad", 6, NULL);
+	g_signal_connect (cell,
+			  "toggled",
+			  G_CALLBACK (active_toggled_cb),
+			  pm);
+	column = gtk_tree_view_column_new_with_attributes (PLUGIN_MANAGER_ACTIVE_TITLE,
+							   cell,
+							   "active",
+							   ACTIVE_COLUMN,
+							   "activatable",
+							   AVAILABLE_COLUMN,
+							   "sensitive",
+							   AVAILABLE_COLUMN,
+							   NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column);
+
+	/* second column */
+	column = gtk_tree_view_column_new ();
+	gtk_tree_view_column_set_title (column, PLUGIN_MANAGER_NAME_TITLE);
+	gtk_tree_view_column_set_resizable (column, TRUE);
+
+	cell = gtk_cell_renderer_pixbuf_new ();
+	gtk_tree_view_column_pack_start (column, cell, FALSE);
+	g_object_set (cell, "stock-size", GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
+	gtk_tree_view_column_set_cell_data_func (column, cell,
+						 plugin_manager_view_icon_cell_cb,
+						 pm, NULL);
+	
+	cell = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, cell, TRUE);
+	g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+	gtk_tree_view_column_set_cell_data_func (column, cell,
+						 plugin_manager_view_info_cell_cb,
+						 pm, NULL);
+	
+	
+	gtk_tree_view_column_set_spacing (column, 6);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column);
+
+	/* Sort on the plugin names */
+	gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model),
+	                                         model_name_sort_func,
+        	                                 NULL,
+                	                         NULL);
+	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
+					      GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+					      GTK_SORT_ASCENDING);
+
+	/* Enable search for our non-string column */
+	gtk_tree_view_set_search_column (GTK_TREE_VIEW (pm->priv->tree),
+					 INFO_COLUMN);
+	gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (pm->priv->tree),
+					     name_search_cb,
+					     NULL,
+					     NULL);
+
+	g_signal_connect (pm->priv->tree,
+			  "cursor_changed",
+			  G_CALLBACK (cursor_changed_cb),
+			  pm);
+	g_signal_connect (pm->priv->tree,
+			  "row_activated",
+			  G_CALLBACK (row_activated_cb),
+			  pm);
+
+	g_signal_connect (pm->priv->tree,
+			  "button-press-event",
+			  G_CALLBACK (button_press_event_cb),
+			  pm);
+	g_signal_connect (pm->priv->tree,
+			  "popup-menu",
+			  G_CALLBACK (popup_menu_cb),
+			  pm);
+	gtk_widget_show (pm->priv->tree);
+}
+
+static void
+plugin_toggled_cb (GtranslatorPluginsEngine *engine,
+		   GtranslatorPluginInfo    *info,
+		   GtranslatorPluginManager *pm)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean info_found = FALSE;
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
+
+	if (gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		/* There is an item selected: it's probably the one we want! */
+		GtranslatorPluginInfo *tinfo;
+		gtk_tree_model_get (model, &iter, INFO_COLUMN, &tinfo, -1);
+		info_found = info == tinfo;
+	}
+
+	if (!info_found)
+	{
+		gtk_tree_model_get_iter_first (model, &iter);
+
+		do
+		{
+			GtranslatorPluginInfo *tinfo;
+			gtk_tree_model_get (model, &iter, INFO_COLUMN, &tinfo, -1);
+			info_found = info == tinfo;
+		}
+		while (!info_found && gtk_tree_model_iter_next (model, &iter));
+	}
+
+	if (!info_found)
+	{
+		g_warning ("GtranslatorPluginManager: plugin '%s' not found in the tree model",
+			   gtranslator_plugin_info_get_name (info));
+		return;
+	}
+
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter, ACTIVE_COLUMN, gtranslator_plugin_info_is_active (info), -1);
+}
+
+static void 
+gtranslator_plugin_manager_init (GtranslatorPluginManager *pm)
+{
+	GtkWidget *label;
+	GtkWidget *alignment;
+	GtkWidget *viewport;
+	GtkWidget *hbuttonbox;
+	gchar *markup;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	pm->priv = GTR_PLUGIN_MANAGER_GET_PRIVATE (pm);
+
+	gtk_box_set_spacing (GTK_BOX (pm), 6);
+
+	label = gtk_label_new (NULL);
+	markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
+					  _("Active plugins"));
+	gtk_label_set_markup (GTK_LABEL (label), markup);
+	g_free (markup);
+	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	
+	gtk_box_pack_start (GTK_BOX (pm), label, FALSE, TRUE, 0);
+	
+	alignment = gtk_alignment_new (0., 0., 1., 1.);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+	gtk_box_pack_start (GTK_BOX (pm), alignment, TRUE, TRUE, 0);
+	
+	viewport = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (viewport),
+					GTK_POLICY_AUTOMATIC,
+					GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (viewport), 
+					     GTK_SHADOW_IN);
+
+	gtk_container_add (GTK_CONTAINER (alignment), viewport);
+
+	pm->priv->tree = gtk_tree_view_new ();
+	gtk_container_add (GTK_CONTAINER (viewport), pm->priv->tree);
+
+	hbuttonbox = gtk_hbutton_box_new ();
+	gtk_box_pack_start (GTK_BOX (pm), hbuttonbox, FALSE, FALSE, 0);
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
+	gtk_box_set_spacing (GTK_BOX (hbuttonbox), 8);
+
+	pm->priv->about_button = gtranslator_gtk_button_new_with_stock_icon (_("_About Plugin"),
+								       GTK_STOCK_ABOUT);
+	gtk_container_add (GTK_CONTAINER (hbuttonbox), pm->priv->about_button);
+
+	pm->priv->configure_button = gtranslator_gtk_button_new_with_stock_icon (_("C_onfigure Plugin"),
+									   GTK_STOCK_PREFERENCES);
+	gtk_container_add (GTK_CONTAINER (hbuttonbox), pm->priv->configure_button);
+
+	/* setup a window of a sane size. */
+	gtk_widget_set_size_request (GTK_WIDGET (viewport), 270, 100);
+
+	g_signal_connect (pm->priv->about_button,
+			  "clicked",
+			  G_CALLBACK (about_button_cb),
+			  pm);
+	g_signal_connect (pm->priv->configure_button,
+			  "clicked",
+			  G_CALLBACK (configure_button_cb),
+			  pm);
+
+	plugin_manager_construct_tree (pm);
+
+	/* get the plugin engine and populate the treeview */
+	pm->priv->engine = gtranslator_plugins_engine_get_default ();
+
+	g_signal_connect_after (pm->priv->engine,
+				"activate-plugin",
+				G_CALLBACK (plugin_toggled_cb),
+				pm);
+	g_signal_connect_after (pm->priv->engine,
+				"deactivate-plugin",
+				G_CALLBACK (plugin_toggled_cb),
+				pm);
+
+	if (gtranslator_plugins_engine_get_plugin_list (pm->priv->engine) != NULL)
+	{
+		plugin_manager_populate_lists (pm);
+	}
+	else
+	{
+		gtk_widget_set_sensitive (pm->priv->about_button, FALSE);
+		gtk_widget_set_sensitive (pm->priv->configure_button, FALSE);		
+	}
+}
+
+static void
+gtranslator_plugin_manager_finalize (GObject *object)
+{
+	GtranslatorPluginManager *pm = GTR_PLUGIN_MANAGER (object);
+
+	g_signal_handlers_disconnect_by_func (pm->priv->engine,
+					      plugin_toggled_cb,
+					      pm);
+
+	if (pm->priv->popup_menu)
+		gtk_widget_destroy (pm->priv->popup_menu);
+
+	G_OBJECT_CLASS (gtranslator_plugin_manager_parent_class)->finalize (object);
+
+}
+
+GtkWidget *gtranslator_plugin_manager_new (void)
+{
+	return g_object_new (GTR_TYPE_PLUGIN_MANAGER,0);
+}

Added: branches/GOBJECT_WORK/src/plugin-system/plugin-manager.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-manager.h	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,83 @@
+/*
+ * plugin-manager.h
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002-2005 Paolo Maggi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a 
+ * list of people on the gtranslator Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: plugin-manager.h 5666 2007-06-29 19:52:25Z sfre $
+ */
+
+#ifndef __GTR_PLUGIN_MANAGER_H__
+#define __GTR_PLUGIN_MANAGER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_PLUGIN_MANAGER              (gtranslator_plugin_manager_get_type())
+#define GTR_PLUGIN_MANAGER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GTR_TYPE_PLUGIN_MANAGER, GtranslatorPluginManager))
+#define GTR_PLUGIN_MANAGER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GTR_TYPE_PLUGIN_MANAGER, GtranslatorPluginManagerClass))
+#define GTR_IS_PLUGIN_MANAGER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTR_TYPE_PLUGIN_MANAGER))
+#define GTR_IS_PLUGIN_MANAGER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_PLUGIN_MANAGER))
+#define GTR_PLUGIN_MANAGER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_PLUGIN_MANAGER, GtranslatorPluginManagerClass))
+
+/* Private structure type */
+typedef struct _GtranslatorPluginManagerPrivate GtranslatorPluginManagerPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorPluginManager GtranslatorPluginManager;
+
+struct _GtranslatorPluginManager 
+{
+	GtkVBox vbox;
+
+	/*< private > */
+	GtranslatorPluginManagerPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorPluginManagerClass GtranslatorPluginManagerClass;
+
+struct _GtranslatorPluginManagerClass 
+{
+	GtkVBoxClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		 gtranslator_plugin_manager_get_type		(void) G_GNUC_CONST;
+
+GtkWidget	*gtranslator_plugin_manager_new		(void);
+   
+G_END_DECLS
+
+#endif  /* __GTR_PLUGIN_MANAGER_H__  */

Added: branches/GOBJECT_WORK/src/plugin-system/plugin.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin.c	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,119 @@
+/*
+ * plugin.h
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002-2005 Paolo Maggi 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+ 
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a 
+ * list of people on the gtranslator Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: plugin.c 4509 2006-01-06 16:45:20Z pborelli $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "plugin.h"
+
+G_DEFINE_TYPE(GtranslatorPlugin, gtranslator_plugin, G_TYPE_OBJECT)
+
+static void
+dummy (GtranslatorPlugin *plugin, GtranslatorWindow *window)
+{
+	/* Empty */
+}
+
+static GtkWidget *
+create_configure_dialog	(GtranslatorPlugin *plugin)
+{
+	return NULL;
+}
+
+static gboolean
+is_configurable (GtranslatorPlugin *plugin)
+{
+	return (GTR_PLUGIN_GET_CLASS (plugin)->create_configure_dialog !=
+		create_configure_dialog);
+}
+
+static void 
+gtranslator_plugin_class_init (GtranslatorPluginClass *klass)
+{
+	klass->activate = dummy;
+	klass->deactivate = dummy;
+	klass->update_ui = dummy;
+	
+	klass->create_configure_dialog = create_configure_dialog;
+	klass->is_configurable = is_configurable;
+}
+
+static void
+gtranslator_plugin_init (GtranslatorPlugin *plugin)
+{
+	/* Empty */
+}
+
+void
+gtranslator_plugin_activate (GtranslatorPlugin *plugin,
+		       GtranslatorWindow *window)
+{
+	g_return_if_fail (GTR_IS_PLUGIN (plugin));
+	g_return_if_fail (GTR_IS_WINDOW (window));
+	
+	GTR_PLUGIN_GET_CLASS (plugin)->activate (plugin, window);
+}
+
+void
+gtranslator_plugin_deactivate	(GtranslatorPlugin *plugin,
+			 GtranslatorWindow *window)
+{
+	g_return_if_fail (GTR_IS_PLUGIN (plugin));
+	g_return_if_fail (GTR_IS_WINDOW (window));
+
+	GTR_PLUGIN_GET_CLASS (plugin)->deactivate (plugin, window);
+}
+				 
+void
+gtranslator_plugin_update_ui	(GtranslatorPlugin *plugin,
+			 GtranslatorWindow *window)
+{
+	g_return_if_fail (GTR_IS_PLUGIN (plugin));
+	g_return_if_fail (GTR_IS_WINDOW (window));
+
+	GTR_PLUGIN_GET_CLASS (plugin)->update_ui (plugin, window);
+}
+
+gboolean
+gtranslator_plugin_is_configurable (GtranslatorPlugin *plugin)
+{
+	g_return_val_if_fail (GTR_IS_PLUGIN (plugin), FALSE);
+
+	return GTR_PLUGIN_GET_CLASS (plugin)->is_configurable (plugin);
+}
+
+GtkWidget *
+gtranslator_plugin_create_configure_dialog (GtranslatorPlugin *plugin)
+{
+	g_return_val_if_fail (GTR_IS_PLUGIN (plugin), NULL);
+	
+	return GTR_PLUGIN_GET_CLASS (plugin)->create_configure_dialog (plugin);
+}

Added: branches/GOBJECT_WORK/src/plugin-system/plugin.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin.h	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,245 @@
+/*
+ * plugin.h
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002-2005 - Paolo Maggi 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+ 
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a 
+ * list of people on the gtranslator Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: plugin.h 5666 2007-06-29 19:52:25Z sfre $
+ */
+
+#ifndef __GTR_PLUGIN_H__
+#define __GTR_PLUGIN_H__
+
+#include <glib-object.h>
+
+#include "window.h"
+//#include <gtranslator/gtranslator-debug.h>
+
+/* TODO: add a .h file that includes all the .h files normally needed to
+ * develop a plugin */ 
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_PLUGIN              (gtranslator_plugin_get_type())
+#define GTR_PLUGIN(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GTR_TYPE_PLUGIN, GtranslatorPlugin))
+#define GTR_PLUGIN_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GTR_TYPE_PLUGIN, GtranslatorPluginClass))
+#define GTR_IS_PLUGIN(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTR_TYPE_PLUGIN))
+#define GTR_IS_PLUGIN_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_PLUGIN))
+#define GTR_PLUGIN_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_PLUGIN, GtranslatorPluginClass))
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorPlugin GtranslatorPlugin;
+
+struct _GtranslatorPlugin 
+{
+	GObject parent;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorPluginClass GtranslatorPluginClass;
+
+struct _GtranslatorPluginClass 
+{
+	GObjectClass parent_class;
+
+	/* Virtual public methods */
+	
+	void 		(*activate)		(GtranslatorPlugin *plugin,
+						 GtranslatorWindow *window);
+	void 		(*deactivate)		(GtranslatorPlugin *plugin,
+						 GtranslatorWindow *window);
+
+	void 		(*update_ui)		(GtranslatorPlugin *plugin,
+						 GtranslatorWindow *window);
+
+	GtkWidget 	*(*create_configure_dialog)
+						(GtranslatorPlugin *plugin);
+
+	/* Plugins should not override this, it's handled automatically by
+	   the GtranslatorPluginClass */
+	gboolean 	(*is_configurable)
+						(GtranslatorPlugin *plugin);
+
+	/* Padding for future expansion */
+	void		(*_gtranslator_reserved1)	(void);
+	void		(*_gtranslator_reserved2)	(void);
+	void		(*_gtranslator_reserved3)	(void);
+	void		(*_gtranslator_reserved4)	(void);
+};
+
+/*
+ * Public methods
+ */
+GType 		 gtranslator_plugin_get_type 		(void) G_GNUC_CONST;
+
+void 		 gtranslator_plugin_activate		(GtranslatorPlugin *plugin,
+						 GtranslatorWindow *window);
+void 		 gtranslator_plugin_deactivate	(GtranslatorPlugin *plugin,
+						 GtranslatorWindow *window);
+				 
+void 		 gtranslator_plugin_update_ui		(GtranslatorPlugin *plugin,
+						 GtranslatorWindow *window);
+
+gboolean	 gtranslator_plugin_is_configurable	(GtranslatorPlugin *plugin);
+GtkWidget	*gtranslator_plugin_create_configure_dialog		
+						(GtranslatorPlugin *plugin);
+
+/*
+ * Utility macro used to register plugins
+ *
+ * use: GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE)
+ */
+#define GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE)	\
+										\
+static GType plugin_name##_type = 0;						\
+										\
+GType										\
+plugin_name##_get_type (void)							\
+{										\
+	return plugin_name##_type;						\
+}										\
+										\
+static void     plugin_name##_init              (PluginName        *self);	\
+static void     plugin_name##_class_init        (PluginName##Class *klass);	\
+static gpointer plugin_name##_parent_class = NULL;				\
+static void     plugin_name##_class_intern_init (gpointer klass)		\
+{										\
+	plugin_name##_parent_class = g_type_class_peek_parent (klass);		\
+	plugin_name##_class_init ((PluginName##Class *) klass);			\
+}										\
+										\
+G_MODULE_EXPORT GType								\
+register_gtranslator_plugin (GTypeModule *module)					\
+{										\
+	static const GTypeInfo our_info =					\
+	{									\
+		sizeof (PluginName##Class),					\
+		NULL, /* base_init */						\
+		NULL, /* base_finalize */					\
+		(GClassInitFunc) plugin_name##_class_intern_init,		\
+		NULL,								\
+		NULL, /* class_data */						\
+		sizeof (PluginName),						\
+		0, /* n_preallocs */						\
+		(GInstanceInitFunc) plugin_name##_init				\
+	};									\
+										\
+	g_warning( "Registering " #PluginName);	\
+										\
+	/* Initialise the i18n stuff */						\
+	bindtextdomain (GETTEXT_PACKAGE, GTR_LOCALEDIR);			\
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");			\
+										\
+	plugin_name##_type = g_type_module_register_type (module,		\
+					    GTR_TYPE_PLUGIN,			\
+					    #PluginName,			\
+					    &our_info,				\
+					    0);					\
+										\
+	CODE									\
+										\
+	return plugin_name##_type;						\
+}
+
+/*
+ * Utility macro used to register plugins
+ *
+ * use: GTR_PLUGIN_REGISTER_TYPE(PluginName, plugin_name)
+ */
+#define GTR_PLUGIN_REGISTER_TYPE(PluginName, plugin_name)			\
+	GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, ;)
+
+/*
+ * Utility macro used to register gobject types in plugins with additional code
+ *
+ * use: GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE)
+ */
+#define GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE)	\
+										\
+static GType g_define_type_id = 0;						\
+										\
+GType										\
+object_name##_get_type (void)							\
+{										\
+	return g_define_type_id;						\
+}										\
+										\
+static void     object_name##_init              (ObjectName        *self);	\
+static void     object_name##_class_init        (ObjectName##Class *klass);	\
+static gpointer object_name##_parent_class = NULL;				\
+static void     object_name##_class_intern_init (gpointer klass)		\
+{										\
+	object_name##_parent_class = g_type_class_peek_parent (klass);		\
+	object_name##_class_init ((ObjectName##Class *) klass);			\
+}										\
+										\
+GType										\
+object_name##_register_type (GTypeModule *module)					\
+{										\
+	static const GTypeInfo our_info =					\
+	{									\
+		sizeof (ObjectName##Class),					\
+		NULL, /* base_init */						\
+		NULL, /* base_finalize */					\
+		(GClassInitFunc) object_name##_class_intern_init,		\
+		NULL,								\
+		NULL, /* class_data */						\
+		sizeof (ObjectName),						\
+		0, /* n_preallocs */						\
+		(GInstanceInitFunc) object_name##_init				\
+	};									\
+										\
+	g_warning( "Registering " #ObjectName);	\
+										\
+	g_define_type_id = g_type_module_register_type (module,			\
+					   	        PARENT_TYPE,		\
+					                #ObjectName,		\
+					                &our_info,		\
+					                0);			\
+										\
+	CODE									\
+										\
+	return g_define_type_id;						\
+}
+
+/*
+ * Utility macro used to register gobject types in plugins
+ *
+ * use: GTR_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE)
+ */
+#define GTR_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE)		\
+	GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, ;)
+
+G_END_DECLS
+
+#endif  /* __GTR_PLUGIN_H__ */
+
+

Added: branches/GOBJECT_WORK/src/plugin-system/plugins-engine.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugins-engine.c	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,693 @@
+/*
+ * plugins-engine.c
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002-2005 Paolo Maggi 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a 
+ * list of people on the gtranslator Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: plugins-engine.c 6052 2008-01-04 17:32:52Z sfre $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <gconf/gconf-client.h>
+
+#include "plugins-engine.h"
+#include "plugin-info-priv.h"
+#include "plugin.h"
+//#include "gtranslator-debug.h"
+#include "application.h"
+
+#include "module.h"
+#ifdef ENABLE_PYTHON
+#include "gtranslator-python-module.h"
+#endif
+
+#define USER_GTR_PLUGINS_LOCATION ".gtranslator/plugins/"
+
+#define GTR_PLUGINS_ENGINE_BASE_KEY "/apps/gtranslator/plugins"
+#define GTR_PLUGINS_ENGINE_KEY GTR_PLUGINS_ENGINE_BASE_KEY "/active-plugins"
+
+#define PLUGIN_EXT	".plugin"
+
+/* Signals */
+enum
+{
+	ACTIVATE_PLUGIN,
+	DEACTIVATE_PLUGIN,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE(GtranslatorPluginsEngine, gtranslator_plugins_engine, G_TYPE_OBJECT)
+
+struct _GtranslatorPluginsEnginePrivate
+{
+	GList *plugin_list;
+	GConfClient *gconf_client;
+};
+
+GtranslatorPluginsEngine *default_engine = NULL;
+
+static void	gtranslator_plugins_engine_active_plugins_changed (GConfClient *client,
+							     guint cnxn_id, 
+							     GConfEntry *entry, 
+							     gpointer user_data);
+static void	gtranslator_plugins_engine_activate_plugin_real (GtranslatorPluginsEngine *engine,
+							   GtranslatorPluginInfo    *info);
+static void	gtranslator_plugins_engine_deactivate_plugin_real (GtranslatorPluginsEngine *engine,
+							     GtranslatorPluginInfo    *info);
+
+static gint
+compare_plugin_info (GtranslatorPluginInfo *info1,
+		     GtranslatorPluginInfo *info2)
+{
+	return strcmp (info1->module_name, info2->module_name);
+}
+
+static void
+gtranslator_plugins_engine_load_dir (GtranslatorPluginsEngine *engine,
+			       const gchar        *dir,
+			       GSList             *active_plugins)
+{
+	GError *error = NULL;
+	GDir *d;
+	const gchar *dirent;
+
+	g_return_if_fail (engine->priv->gconf_client != NULL);
+	g_return_if_fail (dir != NULL);
+
+	g_warning( "DIR: %s", dir);
+
+	d = g_dir_open (dir, 0, &error);
+	if (!d)
+	{
+		g_warning (error->message);
+		g_error_free (error);
+		return;
+	}
+
+	while ((dirent = g_dir_read_name (d)))
+	{
+		if (g_str_has_suffix (dirent, PLUGIN_EXT))
+		{
+			gchar *plugin_file;
+			GtranslatorPluginInfo *info;
+			
+			plugin_file = g_build_filename (dir, dirent, NULL);
+			info = _gtranslator_plugin_info_new (plugin_file);
+			g_free (plugin_file);
+
+			if (info == NULL)
+				continue;
+
+			/* If a plugin with this name has already been loaded
+			 * drop this one (user plugins override system plugins) */
+			if (g_list_find_custom (engine->priv->plugin_list,
+						info,
+						(GCompareFunc)compare_plugin_info) != NULL)
+			{
+				g_warning ("Two or more plugins named '%s'. "
+					   "Only the first will be considered.\n",
+					   info->module_name);
+
+				_gtranslator_plugin_info_unref (info);
+
+				continue;
+			}
+
+			/* Actually, the plugin will be activated when reactivate_all
+			 * will be called for the first time. */
+			info->active = g_slist_find_custom (active_plugins,
+							    info->module_name,
+							    (GCompareFunc)strcmp) != NULL;
+
+			engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info);
+
+			g_warning( "Plugin %s loaded", info->name);
+		}
+	}
+
+	g_dir_close (d);
+}
+
+static void
+gtranslator_plugins_engine_load_all (GtranslatorPluginsEngine *engine)
+{
+	GSList *active_plugins;
+	const gchar *home;
+	const gchar *pdirs_env;
+	gchar **pdirs;
+	int i;
+
+	active_plugins = gconf_client_get_list (engine->priv->gconf_client,
+						GTR_PLUGINS_ENGINE_KEY,
+						GCONF_VALUE_STRING,
+						NULL);
+
+	/* load user's plugins */
+	home = g_get_home_dir ();
+	if (home == NULL)
+	{
+		g_warning ("Could not get HOME directory\n");
+	}
+	else
+	{
+		gchar *pdir;
+
+		pdir = g_build_filename (home,
+					 USER_GTR_PLUGINS_LOCATION,
+					 NULL);
+
+		if (g_file_test (pdir, G_FILE_TEST_IS_DIR))
+			gtranslator_plugins_engine_load_dir (engine, pdir, active_plugins);
+		
+		g_free (pdir);
+	}
+
+	pdirs_env = g_getenv ("GTR_PLUGINS_PATH");
+	/* What if no env var is set? We use the default location(s)! */
+	if (pdirs_env == NULL)
+		pdirs_env = GTR_PLUGINDIR;
+
+	g_warning( "GTR_PLUGINS_PATH=%s", pdirs_env);
+	pdirs = g_strsplit (pdirs_env, G_SEARCHPATH_SEPARATOR_S, 0);
+
+	for (i = 0; pdirs[i] != NULL; i++)
+		gtranslator_plugins_engine_load_dir (engine, pdirs[i], active_plugins);
+
+	g_strfreev (pdirs);
+}
+
+static void
+gtranslator_plugins_engine_init (GtranslatorPluginsEngine *engine)
+{
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	if (!g_module_supported ())
+	{
+		g_warning ("gtranslator is not able to initialize the plugins engine.");
+		return;
+	}
+
+	engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine,
+						    GTR_TYPE_PLUGINS_ENGINE,
+						    GtranslatorPluginsEnginePrivate);
+
+	engine->priv->gconf_client = gconf_client_get_default ();
+	g_return_if_fail (engine->priv->gconf_client != NULL);
+
+	gconf_client_add_dir (engine->priv->gconf_client,
+			      GTR_PLUGINS_ENGINE_BASE_KEY,
+			      GCONF_CLIENT_PRELOAD_ONELEVEL,
+			      NULL);
+
+	gconf_client_notify_add (engine->priv->gconf_client,
+				 GTR_PLUGINS_ENGINE_KEY,
+				 gtranslator_plugins_engine_active_plugins_changed,
+				 engine, NULL, NULL);
+
+	gtranslator_plugins_engine_load_all (engine);
+}
+
+void
+gtranslator_plugins_engine_garbage_collect (GtranslatorPluginsEngine *engine)
+{
+#ifdef ENABLE_PYTHON
+	gtranslator_python_garbage_collect ();
+#endif
+}
+
+static void
+gtranslator_plugins_engine_finalize (GObject *object)
+{
+	GtranslatorPluginsEngine *engine = GTR_PLUGINS_ENGINE (object);
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+#ifdef ENABLE_PYTHON
+	/* Note: that this may cause finalization of objects (typically
+	 * the GtranslatorWindow) by running the garbage collector. Since some
+	 * of the plugin may have installed callbacks upon object
+	 * finalization (typically they need to free the WindowData)
+	 * it must run before we get rid of the plugins.
+	 */
+	gtranslator_python_shutdown ();
+#endif
+
+	g_return_if_fail (engine->priv->gconf_client != NULL);
+
+	g_list_foreach (engine->priv->plugin_list,
+			(GFunc) _gtranslator_plugin_info_unref, NULL);
+	g_list_free (engine->priv->plugin_list);
+
+	g_object_unref (engine->priv->gconf_client);
+}
+
+static void
+gtranslator_plugins_engine_class_init (GtranslatorPluginsEngineClass *klass)
+{
+	GType the_type = G_TYPE_FROM_CLASS (klass);
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gtranslator_plugins_engine_finalize;
+	klass->activate_plugin = gtranslator_plugins_engine_activate_plugin_real;
+	klass->deactivate_plugin = gtranslator_plugins_engine_deactivate_plugin_real;
+
+	signals[ACTIVATE_PLUGIN] =
+		g_signal_new ("activate-plugin",
+			      the_type,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GtranslatorPluginsEngineClass, activate_plugin),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__BOXED,
+			      G_TYPE_NONE,
+			      1,
+			      GTR_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+	signals[DEACTIVATE_PLUGIN] =
+		g_signal_new ("deactivate-plugin",
+			      the_type,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GtranslatorPluginsEngineClass, deactivate_plugin),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__BOXED,
+			      G_TYPE_NONE,
+			      1,
+			      GTR_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+	g_type_class_add_private (klass, sizeof (GtranslatorPluginsEnginePrivate));
+}
+
+GtranslatorPluginsEngine *
+gtranslator_plugins_engine_get_default (void)
+{
+	if (default_engine != NULL)
+		return default_engine;
+
+	default_engine = GTR_PLUGINS_ENGINE (g_object_new (GTR_TYPE_PLUGINS_ENGINE, NULL));
+	g_object_add_weak_pointer (G_OBJECT (default_engine),
+				   (gpointer) &default_engine);
+	return default_engine;
+}
+
+const GList *
+gtranslator_plugins_engine_get_plugin_list (GtranslatorPluginsEngine *engine)
+{
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	return engine->priv->plugin_list;
+}
+
+static gboolean
+load_plugin_module (GtranslatorPluginInfo *info)
+{
+	gchar *path;
+	gchar *dirname;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	g_return_val_if_fail (info != NULL, FALSE);
+	g_return_val_if_fail (info->file != NULL, FALSE);
+	g_return_val_if_fail (info->module_name != NULL, FALSE);
+	g_return_val_if_fail (info->plugin == NULL, FALSE);
+	g_return_val_if_fail (info->available, FALSE);
+	
+	switch (info->loader)
+	{
+		case GTR_PLUGIN_LOADER_C:
+			dirname = g_path_get_dirname (info->file);	
+			g_return_val_if_fail (dirname != NULL, FALSE);
+
+			path = g_module_build_path (dirname, info->module_name);
+			g_free (dirname);
+			g_return_val_if_fail (path != NULL, FALSE);
+	
+			info->module = G_TYPE_MODULE (gtranslator_module_new (path));
+			g_free (path);
+			
+			break;
+
+#ifdef ENABLE_PYTHON
+		case GTR_PLUGIN_LOADER_PY:
+		{
+			gchar *dir;
+			
+			if (!gtranslator_python_init ())
+			{
+				/* Mark plugin as unavailable and fails */
+				info->available = FALSE;
+				
+				g_warning ("Cannot load Python plugin '%s' since gtranslator "
+				           "was not able to initialize the Python interpreter.",
+				           info->name);
+
+				return FALSE;
+			}
+
+			dir = g_path_get_dirname (info->file);
+			
+			g_return_val_if_fail ((info->module_name != NULL) &&
+			                      (info->module_name[0] != '\0'),
+			                      FALSE);
+
+			info->module = G_TYPE_MODULE (
+					gtranslator_python_module_new (dir, info->module_name));
+					
+			g_free (dir);
+			break;
+		}
+#endif
+		default:
+			g_return_val_if_reached (FALSE);
+	}
+
+	if (!g_type_module_use (info->module))
+	{
+		switch (info->loader)
+		{
+			case GTR_PLUGIN_LOADER_C:
+				g_warning ("Cannot load plugin '%s' since file '%s' cannot be read.",
+					   info->name,			           
+					   gtranslator_module_get_path (GTR_MODULE (info->module)));
+				break;
+
+			case GTR_PLUGIN_LOADER_PY:
+				g_warning ("Cannot load Python plugin '%s' since file '%s' cannot be read.",
+					   info->name,			           
+					   info->module_name);
+				break;
+
+			default:
+				g_return_val_if_reached (FALSE);				
+		}
+			   
+		g_object_unref (G_OBJECT (info->module));
+		info->module = NULL;
+
+		/* Mark plugin as unavailable and fails */
+		info->available = FALSE;
+		
+		return FALSE;
+	}
+	
+	switch (info->loader)
+	{
+		case GTR_PLUGIN_LOADER_C:
+			info->plugin = 
+				GTR_PLUGIN (gtranslator_module_new_object (GTR_MODULE (info->module)));
+			break;
+
+#ifdef ENABLE_PYTHON
+		case GTR_PLUGIN_LOADER_PY:
+			info->plugin = 
+				GTR_PLUGIN (gtranslator_python_module_new_object (GTR_PYTHON_MODULE (info->module)));
+			break;
+#endif
+
+		default:
+			g_return_val_if_reached (FALSE);
+	}
+	
+	g_type_module_unuse (info->module);
+
+	g_warning( "End");
+	
+	return TRUE;
+}
+
+static void
+save_active_plugin_list (GtranslatorPluginsEngine *engine)
+{
+	GSList *active_plugins = NULL;
+	GList *l;
+	gboolean res;
+
+	for (l = engine->priv->plugin_list; l != NULL; l = l->next)
+	{
+		const GtranslatorPluginInfo *info = (const GtranslatorPluginInfo *) l->data;
+		if (info->active)
+		{
+			active_plugins = g_slist_prepend (active_plugins,
+							  info->module_name);
+		}
+	}
+
+	res = gconf_client_set_list (engine->priv->gconf_client,
+				     GTR_PLUGINS_ENGINE_KEY,
+				     GCONF_VALUE_STRING,
+				     active_plugins,
+				     NULL);
+
+	if (!res)
+		g_warning ("Error saving the list of active plugins.");
+
+	g_slist_free (active_plugins);
+}
+
+static void
+gtranslator_plugins_engine_activate_plugin_real (GtranslatorPluginsEngine *engine,
+					   GtranslatorPluginInfo *info)
+{
+	gboolean res = TRUE;
+
+	if (info->active || !info->available)
+		return;
+
+	if (info->plugin == NULL)
+		res = load_plugin_module (info);
+
+	if (res)
+	{
+		const GList *wins = gtranslator_application_get_windows (gtranslator_application_get_default ());
+		for (; wins != NULL; wins = wins->next)
+			gtranslator_plugin_activate (info->plugin, GTR_WINDOW (wins->data));
+
+		info->active = TRUE;
+	}
+	else
+		g_warning ("Error activating plugin '%s'", info->name);
+}
+
+gboolean
+gtranslator_plugins_engine_activate_plugin (GtranslatorPluginsEngine *engine,
+				      GtranslatorPluginInfo    *info)
+{
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	g_return_val_if_fail (info != NULL, FALSE);
+
+	if (!info->available)
+		return FALSE;
+		
+	if (info->active)
+		return TRUE;
+
+	g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
+	if (info->active)
+		save_active_plugin_list (engine);
+
+	return info->active;
+}
+
+static void
+gtranslator_plugins_engine_deactivate_plugin_real (GtranslatorPluginsEngine *engine,
+					     GtranslatorPluginInfo *info)
+{
+	const GList *wins;
+
+	if (!info->active || !info->available)
+		return;
+
+	wins = gtranslator_application_get_windows (gtranslator_application_get_default ());
+	for (; wins != NULL; wins = wins->next)
+		gtranslator_plugin_deactivate (info->plugin, GTR_WINDOW (wins->data));
+
+	info->active = FALSE;
+}
+
+gboolean
+gtranslator_plugins_engine_deactivate_plugin (GtranslatorPluginsEngine *engine,
+					GtranslatorPluginInfo    *info)
+{
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	g_return_val_if_fail (info != NULL, FALSE);
+
+	if (!info->active || !info->available)
+		return TRUE;
+
+	g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
+	if (!info->active)
+		save_active_plugin_list (engine);
+
+	return !info->active;
+}
+
+static void
+reactivate_all (GtranslatorPluginsEngine *engine,
+		GtranslatorWindow        *window)
+{
+	GList *pl;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
+	{
+		gboolean res = TRUE;
+		
+		GtranslatorPluginInfo *info = (GtranslatorPluginInfo*)pl->data;
+
+		/* If plugin is not available, don't try to activate/load it */
+		if (info->available && info->active)
+		{		
+			if (info->plugin == NULL)
+				res = load_plugin_module (info);
+				
+			if (res)
+				gtranslator_plugin_activate (info->plugin,
+						       window);			
+		}
+	}
+	
+	g_warning( "End");
+}
+
+void
+gtranslator_plugins_engine_update_plugins_ui (GtranslatorPluginsEngine *engine,
+					GtranslatorWindow        *window,
+					gboolean            new_window)
+{
+	GList *pl;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	g_return_if_fail (GTR_IS_WINDOW (window));
+
+	if (new_window)
+		reactivate_all (engine, window);
+
+	/* updated ui of all the plugins that implement update_ui */
+	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
+	{
+		GtranslatorPluginInfo *info = (GtranslatorPluginInfo*)pl->data;
+
+		if (!info->available || !info->active)
+			continue;
+			
+	       	g_warning( "Updating UI of %s", info->name);
+		
+		gtranslator_plugin_update_ui (info->plugin, window);
+	}
+}
+
+void 	 
+gtranslator_plugins_engine_configure_plugin (GtranslatorPluginsEngine *engine,
+				       GtranslatorPluginInfo    *info,
+				       GtkWindow          *parent)
+{
+	GtkWidget *conf_dlg;
+	
+	GtkWindowGroup *wg;
+	
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	g_return_if_fail (info != NULL);
+
+	conf_dlg = gtranslator_plugin_create_configure_dialog (info->plugin);
+	g_return_if_fail (conf_dlg != NULL);
+	gtk_window_set_transient_for (GTK_WINDOW (conf_dlg),
+				      parent);
+
+	wg = parent->group;		      
+	if (wg == NULL)
+	{
+		wg = gtk_window_group_new ();
+		gtk_window_group_add_window (wg, parent);
+	}
+			
+	gtk_window_group_add_window (wg,
+				     GTK_WINDOW (conf_dlg));
+		
+	gtk_window_set_modal (GTK_WINDOW (conf_dlg), TRUE);		     
+	gtk_widget_show (conf_dlg);
+}
+
+static void 
+gtranslator_plugins_engine_active_plugins_changed (GConfClient *client,
+					     guint cnxn_id,
+					     GConfEntry *entry,
+					     gpointer user_data)
+{
+	GtranslatorPluginsEngine *engine;
+	GList *pl;
+	gboolean to_activate;
+	GSList *active_plugins;
+
+	//gtranslator_debug (DEBUG_PLUGINS);
+
+	g_return_if_fail (entry->key != NULL);
+	g_return_if_fail (entry->value != NULL);
+
+	engine = GTR_PLUGINS_ENGINE (user_data);
+	
+	if (!((entry->value->type == GCONF_VALUE_LIST) && 
+	      (gconf_value_get_list_type (entry->value) == GCONF_VALUE_STRING)))
+	{
+		g_warning ("The gconf key '%s' may be corrupted.", GTR_PLUGINS_ENGINE_KEY);
+		return;
+	}
+	
+	active_plugins = gconf_client_get_list (engine->priv->gconf_client,
+						GTR_PLUGINS_ENGINE_KEY,
+						GCONF_VALUE_STRING,
+						NULL);
+
+	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
+	{
+		GtranslatorPluginInfo *info = (GtranslatorPluginInfo*)pl->data;
+
+		if (!info->available)
+			continue;
+
+		to_activate = (g_slist_find_custom (active_plugins,
+						    info->module_name,
+						    (GCompareFunc)strcmp) != NULL);
+
+		if (!info->active && to_activate)
+			g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
+		else if (info->active && !to_activate)
+			g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
+	}
+
+	g_slist_foreach (active_plugins, (GFunc) g_free, NULL);
+	g_slist_free (active_plugins);
+}
+
+

Added: branches/GOBJECT_WORK/src/plugin-system/plugins-engine.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugins-engine.h	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,97 @@
+/*
+ * plugins-engine.h
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2002-2005 - Paolo Maggi 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+ 
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a 
+ * list of people on the gtranslator Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: plugins-engine.h 6045 2007-12-28 20:45:22Z sfre $
+ */
+
+#ifndef __GTR_PLUGINS_ENGINE_H__
+#define __GTR_PLUGINS_ENGINE_H__
+
+#include <glib.h>
+#include "window.h"
+#include "plugin-info.h"
+#include "plugin.h"
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_PLUGINS_ENGINE              (gtranslator_plugins_engine_get_type ())
+#define GTR_PLUGINS_ENGINE(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GTR_TYPE_PLUGINS_ENGINE, GtranslatorPluginsEngine))
+#define GTR_PLUGINS_ENGINE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GTR_TYPE_PLUGINS_ENGINE, GtranslatorPluginsEngineClass))
+#define GTR_IS_PLUGINS_ENGINE(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTR_TYPE_PLUGINS_ENGINE))
+#define GTR_IS_PLUGINS_ENGINE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_PLUGINS_ENGINE))
+#define GTR_PLUGINS_ENGINE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_PLUGINS_ENGINE, GtranslatorPluginsEngineClass))
+
+typedef struct _GtranslatorPluginsEngine		GtranslatorPluginsEngine;
+typedef struct _GtranslatorPluginsEnginePrivate	GtranslatorPluginsEnginePrivate;
+
+struct _GtranslatorPluginsEngine
+{
+	GObject parent;
+	GtranslatorPluginsEnginePrivate *priv;
+};
+
+typedef struct _GtranslatorPluginsEngineClass		GtranslatorPluginsEngineClass;
+
+struct _GtranslatorPluginsEngineClass
+{
+	GObjectClass parent_class;
+
+	void	 (* activate_plugin)		(GtranslatorPluginsEngine *engine,
+						 GtranslatorPluginInfo    *info);
+
+	void	 (* deactivate_plugin)		(GtranslatorPluginsEngine *engine,
+						 GtranslatorPluginInfo    *info);
+};
+
+GType			 gtranslator_plugins_engine_get_type		(void) G_GNUC_CONST;
+
+GtranslatorPluginsEngine	*gtranslator_plugins_engine_get_default	(void);
+
+void		 gtranslator_plugins_engine_garbage_collect	(GtranslatorPluginsEngine *engine);
+
+const GList	*gtranslator_plugins_engine_get_plugin_list 	(GtranslatorPluginsEngine *engine);
+
+gboolean 	 gtranslator_plugins_engine_activate_plugin 	(GtranslatorPluginsEngine *engine,
+							 GtranslatorPluginInfo    *info);
+gboolean 	 gtranslator_plugins_engine_deactivate_plugin	(GtranslatorPluginsEngine *engine,
+							 GtranslatorPluginInfo    *info);
+
+void	 	 gtranslator_plugins_engine_configure_plugin	(GtranslatorPluginsEngine *engine,
+							 GtranslatorPluginInfo    *info,
+							 GtkWindow          *parent);
+
+/* 
+ * new_window == TRUE if this function is called because a new top window
+ * has been created
+ */
+void		 gtranslator_plugins_engine_update_plugins_ui (GtranslatorPluginsEngine *engine,
+							 GtranslatorWindow        *window, 
+							 gboolean            new_window);
+
+G_END_DECLS
+
+#endif  /* __GTR_PLUGINS_ENGINE_H__ */

Added: branches/GOBJECT_WORK/src/plugin-system/update-from-gedit.sh
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/update-from-gedit.sh	Sun Jan 13 08:12:00 2008
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+SVN_URI=http://svn.gnome.org/svn/gedit/trunk/gedit
+FILES="gedit-module.h \
+       gedit-module.c \
+       gedit-plugin-info-priv.h \
+       gedit-plugin-info.c \
+       gedit-plugin-info.h \
+       gedit-plugin.h \
+       gedit-plugin.c \
+       gedit-plugin-manager.c \
+       gedit-plugin-manager.h \
+       gedit-plugins-engine.c \
+       gedit-plugins-engine.h"
+
+echo "Obtaining latest version of the sources"
+for FILE in $FILES
+do
+  svn export $SVN_URI/$FILE
+done
+
+sed_it () {
+	sed \
+	-e 's/gedit-module/module/g' \
+	-e 's/gedit-plugin-info/plugin-info/g' \
+	-e 's/gedit-plugin/plugin/g' \
+	-e 's/gedit-panel.h/panel.h/g' \
+	-e 's/gedit-window.h/window.h/g' \
+	-e 's/gedit-utils.h/utils_gui.h/g' \
+	-e 's/#include <gedit\/gedit-debug.h>/\/\/#include <gedit\/gedit-debug.h>/g' \
+	-e 's/#include "gedit-debug.h"/\/\/#include "gedit-debug.h"/g' \
+	-e 's/#include "gedit-app.h"/#include "application.h"/g' \
+	-e 's/gedit_debug_message (DEBUG_PLUGINS,/g_warning(/g' \
+	-e 's/gedit_debug/\/\/gedit_debug/g' \
+	-e 's/gedit_app/gtranslator_application/g' \
+	-e 's/.gnome2\/gedit\/plugins\//.gtranslator\/plugins\//g' \
+	-e 's/\/apps\/gedit-2\/plugins/\/apps\/gtranslator\/plugins/g' \
+	-e 's/gedit/gtranslator/g' \
+	-e 's/Gedit/Gtranslator/g' \
+	-e 's/GEDIT/GTR/g' \
+	$1
+}
+
+sed_it gedit-module.h > module.h
+sed_it gedit-module.c > module.c
+sed_it gedit-plugin-info-priv.h > plugin-info-priv.h
+sed_it gedit-plugin-info.h > plugin-info.h
+sed_it gedit-plugin-info.c > plugin-info.c
+sed_it gedit-plugin.c > plugin.c
+sed_it gedit-plugin.h > plugin.h
+sed_it gedit-plugin-manager.h > plugin-manager.h
+sed_it gedit-plugin-manager.c > plugin-manager.c
+sed_it gedit-plugins-engine.c > plugins-engine.c
+sed_it gedit-plugins-engine.h > plugins-engine.h
+
+rm gedit-module.h
+rm gedit-module.c
+rm gedit-plugin-info-priv.h
+rm gedit-plugin-info.h
+rm gedit-plugin-info.c
+rm gedit-plugin.c
+rm gedit-plugin.h
+rm gedit-plugin-manager.c
+rm gedit-plugin-manager.h
+rm gedit-plugins-engine.c
+rm gedit-plugins-engine.h
+

Modified: branches/GOBJECT_WORK/src/utils_gui.c
==============================================================================
--- branches/GOBJECT_WORK/src/utils_gui.c	(original)
+++ branches/GOBJECT_WORK/src/utils_gui.c	Sun Jan 13 08:12:00 2008
@@ -32,6 +32,98 @@
 #include <gtk/gtk.h>
 
 
+GtkWidget *
+gtranslator_gtk_button_new_with_stock_icon (const gchar *label,
+				      const gchar *stock_id)
+{
+	GtkWidget *button;
+
+	button = gtk_button_new_with_mnemonic (label);
+	gtk_button_set_image (GTK_BUTTON (button),
+			      gtk_image_new_from_stock (stock_id,
+							GTK_ICON_SIZE_BUTTON));
+
+        return button;
+}
+
+void
+gtranslator_utils_menu_position_under_widget (GtkMenu  *menu,
+					gint     *x,
+					gint     *y,
+					gboolean *push_in,
+					gpointer  user_data)
+{
+	GtkWidget *w = GTK_WIDGET (user_data);
+	GtkRequisition requisition;
+
+	gdk_window_get_origin (w->window, x, y);
+	gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
+
+	if (gtk_widget_get_direction (w) == GTK_TEXT_DIR_RTL)
+	{
+		*x += w->allocation.x + w->allocation.width - requisition.width;
+	}
+	else
+	{
+		*x += w->allocation.x;
+	}
+
+	*y += w->allocation.y + w->allocation.height;
+
+	*push_in = TRUE;
+}
+
+void
+gtranslator_utils_menu_position_under_tree_view (GtkMenu  *menu,
+					   gint     *x,
+					   gint     *y,
+					   gboolean *push_in,
+					   gpointer  user_data)
+{
+	GtkTreeView *tree = GTK_TREE_VIEW (user_data);
+	GtkTreeModel *model;
+	GtkTreeSelection *selection;
+	GtkTreeIter iter;
+	
+	model = gtk_tree_view_get_model (tree);
+	g_return_if_fail (model != NULL);
+
+	selection = gtk_tree_view_get_selection (tree);
+	g_return_if_fail (selection != NULL);
+
+	if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+	{
+		GtkTreePath *path;
+		GdkRectangle rect;
+
+		gdk_window_get_origin (GTK_WIDGET (tree)->window, x, y);
+			
+		path = gtk_tree_model_get_path (model, &iter);
+		gtk_tree_view_get_cell_area (tree, path,
+					     gtk_tree_view_get_column (tree, 0), /* FIXME 0 for RTL ? */
+					     &rect);
+		gtk_tree_path_free (path);
+		
+		*x += rect.x;
+		*y += rect.y + rect.height;
+		
+		if (gtk_widget_get_direction (GTK_WIDGET (tree)) == GTK_TEXT_DIR_RTL)
+		{
+			GtkRequisition requisition;
+			gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
+			*x += rect.width - requisition.width;
+		}
+	}
+	else
+	{
+		/* no selection -> regular "under widget" positioning */
+		gtranslator_utils_menu_position_under_widget (menu,
+							x, y, push_in,
+							tree);
+	}
+}
+
+
 /**
  * gtranslator_utils_get_glade_widgets:
  * @filename: the path to the glade file

Modified: branches/GOBJECT_WORK/src/utils_gui.h
==============================================================================
--- branches/GOBJECT_WORK/src/utils_gui.h	(original)
+++ branches/GOBJECT_WORK/src/utils_gui.h	Sun Jan 13 08:12:00 2008
@@ -21,6 +21,22 @@
 #define GTR_UTILS_GUI_H 1
 
 #include <gtk/gtkwidget.h>
+#include <gtk/gtkmenu.h>
+
+GtkWidget     *gtranslator_gtk_button_new_with_stock_icon (const gchar *label,
+				      const gchar *stock_id);
+
+void           gtranslator_utils_menu_position_under_widget (GtkMenu  *menu,
+					gint     *x,
+					gint     *y,
+					gboolean *push_in,
+					gpointer  user_data);
+					
+void           gtranslator_utils_menu_position_under_tree_view (GtkMenu  *menu,
+					   gint     *x,
+					   gint     *y,
+					   gboolean *push_in,
+					   gpointer  user_data);
 
 gboolean       gtranslator_utils_get_glade_widgets    (const gchar *filename,
 						       const gchar *root_node,



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