gedit r6619 - in trunk: . bindings gedit plugin-loaders plugin-loaders/python/bindings



Author: jessevdk
Date: Tue Nov 25 22:00:16 2008
New Revision: 6619
URL: http://svn.gnome.org/viewvc/gedit?rev=6619&view=rev

Log:
	* configure.ac:
	* Makefile.am:
	* bindings/:
	* plugin-loaders/:
	* gedit/Makefile.am:
	* gedit/gedit-module.[ch]:
	* gedit/gedit-object-module.[ch]:
	* gedit/gedit-plugin.h:
	* gedit/gedit-plugin-info.c:
	* gedit/gedit-plugin-info-priv.h:
	* gedit/gedit-plugin-loader.[ch]:
	* gedit/gedit-plugins-engine.[ch]:
	* gedit/gedit-window.c:
	* gedit/gedit-window-private.h:	

	Merged plugin system changes from new_plugins branch to trunk. Changes
	include plugin loader refactoring in loadable modules and pyton
	plugin internals rework.


Added:
   trunk/gedit/gedit-object-module.c
      - copied unchanged from r6618, /branches/new_plugins/gedit/gedit-object-module.c
   trunk/gedit/gedit-object-module.h
      - copied unchanged from r6618, /branches/new_plugins/gedit/gedit-object-module.h
   trunk/gedit/gedit-plugin-loader.c
      - copied unchanged from r6618, /branches/new_plugins/gedit/gedit-plugin-loader.c
   trunk/gedit/gedit-plugin-loader.h
      - copied unchanged from r6618, /branches/new_plugins/gedit/gedit-plugin-loader.h
   trunk/plugin-loaders/
      - copied from r6618, /branches/new_plugins/plugin-loaders/
Removed:
   trunk/bindings/
   trunk/gedit/gedit-module.c
   trunk/gedit/gedit-module.h
Modified:
   trunk/   (props changed)
   trunk/ChangeLog
   trunk/Makefile.am
   trunk/configure.ac
   trunk/gedit/Makefile.am
   trunk/gedit/gedit-plugin-info-priv.h
   trunk/gedit/gedit-plugin-info.c
   trunk/gedit/gedit-plugin-info.h
   trunk/gedit/gedit-plugin.h
   trunk/gedit/gedit-plugins-engine.c
   trunk/gedit/gedit-plugins-engine.h
   trunk/gedit/gedit-window-private.h
   trunk/gedit/gedit-window.c
   trunk/plugin-loaders/python/bindings/   (props changed)
   trunk/plugin-loaders/python/bindings/Makefile.am
   trunk/plugin-loaders/python/bindings/gedit.defs
   trunk/plugin-loaders/python/bindings/gedit.override

Modified: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am	(original)
+++ trunk/Makefile.am	Tue Nov 25 22:00:16 2008
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = bindings gedit pixmaps po help data plugins docs
+SUBDIRS = plugin-loaders gedit pixmaps po help data plugins docs
 
 distuninstallcheck_listfiles = find . -type f -print | grep -v scrollkeeper
 

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Tue Nov 25 22:00:16 2008
@@ -189,7 +189,6 @@
 AC_SUBST(GEDIT_LIBS)
 AC_SUBST(GEDIT_CFLAGS)
 
-
 dnl ================================================================
 dnl GConf related settings
 dnl ================================================================
@@ -345,10 +344,11 @@
 AC_SUBST(GEDIT_IMPLIB)
 AC_SUBST(PLUGIN_LIBTOOL_FLAGS)
 
+LOADER_LIBTOOL_FLAGS="-module -avoid-version"
+AC_SUBST(LOADER_LIBTOOL_FLAGS)
+
 AC_CONFIG_FILES([
 Makefile
-bindings/Makefile
-bindings/python/Makefile
 data/gedit.desktop.in
 data/gedit-bugreport.sh
 data/gedit.pc
@@ -362,6 +362,10 @@
 help/eu/Makefile
 help/ro/Makefile
 pixmaps/Makefile
+plugin-loaders/Makefile
+plugin-loaders/c/Makefile
+plugin-loaders/python/Makefile
+plugin-loaders/python/bindings/Makefile
 plugins/changecase/Makefile
 plugins/docinfo/Makefile
 plugins/externaltools/Makefile

Modified: trunk/gedit/Makefile.am
==============================================================================
--- trunk/gedit/Makefile.am	(original)
+++ trunk/gedit/Makefile.am	Tue Nov 25 22:00:16 2008
@@ -5,34 +5,30 @@
 
 noinst_LTLIBRARIES = libgedit.la
 
-INCLUDES =							\
-	-I$(top_srcdir)						\
-	-I$(srcdir)						\
-	-I$(srcdir)/smclient					\
-	$(GEDIT_CFLAGS)						\
-	$(WARN_CFLAGS)						\
-	$(DISABLE_DEPRECATED_CFLAGS)				\
-	-DDATADIR=\""$(datadir)"\"				\
-	-DGEDIT_DATADIR=\""$(datadir)/gedit-2"\"		\
-	-DGEDIT_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"	\
-	-DGEDIT_UIDIR=\""$(datadir)/gedit-2/ui/"\"		\
-	-DGEDIT_PLUGINDIR=\""$(libdir)/gedit-2/plugins"\"	\
+INCLUDES =								\
+	-I$(top_srcdir)							\
+	-I$(srcdir)							\
+	-I$(srcdir)/smclient						\
+	$(GEDIT_CFLAGS)							\
+	$(WARN_CFLAGS)							\
+	$(DISABLE_DEPRECATED_CFLAGS)					\
+	-DDATADIR=\""$(datadir)"\"					\
+	-DGEDIT_DATADIR=\""$(datadir)/gedit-2"\"			\
+	-DGEDIT_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"		\
+	-DGEDIT_UIDIR=\""$(datadir)/gedit-2/ui/"\"			\
+	-DGEDIT_PLUGINDIR=\""$(libdir)/gedit-2/plugins"\"		\
+	-DGEDIT_LOADERDIR=\""$(libdir)/gedit-2/plugin-loaders"\"	\
 	-DGEDIT_ICONDIR=\""$(datadir)/gedit-2/icons"\"
 
-if ENABLE_PYTHON
-INCLUDES += \
-	$(NO_STRICT_ALIASING_CFLAGS)	\
-	$(PYGTK_CFLAGS)			\
-	$(PYTHON_CFLAGS)		\
-	$(AM_CFLAGS)
-endif
+gedit_SOURCES = \
+	gedit.c
 
-gedit_SOURCES = gedit.c
 gedit_LDADD = libgedit.la $(GEDIT_LIBS)
  
 if PLATFORM_WIN32
 gedit_LDFLAGS = -Wl,--export-all-symbols -Wl,--out-implib,libgedit-$(GEDIT_API_VERSION).a
 else
+
 gedit_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
 endif
 
@@ -42,10 +38,6 @@
 	dialogs/libdialogs.la		\
 	smclient/libeggsmclient.la
 
-if ENABLE_PYTHON
-libgedit_la_LIBADD += $(top_builddir)/bindings/python/gedit.la
-endif
-
 # GEDIT_LIBS must be the last to ensure correct order on some platforms
 libgedit_la_LIBADD += $(GEDIT_LIBS)
 
@@ -63,7 +55,7 @@
 	gedit-plugin-info-priv.h	\
 	gedit-plugin-manager.h		\
 	gedit-plugins-engine.h		\
-	gedit-module.h			\
+	gedit-object-module.h		\
 	gedit-ui.h			\
 	gedit-window-private.h		\
 	gedit-documents-panel.h		\
@@ -83,12 +75,6 @@
 	gedittextregion.h		\
 	gedit-session.h
 
-if ENABLE_PYTHON
-NOINST_H_FILES += \
-	gedit-python-module.h		\
-	gedit-python-plugin.h 
-endif
-
 INST_H_FILES =				\
 	gedit-app.h			\
 	gedit-convert.h			\
@@ -103,6 +89,7 @@
 	gedit-notebook.h		\
 	gedit-panel.h			\
 	gedit-plugin.h			\
+	gedit-plugin-loader.h		\
 	gedit-prefs-manager-app.h	\
 	gedit-prefs-manager.h		\
 	gedit-progress-message-area.h	\
@@ -147,11 +134,12 @@
 	gedit-language-manager.c	\
 	gedit-message-area.c		\
 	gedit-metadata-manager.c	\
-	gedit-module.c			\
+	gedit-object-module.c		\
 	gedit-notebook.c		\
 	gedit-panel.c			\
 	gedit-plugin-info.c		\
 	gedit-plugin.c			\
+	gedit-plugin-loader.c		\
 	gedit-plugin-manager.c		\
 	gedit-plugins-engine.c		\
 	gedit-prefs-manager-app.c	\
@@ -173,15 +161,6 @@
 	$(NOINST_H_FILES)		\
 	$(INST_H_FILES)
 
-
-if ENABLE_PYTHON
-libgedit_la_SOURCES += \
-	gedit-python-module.c		\
-	gedit-python-module.h		\
-	gedit-python-plugin.c		\
-	gedit-python-plugin.h	
-endif
-
 gedit-enum-types.h: gedit-enum-types.h.template $(INST_H_FILES) $(GLIB_MKENUMS)
 	(cd $(srcdir) && $(GLIB_MKENUMS) --template gedit-enum-types.h.template $(INST_H_FILES)) > $@
 	

Modified: trunk/gedit/gedit-plugin-info-priv.h
==============================================================================
--- trunk/gedit/gedit-plugin-info-priv.h	(original)
+++ trunk/gedit/gedit-plugin-info-priv.h	Tue Nov 25 22:00:16 2008
@@ -39,11 +39,11 @@
 {
 	gint               refcount;
 
+	GeditPlugin       *plugin;
 	gchar             *file;
 
 	gchar             *module_name;
-	GType              module_type;
-	GeditModule       *module;
+	gchar		  *loader;
 	gchar            **dependencies;
 
 	gchar             *name;
@@ -53,10 +53,6 @@
 	gchar             *copyright;
 	gchar             *website;
 
-	GeditPlugin       *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) */

Modified: trunk/gedit/gedit-plugin-info.c
==============================================================================
--- trunk/gedit/gedit-plugin-info.c	(original)
+++ trunk/gedit/gedit-plugin-info.c	Tue Nov 25 22:00:16 2008
@@ -42,10 +42,6 @@
 #include "gedit-debug.h"
 #include "gedit-plugin.h"
 
-#ifdef ENABLE_PYTHON
-#include "gedit-python-module.h"
-#endif
-
 void
 _gedit_plugin_info_ref (GeditPluginInfo *info)
 {
@@ -70,9 +66,6 @@
 		gedit_debug_message (DEBUG_PLUGINS, "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);
@@ -83,6 +76,7 @@
 	g_free (info->icon_name);
 	g_free (info->website);
 	g_free (info->copyright);
+	g_free (info->loader);
 	g_strfreev (info->authors);
 
 	g_free (info);
@@ -194,21 +188,16 @@
 				     "Gedit Plugin",
 				     "Loader",
 				     NULL);
-	if (str && strcmp(str, "python") == 0)
+	
+	if ((str != NULL) && (*str != '\0'))
 	{
-#ifndef ENABLE_PYTHON
-		g_warning ("Cannot load Python plugin '%s' since gedit was not "
-			   "compiled with Python support.", file);
-		goto error;
-#else
-		info->module_type = GEDIT_TYPE_PYTHON_MODULE;
-#endif
+		info->loader = str;
 	}
 	else
 	{
-		info->module_type = GEDIT_TYPE_MODULE;
+		/* default to the C loader */
+		info->loader = g_strdup("c");
 	}
-	g_free (str);
 
 	/* Get Name */
 	str = g_key_file_get_locale_string (plugin_file,
@@ -286,6 +275,7 @@
 	g_free (info->file);
 	g_free (info->module_name);
 	g_free (info->name);
+	g_free (info->loader);
 	g_free (info);
 	g_key_file_free (plugin_file);
 
@@ -297,7 +287,7 @@
 {
 	g_return_val_if_fail (info != NULL, FALSE);
 
-	return info->available && info->active;
+	return info->available && info->plugin != NULL;
 }
 
 gboolean
@@ -315,13 +305,21 @@
 
 	g_return_val_if_fail (info != NULL, FALSE);
 
-	if (info->plugin == NULL || !info->active || !info->available)
+	if (info->plugin == NULL || !info->available)
 		return FALSE;
 
 	return gedit_plugin_is_configurable (info->plugin);
 }
 
 const gchar *
+gedit_plugin_info_get_module_name (GeditPluginInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+
+	return info->module_name;
+}
+
+const gchar *
 gedit_plugin_info_get_name (GeditPluginInfo *info)
 {
 	g_return_val_if_fail (info != NULL, NULL);

Modified: trunk/gedit/gedit-plugin-info.h
==============================================================================
--- trunk/gedit/gedit-plugin-info.h	(original)
+++ trunk/gedit/gedit-plugin-info.h	Tue Nov 25 22:00:16 2008
@@ -33,7 +33,6 @@
 #define __GEDIT_PLUGIN_INFO_H__
 
 #include <glib-object.h>
-#include "gedit-module.h"
 
 G_BEGIN_DECLS
 
@@ -48,6 +47,8 @@
 gboolean 	 gedit_plugin_info_is_available		(GeditPluginInfo *info);
 gboolean	 gedit_plugin_info_is_configurable	(GeditPluginInfo *info);
 
+const gchar	*gedit_plugin_info_get_module_name	(GeditPluginInfo *info);
+
 const gchar	*gedit_plugin_info_get_name		(GeditPluginInfo *info);
 const gchar	*gedit_plugin_info_get_description	(GeditPluginInfo *info);
 const gchar	*gedit_plugin_info_get_icon_name	(GeditPluginInfo *info);

Modified: trunk/gedit/gedit-plugin.h
==============================================================================
--- trunk/gedit/gedit-plugin.h	(original)
+++ trunk/gedit/gedit-plugin.h	Tue Nov 25 22:00:16 2008
@@ -35,6 +35,7 @@
 
 #include <gedit/gedit-window.h>
 #include <gedit/gedit-debug.h>
+#include <gedit/gedit-object-module.h>
 
 /* TODO: add a .h file that includes all the .h files normally needed to
  * develop a plugin */ 
@@ -118,56 +119,15 @@
  * Utility macro used to register plugins with additional code.
  */
 #define GEDIT_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_gedit_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				\
-	};									\
-										\
-	gedit_debug_message (DEBUG_PLUGINS, "Registering " #PluginName);	\
-										\
+	GEDIT_OBJECT_MODULE_REGISTER_TYPE_WITH_CODE (register_gedit_plugin,	\
+						     PluginName,		\
+						     plugin_name,		\
+						     GEDIT_TYPE_PLUGIN,		\
 	/* Initialise the i18n stuff */						\
 	bindtextdomain (GETTEXT_PACKAGE, GEDIT_LOCALEDIR);			\
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");			\
 										\
-	plugin_name##_type = g_type_module_register_type (module,		\
-					    GEDIT_TYPE_PLUGIN,			\
-					    #PluginName,			\
-					    &our_info,				\
-					    0);					\
-										\
-	CODE									\
-										\
-	return plugin_name##_type;						\
-}
+						     CODE)
 
 /**
  * GEDIT_PLUGIN_REGISTER_TYPE(PluginName, plugin_name):
@@ -182,53 +142,7 @@
  *
  * Utility macro used to register gobject types in plugins with additional code.
  */
-#define GEDIT_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				\
-	};									\
-										\
-	gedit_debug_message (DEBUG_PLUGINS, "Registering " #ObjectName);	\
-										\
-	g_define_type_id = g_type_module_register_type (module,			\
-					   	        PARENT_TYPE,		\
-					                #ObjectName,		\
-					                &our_info,		\
-					                0);			\
-										\
-	CODE									\
-										\
-	return g_define_type_id;						\
-}
+#define GEDIT_PLUGIN_DEFINE_TYPE_WITH_CODE GEDIT_OBJECT_MODULE_DEFINE_TYPE_WITH_CODE
 
 /**
  * GEDIT_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE):
@@ -244,17 +158,7 @@
  * Utility macro used to register interfaces for gobject types in plugins.
  */
 #define GEDIT_PLUGIN_IMPLEMENT_INTERFACE(object_name, TYPE_IFACE, iface_init)	\
-	const GInterfaceInfo object_name##_interface_info = 			\
-	{ 									\
-		(GInterfaceInitFunc) iface_init,				\
-		NULL, 								\
-		NULL								\
-	};									\
-										\
-	g_type_module_add_interface (module, 					\
-				     g_define_type_id, 				\
-				     TYPE_IFACE, 				\
-				     &object_name##_interface_info);		\
+	GEDIT_OBJECT_MODULE_IMPLEMENT_INTERFACE(object_name, TYPE_IFACE, iface_init)
 
 G_END_DECLS
 

Modified: trunk/gedit/gedit-plugins-engine.c
==============================================================================
--- trunk/gedit/gedit-plugins-engine.c	(original)
+++ trunk/gedit/gedit-plugins-engine.c	Tue Nov 25 22:00:16 2008
@@ -42,18 +42,22 @@
 #include "gedit-plugin.h"
 #include "gedit-debug.h"
 #include "gedit-app.h"
+#include "gedit-plugin-loader.h"
+#include "gedit-object-module.h"
 
-#include "gedit-module.h"
-#ifdef ENABLE_PYTHON
-#include "gedit-python-module.h"
-#endif
-
-#define USER_GEDIT_PLUGINS_LOCATION ".gnome2/gedit/plugins/"
+#define USER_GEDIT_LOCATION ".gnome2/gedit/"
 
 #define GEDIT_PLUGINS_ENGINE_BASE_KEY "/apps/gedit-2/plugins"
 #define GEDIT_PLUGINS_ENGINE_KEY GEDIT_PLUGINS_ENGINE_BASE_KEY "/active-plugins"
 
 #define PLUGIN_EXT	".gedit-plugin"
+#define LOADER_EXT	G_MODULE_SUFFIX
+
+typedef struct
+{
+	GeditPluginLoader *loader;
+	GeditObjectModule *module;
+} LoaderInfo;
 
 /* Signals */
 enum
@@ -70,7 +74,10 @@
 struct _GeditPluginsEnginePrivate
 {
 	GList *plugin_list;
+	GHashTable *loaders;
+
 	GConfClient *gconf_client;
+	gboolean activate_from_gconf;
 };
 
 GeditPluginsEngine *default_engine = NULL;
@@ -84,86 +91,100 @@
 static void	gedit_plugins_engine_deactivate_plugin_real (GeditPluginsEngine *engine,
 							     GeditPluginInfo    *info);
 
-static void
-gedit_plugins_engine_load_dir (GeditPluginsEngine *engine,
-			       const gchar        *dir,
-			       GSList             *active_plugins)
+typedef gboolean (*LoadDirCallback)(GeditPluginsEngine *engine, const gchar *filename, gpointer userdata);
+
+static gboolean
+load_dir_real (GeditPluginsEngine *engine,
+	       const gchar        *dir,
+	       const gchar        *suffix,
+	       LoadDirCallback     callback,
+	       gpointer            userdata)
 {
 	GError *error = NULL;
 	GDir *d;
 	const gchar *dirent;
+	gboolean ret = TRUE;
 
-	g_return_if_fail (engine->priv->gconf_client != NULL);
-	g_return_if_fail (dir != NULL);
+	g_return_val_if_fail (dir != NULL, TRUE);
 
 	gedit_debug_message (DEBUG_PLUGINS, "DIR: %s", dir);
 
 	d = g_dir_open (dir, 0, &error);
+
 	if (!d)
 	{
 		g_warning ("%s", error->message);
 		g_error_free (error);
-		return;
+		return TRUE;
 	}
-
+	
 	while ((dirent = g_dir_read_name (d)))
 	{
-		if (g_str_has_suffix (dirent, PLUGIN_EXT))
-		{
-			gchar *plugin_file;
-			GeditPluginInfo *info;
-			
-			plugin_file = g_build_filename (dir, dirent, NULL);
-			info = _gedit_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 (gedit_plugins_engine_get_plugin_info (engine, info->module_name) != NULL)
-			{
-				g_warning ("Two or more plugins named '%s'. "
-					   "Only the first will be considered.\n",
-					   info->module_name);
-
-				_gedit_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;
+		gchar *filename;
+		
+		if (!g_str_has_suffix (dirent, suffix))
+			continue;
+		
+		filename = g_build_filename (dir, dirent, NULL);
 
-			engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info);
+		ret = callback (engine, filename, userdata);
+		
+		if (!ret)
+			break;
+	}
+	
+	g_dir_close (d);
+	return ret;
+}
 
-			gedit_debug_message (DEBUG_PLUGINS, "Plugin %s loaded", info->name);
-		}
+static gboolean
+load_plugin_info (GeditPluginsEngine *engine,
+		  const gchar        *filename,
+		  gpointer            userdata)
+{
+	GeditPluginInfo *info;
+	
+	info = _gedit_plugin_info_new (filename);
+
+	if (info == NULL)
+		return TRUE;
+
+	/* If a plugin with this name has already been loaded
+	 * drop this one (user plugins override system plugins) */
+	if (gedit_plugins_engine_get_plugin_info (engine, gedit_plugin_info_get_module_name (info)) != NULL)
+	{
+		g_warning ("Two or more plugins named '%s'. "
+			   "Only the first will be considered.\n",
+			   gedit_plugin_info_get_module_name (info));
+
+		_gedit_plugin_info_unref (info);
+
+		return TRUE;
 	}
 
-	g_dir_close (d);
+	engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info);
+
+	gedit_debug_message (DEBUG_PLUGINS, "Plugin %s loaded", info->name);
+	return TRUE;
 }
 
 static void
-gedit_plugins_engine_load_all (GeditPluginsEngine *engine)
+load_all_real (GeditPluginsEngine *engine,
+               const gchar        *dir,
+               const gchar        *envname,
+               const gchar        *envdefault,
+               const gchar        *suffix,
+	       LoadDirCallback     callback,
+	       gpointer            userdata)
 {
-	GSList *active_plugins = NULL;
 	const gchar *home;
-	const gchar *pdirs_env;
+	const gchar *pdirs_env = NULL;
 	gchar **pdirs;
 	int i;
 
-	active_plugins = gconf_client_get_list (engine->priv->gconf_client,
-						GEDIT_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");
@@ -171,31 +192,95 @@
 	else
 	{
 		gchar *pdir;
+		gboolean ret = TRUE;
 
 		pdir = g_build_filename (home,
-					 USER_GEDIT_PLUGINS_LOCATION,
+					 USER_GEDIT_LOCATION,
+					 dir,
 					 NULL);
 
 		if (g_file_test (pdir, G_FILE_TEST_IS_DIR))
-			gedit_plugins_engine_load_dir (engine, pdir, active_plugins);
+			ret = load_dir_real (engine, pdir, suffix, callback, userdata);
 		
 		g_free (pdir);
+		
+		if (!ret)
+			return;
 	}
+	
+	if (envname)
+		pdirs_env = g_getenv (envname);
 
-	pdirs_env = g_getenv ("GEDIT_PLUGINS_PATH");
-	/* What if no env var is set? We use the default location(s)! */
 	if (pdirs_env == NULL)
-		pdirs_env = GEDIT_PLUGINDIR;
+		pdirs_env = envdefault;
 
-	gedit_debug_message (DEBUG_PLUGINS, "GEDIT_PLUGINS_PATH=%s", pdirs_env);
+	gedit_debug_message (DEBUG_PLUGINS, "%s=%s", envname, pdirs_env);
 	pdirs = g_strsplit (pdirs_env, G_SEARCHPATH_SEPARATOR_S, 0);
 
 	for (i = 0; pdirs[i] != NULL; i++)
-		gedit_plugins_engine_load_dir (engine, pdirs[i], active_plugins);
+	{
+		if (!load_dir_real (engine, pdirs[i], suffix, callback, userdata))
+			break;
+	}
 
 	g_strfreev (pdirs);
-	g_slist_foreach (active_plugins, (GFunc) g_free, NULL);
-	g_slist_free (active_plugins);
+}
+
+static void
+load_all_plugins (GeditPluginsEngine *engine)
+{
+	load_all_real (engine, 
+		       "plugins", 
+		       "GEDIT_PLUGINS_PATH", 
+		       GEDIT_PLUGINDIR,
+		       PLUGIN_EXT,
+		       load_plugin_info,
+		       NULL);
+}
+
+static guint
+hash_lowercase (gconstpointer data)
+{
+	gchar *lowercase;
+	guint ret;
+	
+	lowercase = g_ascii_strdown ((const gchar *)data, -1);
+	ret = g_str_hash (lowercase);
+	g_free (lowercase);
+	
+	return ret;
+}
+
+static gboolean
+equal_lowercase (gconstpointer a, gconstpointer b)
+{
+	return g_ascii_strcasecmp ((const gchar *)a, (const gchar *)b) == 0;
+}
+
+static void
+loader_destroy (LoaderInfo *info)
+{
+	if (!info)
+		return;
+	
+	if (info->loader)
+		g_object_unref (info->loader);
+	
+	g_free (info);
+}
+
+static void
+add_loader (GeditPluginsEngine *engine,
+	    const gchar        *loader_name,
+	    GeditObjectModule  *module)
+{
+	LoaderInfo *info;
+
+	info = g_new (LoaderInfo, 1);
+	info->loader = NULL;
+	info->module = module;
+
+	g_hash_table_insert (engine->priv->loaders, g_strdup (loader_name), info);
 }
 
 static void
@@ -226,46 +311,61 @@
 				 gedit_plugins_engine_active_plugins_changed,
 				 engine, NULL, NULL);
 
-	gedit_plugins_engine_load_all (engine);
+	load_all_plugins (engine);
+	
+	/* make sure that the first reactivation will read active plugins from
+	   gconf */
+	engine->priv->activate_from_gconf = TRUE;
+	
+	/* mapping from loadername -> loader object */
+	engine->priv->loaders = g_hash_table_new_full (hash_lowercase,
+						       equal_lowercase,
+						       (GDestroyNotify)g_free,
+						       (GDestroyNotify)loader_destroy);
 }
 
 void
 gedit_plugins_engine_garbage_collect (GeditPluginsEngine *engine)
 {
-	GType *module_types = g_type_children (GEDIT_TYPE_MODULE, NULL);
-	unsigned i;
-	for (i = 0; module_types[i] != 0; i++)
-	{
-		gpointer klass = g_type_class_peek (module_types[i]);
-		if (klass != NULL)
-			gedit_module_class_garbage_collect (klass);
+	GList *loaders;
+	GList *item;
+	
+	loaders = g_hash_table_get_values (engine->priv->loaders);
+	
+	for (item = loaders; item; item = item->next)
+	{
+		LoaderInfo *info = (LoaderInfo *)item->data;
+		
+		if (info->loader)
+			gedit_plugin_loader_garbage_collect (info->loader);
 	}
-	g_free (module_types);
+	
+	g_list_free (loaders);
 }
 
 static void
 gedit_plugins_engine_finalize (GObject *object)
 {
 	GeditPluginsEngine *engine = GEDIT_PLUGINS_ENGINE (object);
-
+	GList *item;
+	
 	gedit_debug (DEBUG_PLUGINS);
 
-#ifdef ENABLE_PYTHON
-	/* Note: that this may cause finalization of objects (typically
-	 * the GeditWindow) 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.
-	 */
-	gedit_python_shutdown ();
-#endif
-
 	g_return_if_fail (engine->priv->gconf_client != NULL);
 
-	g_list_foreach (engine->priv->plugin_list,
-			(GFunc) _gedit_plugin_info_unref, NULL);
+	for (item = engine->priv->plugin_list; item; item = item->next)
+	{
+		GeditPluginInfo *info = GEDIT_PLUGIN_INFO (item->data);
+		
+		if (gedit_plugin_info_is_active (info))
+			gedit_plugins_engine_deactivate_plugin_real (engine, info);
+		
+		_gedit_plugin_info_unref (info);
+	}
+	
 	g_list_free (engine->priv->plugin_list);
-
+	
+	g_hash_table_destroy (engine->priv->loaders);
 	g_object_unref (engine->priv->gconf_client);
 }
 
@@ -304,6 +404,111 @@
 	g_type_class_add_private (klass, sizeof (GeditPluginsEnginePrivate));
 }
 
+static gboolean
+load_loader (GeditPluginsEngine *engine,
+	     const gchar        *filename,
+	     gpointer		 data)
+{
+	GeditObjectModule *module;
+	gchar *base;
+	gchar *path;
+	const gchar *name;
+	GType type;
+	
+	/* try to load in the module */
+	path = g_path_get_dirname (filename);
+	base = g_path_get_basename (filename);
+
+	module = gedit_object_module_new (base, path, "register_gedit_plugin_loader");
+	
+	g_free (base);
+	g_free (path);
+
+	/* make sure to load the type definition */
+	if (!g_type_module_use (G_TYPE_MODULE (module)))
+	{
+		g_object_unref (module);
+		g_warning ("Plugin loader module `%s' could not be loaded", filename);
+
+		return TRUE;
+	}
+	
+	/* get the exported type and check the name as exported by the 
+	 * loader interface */
+	type = gedit_object_module_get_object_type (module);
+	name = gedit_plugin_loader_type_get_name (type);
+	
+	add_loader (engine, name, module);	
+	g_type_module_unuse (G_TYPE_MODULE (module));
+
+	return TRUE;
+}
+
+static void
+ensure_loader (LoaderInfo *info)
+{
+	if (info->loader == NULL && info->module != NULL)
+	{
+		/* create a new loader object */
+		GeditPluginLoader *loader;
+		loader = (GeditPluginLoader *)gedit_object_module_new_object (info->module, NULL);
+	
+		if (loader == NULL || !GEDIT_IS_PLUGIN_LOADER (loader))
+		{
+			g_warning ("Loader object is not a valid GeditPluginLoader instance");
+		
+			if (loader != NULL && G_IS_OBJECT (loader))
+				g_object_unref (loader);
+		}
+		else
+		{
+			info->loader = loader;
+		}
+	}
+}
+
+static GeditPluginLoader *
+get_plugin_loader (GeditPluginsEngine *engine, GeditPluginInfo *info)
+{
+	const gchar *loader_name;
+	LoaderInfo *loader_info;
+	
+	loader_name = info->loader;
+
+	loader_info = (LoaderInfo *)g_hash_table_lookup (
+			engine->priv->loaders, 
+			loader_name);
+
+	if (loader_info == NULL)
+	{
+		/* loader could not be found in the hash, try to find it by 
+		   scanning */
+		load_all_real (engine, 
+			       "plugin-loaders", 
+			       NULL, 
+			       GEDIT_LOADERDIR,
+			       LOADER_EXT,
+			       (LoadDirCallback)load_loader,
+			       NULL);
+		
+		loader_info = (LoaderInfo *)g_hash_table_lookup (
+				engine->priv->loaders, 
+				loader_name);
+	}
+	
+	
+	
+	if (loader_info == NULL)
+	{
+		/* cache non-existent so we don't scan again */
+		add_loader (engine, loader_name, NULL);
+		return NULL;
+	}
+	
+	ensure_loader (loader_info);
+	return loader_info->loader;
+}
+
 GeditPluginsEngine *
 gedit_plugins_engine_get_default (void)
 {
@@ -328,7 +533,7 @@
 compare_plugin_info_and_name (GeditPluginInfo *info,
 			      const gchar *module_name)
 {
-	return strcmp (info->module_name, module_name);
+	return strcmp (gedit_plugin_info_get_module_name (info), module_name);
 }
 
 GeditPluginInfo *
@@ -341,67 +546,6 @@
 	return l == NULL ? NULL : (GeditPluginInfo *) l->data;
 }
 
-static gboolean
-load_plugin_module (GeditPluginInfo *info)
-{
-	gchar *dirname;
-
-	gedit_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);
-
-	dirname = g_path_get_dirname (info->file);
-	g_return_val_if_fail (dirname != NULL, FALSE);
-
-#ifdef ENABLE_PYTHON
-	if (info->module_type == GEDIT_TYPE_PYTHON_MODULE)
-	{
-		if (!gedit_python_init ())
-		{
-			/* Mark plugin as unavailable and fail */
-			info->available = FALSE;
-			g_warning ("Cannot load Python plugin '%s' since gedit "
-			           "was not able to initialize the Python interpreter.",
-			           info->name);
-		}
-	}
-#endif
-
-	info->module = GEDIT_MODULE (g_object_new (info->module_type,
-						   "path", dirname,
-						   "module-name", info->module_name,
-						   NULL));
-
-	g_free (dirname);
-
-	if (!g_type_module_use (G_TYPE_MODULE (info->module)))
-	{
-		g_warning ("Cannot load plugin '%s' since file '%s' cannot be read.",
-			   gedit_module_get_module_name (info->module),
-			   gedit_module_get_path (info->module));
-
-		g_object_unref (G_OBJECT (info->module));
-		info->module = NULL;
-
-		/* Mark plugin as unavailable and fail. */
-		info->available = FALSE;
-		
-		return FALSE;
-	}
-
-	info->plugin = GEDIT_PLUGIN (gedit_module_new_object (info->module));
-
-	g_type_module_unuse (G_TYPE_MODULE (info->module));
-
-	gedit_debug_message (DEBUG_PLUGINS, "End");
-
-	return TRUE;
-}
-
 static void
 save_active_plugin_list (GeditPluginsEngine *engine)
 {
@@ -411,11 +555,12 @@
 
 	for (l = engine->priv->plugin_list; l != NULL; l = l->next)
 	{
-		const GeditPluginInfo *info = (const GeditPluginInfo *) l->data;
-		if (info->active)
+		GeditPluginInfo *info = (GeditPluginInfo *) l->data;
+
+		if (gedit_plugin_info_is_active (info))
 		{
 			active_plugins = g_slist_prepend (active_plugins,
-							  info->module_name);
+							  (gpointer)gedit_plugin_info_get_module_name (info));
 		}
 	}
 
@@ -431,28 +576,56 @@
 	g_slist_free (active_plugins);
 }
 
-static void
-gedit_plugins_engine_activate_plugin_real (GeditPluginsEngine *engine,
-					   GeditPluginInfo *info)
+static gboolean
+load_plugin (GeditPluginsEngine *engine,
+	     GeditPluginInfo    *info)
 {
-	gboolean res = TRUE;
-
-	if (info->active || !info->available)
-		return;
+	GeditPluginLoader *loader;
+	gchar *path;
 
-	if (info->plugin == NULL)
-		res = load_plugin_module (info);
+	if (gedit_plugin_info_is_active (info))
+		return TRUE;
+	
+	if (!gedit_plugin_info_is_available (info))
+		return FALSE;
 
-	if (res)
+	loader = get_plugin_loader (engine, info);
+	
+	if (loader == NULL)
 	{
-		const GList *wins = gedit_app_get_windows (gedit_app_get_default ());
-		for (; wins != NULL; wins = wins->next)
-			gedit_plugin_activate (info->plugin, GEDIT_WINDOW (wins->data));
+		g_warning ("Could not find loader `%s' for plugin `%s'", info->loader, info->name);
+		info->available = FALSE;
+		return FALSE;
+	}
+	
+	path = g_path_get_dirname (info->file);
+	g_return_val_if_fail (path != NULL, FALSE);
 
-		info->active = TRUE;
+	info->plugin = gedit_plugin_loader_load (loader, info, path);
+	
+	g_free (path);
+	
+	if (info->plugin == NULL)
+	{
+		g_warning ("Error loading plugin '%s'", info->name);
+		info->available = FALSE;
+		return FALSE;
 	}
-	else
-		g_warning ("Error activating plugin '%s'", info->name);
+	
+	return TRUE;
+}
+
+static void
+gedit_plugins_engine_activate_plugin_real (GeditPluginsEngine *engine,
+					   GeditPluginInfo *info)
+{
+	if (!load_plugin (engine, info))
+		return;
+
+	/* activate plugin for all windows */
+	const GList *wins = gedit_app_get_windows (gedit_app_get_default ());
+	for (; wins != NULL; wins = wins->next)
+		gedit_plugin_activate (info->plugin, GEDIT_WINDOW (wins->data));
 }
 
 gboolean
@@ -463,17 +636,18 @@
 
 	g_return_val_if_fail (info != NULL, FALSE);
 
-	if (!info->available)
+	if (!gedit_plugin_info_is_available (info))
 		return FALSE;
 		
-	if (info->active)
+	if (gedit_plugin_info_is_active (info))
 		return TRUE;
 
 	g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
-	if (info->active)
+
+	if (gedit_plugin_info_is_active (info))
 		save_active_plugin_list (engine);
 
-	return info->active;
+	return gedit_plugin_info_is_active (info);
 }
 
 static void
@@ -481,15 +655,26 @@
 					     GeditPluginInfo *info)
 {
 	const GList *wins;
+	GeditPluginLoader *loader;
 
-	if (!info->active || !info->available)
+	if (!gedit_plugin_info_is_active (info) || 
+	    !gedit_plugin_info_is_available (info))
 		return;
 
 	wins = gedit_app_get_windows (gedit_app_get_default ());
 	for (; wins != NULL; wins = wins->next)
 		gedit_plugin_deactivate (info->plugin, GEDIT_WINDOW (wins->data));
 
-	info->active = FALSE;
+	/* first unref the plugin (the loader still has one) */
+	g_object_unref (info->plugin);
+	
+	/* find the loader and tell it to gc and unload the plugin */
+	loader = get_plugin_loader (engine, info);
+	
+	gedit_plugin_loader_garbage_collect (loader);
+	gedit_plugin_loader_unload (loader, info);
+	
+	info->plugin = NULL;
 }
 
 gboolean
@@ -500,40 +685,90 @@
 
 	g_return_val_if_fail (info != NULL, FALSE);
 
-	if (!info->active || !info->available)
+	if (!gedit_plugin_info_is_active (info))
 		return TRUE;
 
 	g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
-	if (!info->active)
+	if (!gedit_plugin_info_is_active (info))
 		save_active_plugin_list (engine);
 
-	return !info->active;
+	return !gedit_plugin_info_is_active (info);
 }
 
-static void
-reactivate_all (GeditPluginsEngine *engine,
-		GeditWindow        *window)
+void
+gedit_plugins_engine_activate_plugins (GeditPluginsEngine *engine,
+					GeditWindow        *window)
 {
 	GList *pl;
+	GSList *active_plugins = NULL;
 
 	gedit_debug (DEBUG_PLUGINS);
 
+	g_return_if_fail (GEDIT_IS_PLUGINS_ENGINE (engine));
+	g_return_if_fail (GEDIT_IS_WINDOW (window));
+	
+	/* the first time, we get the 'active' plugins from gconf */
+	if (engine->priv->activate_from_gconf)
+	{
+		active_plugins = gconf_client_get_list (engine->priv->gconf_client,
+							GEDIT_PLUGINS_ENGINE_KEY,
+							GCONF_VALUE_STRING,
+							NULL);
+	}
+
 	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
 	{
-		gboolean res = TRUE;
-		
 		GeditPluginInfo *info = (GeditPluginInfo*)pl->data;
+		
+		if (engine->priv->activate_from_gconf && 
+		    g_slist_find_custom (active_plugins,
+					 gedit_plugin_info_get_module_name (info),
+					 (GCompareFunc)strcmp) == NULL)
+			continue;
+		
+		/* If plugin is not active, don't try to activate/load it */
+		if (!engine->priv->activate_from_gconf && 
+		    !gedit_plugin_info_is_active (info))
+			continue;
 
-		/* 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)
-				gedit_plugin_activate (info->plugin,
-						       window);			
-		}
+		if (load_plugin (engine, info))
+			gedit_plugin_activate (info->plugin,
+					       window);
+	}
+	
+	if (engine->priv->activate_from_gconf)
+	{
+		g_slist_free (active_plugins);
+		engine->priv->activate_from_gconf = FALSE;
+	}
+	
+	gedit_debug_message (DEBUG_PLUGINS, "End");
+
+	/* also call update_ui after activation */
+	gedit_plugins_engine_update_plugins_ui (engine, window);
+}
+
+void
+gedit_plugins_engine_deactivate_plugins (GeditPluginsEngine *engine,
+					  GeditWindow        *window)
+{
+	GList *pl;
+	
+	gedit_debug (DEBUG_PLUGINS);
+
+	g_return_if_fail (GEDIT_IS_PLUGINS_ENGINE (engine));
+	g_return_if_fail (GEDIT_IS_WINDOW (window));
+	
+	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
+	{
+		GeditPluginInfo *info = (GeditPluginInfo*)pl->data;
+		
+		/* check if the plugin is actually active */
+		if (!gedit_plugin_info_is_active (info))
+			continue;
+		
+		/* call deactivate for the plugin for this window */
+		gedit_plugin_deactivate (info->plugin, window);
 	}
 	
 	gedit_debug_message (DEBUG_PLUGINS, "End");
@@ -541,28 +776,24 @@
 
 void
 gedit_plugins_engine_update_plugins_ui (GeditPluginsEngine *engine,
-					GeditWindow        *window,
-					gboolean            new_window)
+					 GeditWindow        *window)
 {
 	GList *pl;
 
 	gedit_debug (DEBUG_PLUGINS);
 
+	g_return_if_fail (GEDIT_IS_PLUGINS_ENGINE (engine));
 	g_return_if_fail (GEDIT_IS_WINDOW (window));
 
-	if (new_window)
-		reactivate_all (engine, window);
-
-	/* updated ui of all the plugins that implement update_ui */
+	/* call update_ui for all active plugins */
 	for (pl = engine->priv->plugin_list; pl; pl = pl->next)
 	{
 		GeditPluginInfo *info = (GeditPluginInfo*)pl->data;
 
-		if (!info->available || !info->active)
+		if (!gedit_plugin_info_is_active (info))
 			continue;
 			
 	       	gedit_debug_message (DEBUG_PLUGINS, "Updating UI of %s", info->name);
-		
 		gedit_plugin_update_ui (info->plugin, window);
 	}
 }
@@ -633,16 +864,16 @@
 	{
 		GeditPluginInfo *info = (GeditPluginInfo*)pl->data;
 
-		if (!info->available)
+		if (!gedit_plugin_info_is_available (info))
 			continue;
 
 		to_activate = (g_slist_find_custom (active_plugins,
-						    info->module_name,
+						    gedit_plugin_info_get_module_name (info),
 						    (GCompareFunc)strcmp) != NULL);
 
-		if (!info->active && to_activate)
+		if (!gedit_plugin_info_is_active (info) && to_activate)
 			g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
-		else if (info->active && !to_activate)
+		else if (gedit_plugin_info_is_active (info) && !to_activate)
 			g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
 	}
 

Modified: trunk/gedit/gedit-plugins-engine.h
==============================================================================
--- trunk/gedit/gedit-plugins-engine.h	(original)
+++ trunk/gedit/gedit-plugins-engine.h	Tue Nov 25 22:00:16 2008
@@ -78,6 +78,8 @@
 GeditPluginInfo	*gedit_plugins_engine_get_plugin_info	(GeditPluginsEngine *engine,
 							 const gchar        *name);
 
+
+/* plugin load and unloading (overall, for all windows) */
 gboolean 	 gedit_plugins_engine_activate_plugin 	(GeditPluginsEngine *engine,
 							 GeditPluginInfo    *info);
 gboolean 	 gedit_plugins_engine_deactivate_plugin	(GeditPluginsEngine *engine,
@@ -87,13 +89,13 @@
 							 GeditPluginInfo    *info,
 							 GtkWindow          *parent);
 
-/* 
- * new_window == TRUE if this function is called because a new top window
- * has been created
- */
-void		 gedit_plugins_engine_update_plugins_ui (GeditPluginsEngine *engine,
-							 GeditWindow        *window, 
-							 gboolean            new_window);
+/* plugin activation/deactivation per window, private to GeditWindow */
+void 		 gedit_plugins_engine_activate_plugins   (GeditPluginsEngine *engine,
+							  GeditWindow        *window);
+void 		 gedit_plugins_engine_deactivate_plugins (GeditPluginsEngine *engine,
+							  GeditWindow        *window);
+void		 gedit_plugins_engine_update_plugins_ui  (GeditPluginsEngine *engine,
+							  GeditWindow        *window);
 
 G_END_DECLS
 

Modified: trunk/gedit/gedit-window-private.h
==============================================================================
--- trunk/gedit/gedit-window-private.h	(original)
+++ trunk/gedit/gedit-window-private.h	Tue Nov 25 22:00:16 2008
@@ -90,6 +90,7 @@
 
 	gboolean	removing_tabs : 1;
 	gboolean	destroy_has_run : 1;
+	gboolean	dispose_has_run : 1;
 };
 
 G_END_DECLS

Modified: trunk/gedit/gedit-window.c
==============================================================================
--- trunk/gedit/gedit-window.c	(original)
+++ trunk/gedit/gedit-window.c	Tue Nov 25 22:00:16 2008
@@ -116,6 +116,8 @@
 {
 	GeditWindow *window;
 
+	gedit_debug (DEBUG_WINDOW);
+
 	window = GEDIT_WINDOW (object);
 
 	/* First of all, force collection so that plugins
@@ -123,6 +125,14 @@
 	 */
 	gedit_plugins_engine_garbage_collect (gedit_plugins_engine_get_default ());
 
+	/* make sure to deactivate plugins for this window, but only once */
+	if (!window->priv->dispose_has_run)
+	{
+		gedit_plugins_engine_deactivate_plugins (gedit_plugins_engine_get_default (),
+					                  window);
+		window->priv->dispose_has_run = TRUE;
+	}
+
 	if (window->priv->recents_handler_id != 0)
 	{
 		GtkRecentManager *recent_manager;
@@ -144,7 +154,7 @@
 		g_object_unref (window->priv->window_group);
 		window->priv->window_group = NULL;
 	}
-
+	
 	/* Now that there have broken some reference loops,
 	 * force collection again.
 	 */
@@ -158,6 +168,8 @@
 {
 	GeditWindow *window; 
 
+	gedit_debug (DEBUG_WINDOW);
+
 	window = GEDIT_WINDOW (object);
 
 	g_free (window->priv->default_path);
@@ -785,7 +797,7 @@
 	update_next_prev_doc_sensitivity (window, tab);
 
 	gedit_plugins_engine_update_plugins_ui (gedit_plugins_engine_get_default (),
-						window, FALSE);
+						 window);
 }
 
 static void
@@ -2254,7 +2266,7 @@
 	g_free (tip);
 
 	gedit_plugins_engine_update_plugins_ui (gedit_plugins_engine_get_default (),
-						window, FALSE);
+						 window);
 }
 
 static GeditWindow *
@@ -2459,7 +2471,7 @@
                   GeditWindow *window)
 {
 	gedit_plugins_engine_update_plugins_ui (gedit_plugins_engine_get_default (),
-						window, FALSE);
+						 window);
 }
 
 static void
@@ -2642,7 +2654,7 @@
 		gtk_action_set_sensitive (action, FALSE);
 
 		gedit_plugins_engine_update_plugins_ui (gedit_plugins_engine_get_default (),
-							window, FALSE);
+							 window);
 	}
 
 	if (window->priv->num_tabs <= 1)
@@ -3064,6 +3076,7 @@
 	window->priv->removing_tabs = FALSE;
 	window->priv->state = GEDIT_WINDOW_STATE_NORMAL;
 	window->priv->destroy_has_run = FALSE;
+	window->priv->dispose_has_run = FALSE;
 
 	window->priv->window_group = gtk_window_group_new ();
 	gtk_window_group_add_window (window->priv->window_group, GTK_WINDOW (window));
@@ -3202,8 +3215,9 @@
 			  NULL);
 
 	gedit_debug_message (DEBUG_WINDOW, "Update plugins ui");
-	gedit_plugins_engine_update_plugins_ui (gedit_plugins_engine_get_default (),
-						window, TRUE);
+	
+	gedit_plugins_engine_activate_plugins (gedit_plugins_engine_get_default (),
+					        window);
 
 	/* set visibility of panes.
 	 * This needs to be done after plugins activatation */

Modified: trunk/plugin-loaders/python/bindings/Makefile.am
==============================================================================
--- /branches/new_plugins/plugin-loaders/python/bindings/Makefile.am	(original)
+++ trunk/plugin-loaders/python/bindings/Makefile.am	Tue Nov 25 22:00:16 2008
@@ -33,7 +33,7 @@
 $(top_builddir)/gedit/gedit-enum-types.h:
 	cd $(top_builddir)/gedit && $(MAKE) gedit-enum-types.h
 
-gedit.c: gedit.defs gedit.override geditplugin.override geditmessage.override $(top_builddir)/gedit/gedit-enum-types.h
+gedit.c: gedit.defs gedit.override geditplugin.override $(top_builddir)/gedit/gedit-enum-types.h
 	( cd $(srcdir) && $(PYGTK_CODEGEN) \
 		--register $(PYGTK_DEFSDIR)/pango-types.defs \
 		--register $(PYGTK_DEFSDIR)/gdk-types.defs \
@@ -67,9 +67,7 @@
 	gedit/gedit-window.h 		\
 	gedit/gedit-help.h		\
 	gedit/gedit-debug.h		\
-	gedit/gedit-language-manager.h	\
-	gedit/gedit-message-bus.h	\
-	gedit/gedit-message.h
+	gedit/gedit-language-manager.h
 
 BINDING_UTILS_HEADERS_SRCDIR_IN = \
 	gedit/gedit-utils.h

Modified: trunk/plugin-loaders/python/bindings/gedit.defs
==============================================================================
--- /branches/new_plugins/plugin-loaders/python/bindings/gedit.defs	(original)
+++ trunk/plugin-loaders/python/bindings/gedit.defs	Tue Nov 25 22:00:16 2008
@@ -14,20 +14,6 @@
   (gtype-id "GEDIT_TYPE_DOCUMENT")
 )
 
-(define-object Message
-  (in-module "Gedit")
-  (parent "GObject")
-  (c-name "GeditMessage")
-  (gtype-id "GEDIT_TYPE_MESSAGE")
-)
-
-(define-object MessageBus
-  (in-module "Gedit")
-  (parent "GObject")
-  (c-name "GeditMessageBus")
-  (gtype-id "GEDIT_TYPE_MESSAGE_BUS")
-)
-
 (define-object Panel
   (in-module "Gedit")
   (parent "GtkVBox")
@@ -1005,271 +991,6 @@
   )
 )
 
-
-;; From gedit-message-bus.h
-
-(define-function gedit_message_bus_get_type
-  (c-name "gedit_message_bus_get_type")
-  (return-type "GType")
-)
-
-(define-function message_bus_get_default
-  (c-name "gedit_message_bus_get_default")
-  (return-type "GeditMessageBus*")
-)
-
-(define-method connect
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_connect")
-  (return-type "guint")
-  (parameters
-    '("const-gchar*" "domain")
-    '("const-gchar*" "name")
-    '("GeditMessageCallback" "callback")
-    '("gpointer" "userdata")
-  )
-)
-
-(define-method disconnect
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_disconnect")
-  (return-type "none")
-  (parameters
-    '("guint" "id")
-  )
-)
-
-(define-method disconnect_by_func
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_disconnect_by_func")
-  (return-type "none")
-  (parameters
-    '("const-gchar*" "domain")
-    '("const-gchar*" "name")
-    '("GeditMessageCallback" "callback")
-    '("gpointer" "userdata")
-  )
-)
-
-(define-method block
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_block")
-  (return-type "none")
-  (parameters
-    '("guint" "id")
-  )
-)
-
-(define-method block_by_func
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_block_by_func")
-  (return-type "none")
-  (parameters
-    '("const-gchar*" "domain")
-    '("const-gchar*" "name")
-    '("GeditMessageCallback" "callback")
-    '("gpointer" "userdata")
-  )
-)
-
-(define-method unblock
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_unblock")
-  (return-type "none")
-  (parameters
-    '("guint" "id")
-  )
-)
-
-(define-method unblock_by_func
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_unblock_by_func")
-  (return-type "none")
-  (parameters
-    '("const-gchar*" "domain")
-    '("const-gchar*" "name")
-    '("GeditMessageCallback" "callback")
-    '("gpointer" "userdata")
-  )
-)
-
-(define-method send_message
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_send_message")
-  (return-type "none")
-  (parameters
-    '("GeditMessage*" "message")
-  )
-)
-
-(define-method send_message_sync
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_send_message_sync")
-  (return-type "none")
-  (parameters
-    '("GeditMessage*" "message")
-  )
-)
-
-(define-method send
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_send")
-  (return-type "none")
-  (parameters
-    '("const-gchar*" "domain")
-    '("const-gchar*" "name")
-  )
-  (varargs #t)
-)
-
-(define-method send_sync
-  (of-object "GeditMessageBus")
-  (c-name "gedit_message_bus_send_sync")
-  (return-type "GeditMessage*")
-  (parameters
-    '("const-gchar*" "domain")
-    '("const-gchar*" "name")
-  )
-  (varargs #t)
-)
-
-
-
-;; From gedit-message.h
-
-(define-function gedit_message_get_type
-  (c-name "gedit_message_get_type")
-  (return-type "GType")
-)
-
-(define-function gedit_message_new
-  (c-name "gedit_message_new")
-  (is-constructor-of "GeditMessage")
-  (return-type "GeditMessage*")
-  (parameters
-    '("const-gchar*" "domain")
-    '("const-gchar*" "name")
-  )
-  (varargs #t)
-)
-
-(define-function gedit_message_new_valist
-  (c-name "gedit_message_new_valist")
-  (return-type "GeditMessage*")
-  (parameters
-    '("const-gchar*" "domain")
-    '("const-gchar*" "name")
-    '("va_list" "var_args")
-  )
-)
-
-(define-method set_types
-  (of-object "GeditMessage")
-  (c-name "gedit_message_set_types")
-  (return-type "none")
-  (parameters
-    '("const-gchar**" "keys")
-    '("GType*" "types")
-    '("gint" "n_types")
-  )
-)
-
-(define-method get_domain
-  (of-object "GeditMessage")
-  (c-name "gedit_message_get_domain")
-  (return-type "const-gchar*")
-)
-
-(define-method get_name
-  (of-object "GeditMessage")
-  (c-name "gedit_message_get_name")
-  (return-type "const-gchar*")
-)
-
-(define-method get
-  (of-object "GeditMessage")
-  (c-name "gedit_message_get")
-  (return-type "none")
-  (parameters
-  )
-  (varargs #t)
-)
-
-(define-method get_valist
-  (of-object "GeditMessage")
-  (c-name "gedit_message_get_valist")
-  (return-type "none")
-  (parameters
-    '("va_list" "var_args")
-  )
-)
-
-(define-method get_value
-  (of-object "GeditMessage")
-  (c-name "gedit_message_get_value")
-  (return-type "none")
-  (parameters
-    '("const-gchar*" "key")
-    '("GValue*" "value")
-  )
-)
-
-(define-method set
-  (of-object "GeditMessage")
-  (c-name "gedit_message_set")
-  (return-type "none")
-  (parameters
-  )
-  (varargs #t)
-)
-
-(define-method set_valist
-  (of-object "GeditMessage")
-  (c-name "gedit_message_set_valist")
-  (return-type "none")
-  (parameters
-    '("va_list" "var_args")
-  )
-)
-
-(define-method set_value
-  (of-object "GeditMessage")
-  (c-name "gedit_message_set_value")
-  (return-type "none")
-  (parameters
-    '("const-gchar*" "key")
-    '("GValue*" "value")
-  )
-)
-
-(define-method set_valuesv
-  (of-object "GeditMessage")
-  (c-name "gedit_message_set_valuesv")
-  (return-type "none")
-  (parameters
-    '("const-gchar**" "keys")
-    '("GValue*" "values")
-    '("gint" "n_values")
-  )
-)
-
-(define-method has_key
-  (of-object "GeditMessage")
-  (c-name "gedit_message_has_key")
-  (return-type "gboolean")
-  (parameters
-    '("const-gchar*" "key")
-  )
-)
-
-(define-method get_keys
-  (of-object "GeditMessage")
-  (c-name "gedit_message_get_keys")
-  (return-type "gchar**")
-  (parameters
-  )
-)
-
 ;; From ../../gedit/gedit-debug.h
 
 (define-function debug

Modified: trunk/plugin-loaders/python/bindings/gedit.override
==============================================================================
--- /branches/new_plugins/plugin-loaders/python/bindings/gedit.override	(original)
+++ trunk/plugin-loaders/python/bindings/gedit.override	Tue Nov 25 22:00:16 2008
@@ -61,7 +61,6 @@
 }
 %%
 include
-  geditmessage.override
   geditplugin.override
 %%
 modulename gedit 



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