SF.net SVN: geany: [1785] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Fri Aug 10 16:11:17 UTC 2007


Revision: 1785
          http://geany.svn.sourceforge.net/geany/?rev=1785&view=rev
Author:   ntrel
Date:     2007-08-10 09:11:17 -0700 (Fri, 10 Aug 2007)

Log Message:
-----------
Add plugin symbol geany_callbacks (see plugindata.h for details).
Add GeanyObject type with "document-new", "document-open",
"document-save" signals.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/Makefile.am
    trunk/src/document.c
    trunk/src/main.c
    trunk/src/plugindata.h
    trunk/src/plugins.c

Added Paths:
-----------
    trunk/src/geanyobject.c
    trunk/src/geanyobject.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-08-10 11:45:20 UTC (rev 1784)
+++ trunk/ChangeLog	2007-08-10 16:11:17 UTC (rev 1785)
@@ -8,6 +8,11 @@
    Update selected line(s) keybindings.
  * src/plugindata.h:
    Tidy up struct typedefs.
+ * src/geanyobject.c, src/plugindata.h, src/geanyobject.h,
+   src/document.c, src/plugins.c, src/main.c, src/Makefile.am:
+   Add plugin symbol geany_callbacks (see plugindata.h for details).
+   Add GeanyObject type with "document-new", "document-open",
+   "document-save" signals.
 
 
 2007-08-10  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2007-08-10 11:45:20 UTC (rev 1784)
+++ trunk/src/Makefile.am	2007-08-10 16:11:17 UTC (rev 1785)
@@ -15,6 +15,7 @@
 	editor.c editor.h \
 	encodings.c encodings.h \
 	filetypes.c filetypes.h \
+	geanyobject.c geanyobject.h \
 	highlighting.c highlighting.h \
 	interface.c interface.h \
 	keybindings.c keybindings.h \

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2007-08-10 11:45:20 UTC (rev 1784)
+++ trunk/src/document.c	2007-08-10 16:11:17 UTC (rev 1785)
@@ -67,6 +67,7 @@
 #include "build.h"
 #include "symbols.h"
 #include "callbacks.h"
+#include "geanyobject.h"
 
 
 /* dynamic array of document elements to hold all information of the notebook tabs */
@@ -459,7 +460,8 @@
 		ft = filetypes_detect_from_file(idx);
 
 	document_set_filetype(idx, ft);	// also clears taglist
-	if (ft == NULL) filetypes[GEANY_FILETYPES_ALL]->style_func_ptr(doc_list[idx].sci);
+	if (ft == NULL)
+		filetypes[GEANY_FILETYPES_ALL]->style_func_ptr(doc_list[idx].sci);
 	ui_set_window_title(idx);
 	build_menu_update(idx);
 
@@ -477,6 +479,11 @@
 	g_signal_connect((GtkWidget*) doc_list[idx].sci, "sci-notify",
 				G_CALLBACK(on_editor_notification), GINT_TO_POINTER(idx));
 
+	if (geany_object)
+	{
+		g_signal_emit_by_name(geany_object, "document-new", idx);
+	}
+
 	msgwin_status_add(_("New file \"%s\" opened."),
 		(doc_list[idx].file_name != NULL) ? doc_list[idx].file_name : GEANY_STRING_UNTITLED);
 
@@ -854,10 +861,13 @@
 	document_set_text_changed(idx);	// also updates tab state
 	ui_document_show_hide(idx);	// update the document menu
 
-
 	// finally add current file to recent files menu, but not the files from the last session
-	if (! app->opening_session_files) ui_add_recent_file(utf8_filename);
+	if (! app->opening_session_files)
+		ui_add_recent_file(utf8_filename);
 
+	if (! reload && geany_object)
+		g_signal_emit_by_name(geany_object, "document-open", idx);
+
 	if (reload)
 		msgwin_status_add(_("File %s reloaded."), utf8_filename);
 	else
@@ -1096,7 +1106,7 @@
 		 * timestamp can be ahead of time(NULL) */
 		document_update_timestamp(idx);
 
-		if (doc_list[idx].file_type == NULL || doc_list[idx].file_type->id == GEANY_FILETYPES_ALL)
+		if (FILETYPE_ID(doc_list[idx].file_type) == GEANY_FILETYPES_ALL)
 		{
 			doc_list[idx].file_type = filetypes_detect_from_file(idx);
 			filetypes_select_radio_item(doc_list[idx].file_type);
@@ -1111,8 +1121,11 @@
 #ifdef HAVE_VTE
 		vte_cwd(doc_list[idx].file_name, FALSE);
 #endif
-
 	}
+	if (geany_object)
+	{
+		g_signal_emit_by_name(geany_object, "document-save", idx);
+	}
 	return TRUE;
 }
 

Added: trunk/src/geanyobject.c
===================================================================
--- trunk/src/geanyobject.c	                        (rev 0)
+++ trunk/src/geanyobject.c	2007-08-10 16:11:17 UTC (rev 1785)
@@ -0,0 +1,152 @@
+/*
+ *      geanyobject.c - this file is part of Geany, a fast and lightweight IDE
+ *
+ *      Copyright 2007 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
+ *      Copyright 2007 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 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., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ *
+ * $Id$
+ */
+
+/* GObject used for connecting and emitting signals when certain events happen,
+ * e.g. opening a document.
+ * Mainly used for plugins - geany_object is created in plugins_init(). */
+
+#include "geany.h"
+#include "geanyobject.h"
+#include "plugindata.h"
+
+GObject	*geany_object;
+
+static guint geany_object_signals[GCB_MAX] = { 0 };
+
+
+typedef struct _GeanyObjectPrivate				GeanyObjectPrivate;
+
+#define GEANY_OBJECT_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+		GEANY_OBJECT_TYPE, GeanyObjectPrivate))
+
+struct _GeanyObjectPrivate
+{
+	/* add your private declarations here */
+};
+
+static void geany_object_class_init			(GeanyObjectClass *klass);
+static void geany_object_init				(GeanyObject *self);
+static void geany_object_finalize			(GObject *object);
+
+/* Local data */
+static GObjectClass *parent_class = NULL;
+
+
+GType geany_object_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(GeanyObjectClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)geany_object_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(GeanyObject),
+			0,
+			(GInstanceInitFunc)geany_object_init,
+			NULL
+		};
+
+		self_type = g_type_register_static(G_TYPE_OBJECT, "GeanyObject", &self_info, 0);	}
+
+	return self_type;
+}
+
+
+static void create_signals(GObjectClass *g_object_class)
+{
+	geany_object_signals[GCB_DOCUMENT_NEW] = g_signal_new (
+		"document-new",
+		G_OBJECT_CLASS_TYPE (g_object_class),
+		G_SIGNAL_RUN_FIRST,
+		G_STRUCT_OFFSET (GeanyObjectClass, document_new),
+		NULL, NULL,
+		gtk_marshal_NONE__INT,
+		G_TYPE_NONE, 1,
+		G_TYPE_INT);
+	geany_object_signals[GCB_DOCUMENT_OPEN] = g_signal_new (
+		"document-open",
+		G_OBJECT_CLASS_TYPE (g_object_class),
+		G_SIGNAL_RUN_FIRST,
+		G_STRUCT_OFFSET (GeanyObjectClass, document_open),
+		NULL, NULL,
+		gtk_marshal_NONE__INT,
+		G_TYPE_NONE, 1,
+		G_TYPE_INT);
+	geany_object_signals[GCB_DOCUMENT_SAVE] = g_signal_new (
+		"document-save",
+		G_OBJECT_CLASS_TYPE (g_object_class),
+		G_SIGNAL_RUN_FIRST,
+		G_STRUCT_OFFSET (GeanyObjectClass, document_save),
+		NULL, NULL,
+		gtk_marshal_NONE__INT,
+		G_TYPE_NONE, 1,
+		G_TYPE_INT);
+}
+
+
+static void geany_object_class_init(GeanyObjectClass *klass)
+{
+	GObjectClass *g_object_class;
+
+	g_object_class = G_OBJECT_CLASS(klass);
+
+	g_object_class->finalize = geany_object_finalize;
+
+	parent_class = (GObjectClass*)g_type_class_peek(G_TYPE_OBJECT);
+	g_type_class_add_private((gpointer)klass, sizeof(GeanyObjectPrivate));
+
+	create_signals(g_object_class);
+}
+
+
+static void geany_object_init(GeanyObject *self)
+{
+
+}
+
+
+GObject* geany_object_new(void)
+{
+	return (GObject*)g_object_new(GEANY_OBJECT_TYPE, NULL);
+}
+
+
+void geany_object_finalize(GObject *object)
+{
+	GeanyObject *self;
+
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(IS_GEANY_OBJECT(object));
+
+	self = GEANY_OBJECT(object);
+
+	if (G_OBJECT_CLASS(parent_class)->finalize)
+		(* G_OBJECT_CLASS(parent_class)->finalize)(object);
+}
+


Property changes on: trunk/src/geanyobject.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: trunk/src/geanyobject.h
===================================================================
--- trunk/src/geanyobject.h	                        (rev 0)
+++ trunk/src/geanyobject.h	2007-08-10 16:11:17 UTC (rev 1785)
@@ -0,0 +1,79 @@
+/*
+ *      geanyobject.h - this file is part of Geany, a fast and lightweight IDE
+ *
+ *      Copyright 2007 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
+ *      Copyright 2007 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 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., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ *
+ * $Id$
+ */
+
+
+#ifndef __GEANYOBJECT_H__
+#define __GEANYOBJECT_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+extern GObject *geany_object;
+
+typedef enum
+{
+	GCB_DOCUMENT_NEW,
+	GCB_DOCUMENT_OPEN,
+	GCB_DOCUMENT_SAVE,
+	GCB_MAX
+} GeanyCallbackId;
+
+
+#define GEANY_OBJECT_TYPE				(geany_object_get_type())
+#define GEANY_OBJECT(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+		GEANY_OBJECT_TYPE, GeanyObject))
+#define GEANY_OBJECT_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+		GEANY_OBJECT_TYPE, GeanyObjectClass))
+#define IS_GEANY_OBJECT(obj)				(G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+		GEANY_OBJECT_TYPE))
+#define IS_GEANY_OBJECT_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE((klass),\
+		GEANY_OBJECT_TYPE))
+
+typedef struct _GeanyObject				GeanyObject;
+typedef struct _GeanyObjectClass			GeanyObjectClass;
+
+struct _GeanyObject
+{
+	GObject parent;
+	/* add your public declarations here */
+};
+
+struct SCNotification;
+
+struct _GeanyObjectClass
+{
+	GObjectClass parent_class;
+
+	void (*document_new)(gint idx);
+	void (*document_open)(gint idx);
+	void (*document_save)(gint idx);
+};
+
+GType		geany_object_get_type	(void);
+GObject*	geany_object_new			(void);
+
+G_END_DECLS
+
+#endif /* __GEANYOBJECT_H__ */


Property changes on: trunk/src/geanyobject.h
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2007-08-10 11:45:20 UTC (rev 1784)
+++ trunk/src/main.c	2007-08-10 16:11:17 UTC (rev 1785)
@@ -701,6 +701,12 @@
 	// apply all configuration options
 	apply_settings();
 
+#ifdef HAVE_PLUGINS
+	// load any enabled plugins before we open any documents
+	if (! no_plugins)
+		plugins_init();
+#endif
+
 	// load any command line files or session files
 	app->opening_session_files = TRUE;
 	if (! open_cl_files(argc, argv))
@@ -720,7 +726,8 @@
 	app->opening_session_files = FALSE;
 
 	// open a new file if no other file was opened
-	if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)) == 0)	document_new_file(NULL, NULL);
+	if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)) == 0)
+		document_new_file(NULL, NULL);
 
 	ui_document_buttons_update();
 	ui_save_buttons_toggle(FALSE);
@@ -743,12 +750,6 @@
 	}
 #endif
 
-#ifdef HAVE_PLUGINS
-	// load any enabled plugins just before we draw the main window
-	if (! no_plugins)
-		plugins_init();
-#endif
-
 	// finally realize the window to show the user what we have done
 	gtk_widget_show(app->window);
 	app->main_window_realized = TRUE;

Modified: trunk/src/plugindata.h
===================================================================
--- trunk/src/plugindata.h	2007-08-10 11:45:20 UTC (rev 1784)
+++ trunk/src/plugindata.h	2007-08-10 16:11:17 UTC (rev 1785)
@@ -40,6 +40,10 @@
  * PluginFields* plugin_fields
  * 	Plugin owned fields, including flags.
  *
+ * GeanyCallback geany_callbacks[]
+ * 	An array for connecting GeanyObject events, which should be terminated with
+ * 	{NULL, NULL, FALSE, NULL}. See signals below.
+ *
  * void init(GeanyData *data)
  * 	Called after loading the plugin. data is the same as geany_data.
  *
@@ -48,10 +52,23 @@
  * 	everything done in init() - e.g. destroy menu items, free memory.
  */
 
+/**
+ * Signals:
+ *
+ * "document-new"
+ * 	Sent when a new document is created.
+ *
+ * "document-open"
+ * 	Sent when a file is opened.
+ *
+ * "document-save"
+ * 	Sent when a file is saved.
+ */
 
+
 /* The API version should be incremented whenever any plugin data types below are
  * modified. */
-static const gint api_version = 8;
+static const gint api_version = 9;
 
 /* The ABI version should be incremented whenever existing fields in the plugin
  * data types below have to be changed or reordered. It should stay the same if fields
@@ -212,4 +229,14 @@
 }
 SupportFuncs;
 
+
+typedef struct GeanyCallback
+{
+	gchar		*signal_name;
+	GCallback	callback;
+	gboolean	after;
+	gpointer	user_data;
+}
+GeanyCallback;
+
 #endif

Modified: trunk/src/plugins.c
===================================================================
--- trunk/src/plugins.c	2007-08-10 11:45:20 UTC (rev 1784)
+++ trunk/src/plugins.c	2007-08-10 16:11:17 UTC (rev 1785)
@@ -46,6 +46,7 @@
 #include "sciwrappers.h"
 #include "ui_utils.h"
 #include "editor.h"
+#include "geanyobject.h"
 
 #ifdef G_OS_WIN32
 # define PLUGIN_EXT "dll"
@@ -211,6 +212,27 @@
 }
 
 
+// TODO: disconnect the callbacks when the plugin is unloaded.
+static void add_callbacks(GeanyCallback *callbacks)
+{
+	GeanyCallback *cb;
+	guint i = 0;
+
+	do
+	{
+		cb = &callbacks[i];
+		if (!cb->signal_name || !cb->callback)
+			break;
+
+		if (cb->after)
+			g_signal_connect_after(geany_object, cb->signal_name, cb->callback, cb->user_data);
+		else
+			g_signal_connect(geany_object, cb->signal_name, cb->callback, cb->user_data);
+		i++;
+	} while (TRUE);
+}
+
+
 static Plugin*
 plugin_new(const gchar *fname)
 {
@@ -219,6 +241,7 @@
 	PluginInfo* (*info)();
 	PluginFields **plugin_fields;
 	GeanyData **p_geany_data;
+	GeanyCallback *callbacks;
 
 	g_return_val_if_fail(fname, NULL);
 	g_return_val_if_fail(g_module_supported(), NULL);
@@ -293,6 +316,10 @@
 		gtk_widget_set_sensitive(plugin->fields.menu_item, enable);
 	}
 
+	g_module_symbol(module, "geany_callbacks", (void *) &callbacks);
+	if (callbacks)
+		add_callbacks(callbacks);
+
 	geany_debug("Loaded:   %s (%s)", fname,
 		NVL(plugin->info()->name, "<Unknown>"));
 	return plugin;
@@ -360,16 +387,10 @@
 #endif
 
 
-void plugins_init()
+static void load_plugin_paths()
 {
-	GtkWidget *widget;
 	gchar *path;
 
-	geany_data_init();
-
-	widget = gtk_separator_menu_item_new();
-	gtk_container_add(GTK_CONTAINER(geany_data.tools_menu), widget);
-
 	path = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "plugins", NULL);
 	// first load plugins in ~/.geany/plugins/, then in $prefix/lib/geany
 	load_plugins(path);
@@ -380,15 +401,32 @@
 #else
 	load_plugins(PACKAGE_LIB_DIR G_DIR_SEPARATOR_S "geany");
 #endif
-	if (g_list_length(plugin_list) > 0)
-		gtk_widget_show(widget);
 
 	g_free(path);
 }
 
 
+void plugins_init()
+{
+	GtkWidget *widget;
+
+	geany_data_init();
+	geany_object = geany_object_new();
+
+	widget = gtk_separator_menu_item_new();
+	gtk_container_add(GTK_CONTAINER(geany_data.tools_menu), widget);
+
+	load_plugin_paths();
+
+	if (g_list_length(plugin_list) > 0)
+		gtk_widget_show(widget);
+}
+
+
 void plugins_free()
 {
+	g_object_unref(geany_object);
+
 	if (plugin_list != NULL)
 	{
 		g_list_foreach(plugin_list, (GFunc) plugin_free, NULL);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list