SF.net SVN: geany:[3074] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Mon Oct 13 12:38:34 UTC 2008


Revision: 3074
          http://geany.svn.sourceforge.net/geany/?rev=3074&view=rev
Author:   ntrel
Date:     2008-10-13 12:38:32 +0000 (Mon, 13 Oct 2008)

Log Message:
-----------
- API changes:
Replace p_ui->get_toolbar_insert_position() with
p_plugin->add_toolbar_item(), which also adds a separator when the
first item is added.
Add 'GeanyPlugin *geany_plugin' plugin symbol, partly to replace
plugin_info (now deprecated), mainly to identify a plugin and hold
private implementation fields for plugin utility functions.
(plugin_info will be removed after the 0.15 release.)
- Code changes:
Add ui_auto_separator_add_ref() to hide separator-like widgets when
their visible group elements are hidden or destroyed.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/doc/Doxyfile.in
    trunk/doc/pluginsymbols.c
    trunk/plugins/demoplugin.c
    trunk/plugins/pluginmacros.h
    trunk/src/plugindata.h
    trunk/src/plugins.c
    trunk/src/ui_utils.c
    trunk/src/ui_utils.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/ChangeLog	2008-10-13 12:38:32 UTC (rev 3074)
@@ -1,3 +1,21 @@
+2008-10-13  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/ui_utils.h, src/plugindata.h, src/plugins.c, src/ui_utils.c,
+   doc/Doxyfile.in, doc/pluginsymbols.c, plugins/demoplugin.c,
+   plugins/pluginmacros.h:
+ - API changes:
+   Replace p_ui->get_toolbar_insert_position() with
+   p_plugin->add_toolbar_item(), which also adds a separator when the
+   first item is added.
+   Add 'GeanyPlugin *geany_plugin' plugin symbol, partly to replace
+   plugin_info (now deprecated), mainly to identify a plugin and hold
+   private implementation fields for plugin utility functions.
+   (plugin_info will be removed after the 0.15 release.)
+ - Code changes:
+   Add ui_auto_separator_add_ref() to hide separator-like widgets when
+   their visible group elements are hidden or destroyed.
+
+
 2008-10-12  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
 
  * src/highlighting.c:

Modified: trunk/doc/Doxyfile.in
===================================================================
--- trunk/doc/Doxyfile.in	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/doc/Doxyfile.in	2008-10-13 12:38:32 UTC (rev 3074)
@@ -226,7 +226,7 @@
 INCLUDE_PATH           =
 INCLUDE_FILE_PATTERNS  =
 # make G_GNUC_PRINTF a no-op unless doxygen would ignore functions with varargs
-PREDEFINED             = "G_GNUC_PRINTF(x,y)=" GEANY_DISABLE_DEPRECATED
+PREDEFINED             = "G_GNUC_PRINTF(x,y)=" GEANY_DISABLE_DEPRECATED HAVE_PLUGINS
 EXPAND_AS_DEFINED      =
 SKIP_FUNCTION_MACROS   = NO
 #---------------------------------------------------------------------------

Modified: trunk/doc/pluginsymbols.c
===================================================================
--- trunk/doc/pluginsymbols.c	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/doc/pluginsymbols.c	2008-10-13 12:38:32 UTC (rev 3074)
@@ -43,22 +43,26 @@
  * @param info The data struct which should be initialized by this function. */
 void plugin_set_info(PluginInfo *info);
 
-/** Basic information about a plugin, which is set in plugin_set_info(). */
-const PluginInfo* plugin_info;
+/** @deprecated Use geany_plugin->info instead.
+ * Basic information about a plugin, which is set in plugin_set_info(). */
+const PluginInfo *plugin_info;
 
+/** Basic information for the plugin and identification. */
+const GeanyPlugin *geany_plugin;
+
 /** Geany owned data pointers.
  * Example: @c assert(geany_data->app->configdir != NULL); */
-const GeanyData* geany_data;
+const GeanyData *geany_data;
 
 /** Geany owned function pointers, split into groups.
  * Example: @c geany_functions->p_document->new_file(NULL, NULL, NULL);
  *
  * Note: Usually plugins would use the pluginmacros.h file and just call:
  * @c p_document->new_file(NULL, NULL, NULL); */
-const GeanyFunctions* geany_functions;
+const GeanyFunctions *geany_functions;
 
 /** Plugin owned fields, including flags. */
-PluginFields* plugin_fields;
+PluginFields *plugin_fields;
 
 /** An array for connecting GeanyObject events, which should be terminated with
  * @c {NULL, NULL, FALSE, NULL}. See @link signals Signal documentation @endlink. */

Modified: trunk/plugins/demoplugin.c
===================================================================
--- trunk/plugins/demoplugin.c	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/plugins/demoplugin.c	2008-10-13 12:38:32 UTC (rev 3074)
@@ -44,15 +44,15 @@
 
 
 /* These items are set by Geany before plugin_init() is called. */
-PluginInfo		*plugin_info;
+GeanyPlugin		*geany_plugin;
 PluginFields	*plugin_fields;
 GeanyData		*geany_data;
 GeanyFunctions	*geany_functions;
 
 
-/* Check that Geany supports plugin API version 7 or later, and check
+/* Check that the running Geany supports the plugin API used below, and check
  * for binary compatibility. */
-PLUGIN_VERSION_CHECK(64)
+PLUGIN_VERSION_CHECK(99)
 
 /* All plugins must set name, description, version and author. */
 PLUGIN_SET_INFO(_("Demo"), _("Example plugin."), VERSION, _("The Geany developer team"))
@@ -75,7 +75,7 @@
 		GTK_BUTTONS_OK,
 		"%s", welcome_text);
 	gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
-		_("(From the %s plugin)"), plugin_info->name);
+		_("(From the %s plugin)"), geany_plugin->info->name);
 
 	gtk_dialog_run(GTK_DIALOG(dialog));
 	gtk_widget_destroy(dialog);

Modified: trunk/plugins/pluginmacros.h
===================================================================
--- trunk/plugins/pluginmacros.h	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/plugins/pluginmacros.h	2008-10-13 12:38:32 UTC (rev 3074)
@@ -52,6 +52,7 @@
 #define p_main			geany_functions->p_main			/**< See main.h */
 #define p_msgwindow		geany_functions->p_msgwindow	/**< See msgwindow.h */
 #define p_navqueue		geany_functions->p_navqueue		/**< See navqueue.h */
+#define p_plugin		geany_functions->p_plugin		/**< See plugins.c */
 #define p_sci			geany_functions->p_sci			/**< See sciwrappers.h */
 #define p_search		geany_functions->p_search		/**< See search.h */
 #define p_support		geany_functions->p_support		/**< See support.h */

Modified: trunk/src/plugindata.h
===================================================================
--- trunk/src/plugindata.h	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/src/plugindata.h	2008-10-13 12:38:32 UTC (rev 3074)
@@ -41,13 +41,13 @@
 enum {
 	/** The Application Programming Interface (API) version, incremented
 	 * whenever any plugin data types are modified or appended to. */
-	GEANY_API_VERSION = 98,
+	GEANY_API_VERSION = 99,
 
 	/** The Application Binary Interface (ABI) version, incremented whenever
 	 * existing fields in the plugin data types have to be changed or reordered. */
 	/* This should usually stay the same if fields are only appended, assuming only pointers to
 	 * structs and not structs themselves are declared by plugins. */
-	GEANY_ABI_VERSION = 46
+	GEANY_ABI_VERSION = 47
 };
 
 /** Check the plugin can be loaded by Geany.
@@ -65,8 +65,8 @@
 	}
 
 
-/** Plugin info structure to hold basic information about a plugin.
- * Should usually be set with PLUGIN_SET_INFO(). */
+/** Basic information about a plugin available to Geany without loading the plugin.
+ * The fields are set in plugin_set_info(), usually with the PLUGIN_SET_INFO() macro. */
 typedef struct PluginInfo
 {
 	/** The name of the plugin. */
@@ -80,6 +80,17 @@
 }
 PluginInfo;
 
+
+/** Basic information for the plugin and identification. */
+typedef struct GeanyPlugin
+{
+	PluginInfo	*info;	/**< Fields set in plugin_set_info(). */
+
+	struct GeanyPluginPrivate *priv;	/* private */
+}
+GeanyPlugin;
+
+
 /** Set the plugin name and some other basic information about a plugin.
  * This declares a function, so you can use the _() translation macro for arguments.
  *
@@ -198,6 +209,7 @@
 	struct NavQueueFuncs        *p_navqueue;		/**< See navqueue.h */
 	struct EditorFuncs        	*p_editor;			/**< See editor.h */
 	struct MainFuncs        	*p_main;			/**< See main.h */
+	struct PluginFuncs        	*p_plugin;			/**< See plugins.c */
 }
 GeanyFunctions;
 
@@ -336,7 +348,6 @@
 	void		(*table_add_row) (GtkTable *table, gint row, ...) G_GNUC_NULL_TERMINATED;
 	GtkWidget*	(*path_box_new) (const gchar *title, GtkFileChooserAction action, GtkEntry *entry);
 	GtkWidget*	(*button_new_with_image) (const gchar *stock_id, const gchar *text);
-	gint		(*get_toolbar_insert_position) (void);
 }
 UIUtilsFuncs;
 
@@ -466,6 +477,14 @@
 EditorFuncs;
 
 
+/* See plugins.c */
+typedef struct PluginFuncs
+{
+	void	(*add_toolbar_item)(GeanyPlugin *plugin, GtkToolItem *item);
+}
+PluginFuncs;
+
+
 /* Deprecated aliases */
 #ifndef GEANY_DISABLE_DEPRECATED
 

Modified: trunk/src/plugins.c
===================================================================
--- trunk/src/plugins.c	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/src/plugins.c	2008-10-13 12:38:32 UTC (rev 3074)
@@ -23,6 +23,8 @@
  */
 
 /* Code to manage, load and unload plugins. */
+/** @file plugins.c
+ * Plugin utility functions. */
 
 #include "geany.h"
 
@@ -65,12 +67,22 @@
 #endif
 
 
+typedef struct GeanyPluginPrivate
+{
+	GeanyAutoSeparator	toolbar_separator;
+}
+GeanyPluginPrivate;
+
+
 typedef struct Plugin
 {
 	GModule 	*module;
 	gchar		*filename;				/* plugin filename (/path/libname.so) */
 	PluginInfo		info;				/* plugin name, description, etc */
 	PluginFields	fields;
+	GeanyPlugin		public;				/* fields the plugin can read */
+	GeanyPluginPrivate	priv;			/* GeanyPlugin type private data */
+
 	gulong		*signal_ids;			/* signal IDs to disconnect when unloading */
 	gsize		signal_ids_len;
 	GeanyKeyGroup	*key_group;
@@ -93,7 +105,13 @@
 
 static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data);
 
+void plugin_add_toolbar_item(GeanyPlugin *plugin, GtkToolItem *item);
 
+
+static PluginFuncs plugin_funcs = {
+	&plugin_add_toolbar_item
+};
+
 static DocumentFuncs doc_funcs = {
 	&document_new_file,
 	&document_get_current,
@@ -185,7 +203,6 @@
 	&ui_table_add_row,
 	&ui_path_box_new,
 	&ui_button_new_with_image,
-	&ui_get_toolbar_insert_position
 };
 
 static DialogFuncs dialog_funcs = {
@@ -265,7 +282,8 @@
 	&filetype_funcs,
 	&navqueue_funcs,
 	&editor_funcs,
-	&main_funcs
+	&main_funcs,
+	&plugin_funcs
 };
 
 static GeanyData geany_data;
@@ -454,6 +472,7 @@
 static void
 plugin_init(Plugin *plugin)
 {
+	GeanyPlugin **p_geany_plugin;
 	PluginCallback *callbacks;
 	PluginInfo **p_info;
 	PluginFields **plugin_fields;
@@ -461,6 +480,9 @@
 	GeanyFunctions **p_geany_functions;
 
 	/* set these symbols before plugin_init() is called */
+	g_module_symbol(plugin->module, "geany_plugin", (void *) &p_geany_plugin);
+	if (p_geany_plugin)
+		*p_geany_plugin = &plugin->public;
 	g_module_symbol(plugin->module, "plugin_info", (void *) &p_info);
 	if (p_info)
 		*p_info = &plugin->info;
@@ -608,6 +630,8 @@
 
 	plugin->filename = g_strdup(fname);
 	plugin->module = module;
+	plugin->public.info = &plugin->info;
+	plugin->public.priv = &plugin->priv;
 
 	if (init_plugin)
 		plugin_init(plugin);
@@ -641,6 +665,7 @@
 static void
 plugin_unload(Plugin *plugin)
 {
+	GtkWidget *widget;
 
 	if (is_active_plugin(plugin) && plugin->cleanup)
 		plugin->cleanup();
@@ -650,6 +675,10 @@
 	if (plugin->key_group)
 		g_ptr_array_remove_fast(keybinding_groups, plugin->key_group);
 
+	widget = plugin->priv.toolbar_separator.widget;
+	if (widget)
+		gtk_widget_destroy(widget);
+
 	active_plugin_list = g_list_remove(active_plugin_list, plugin);
 	geany_debug("Unloaded: %s", plugin->filename);
 }
@@ -1194,4 +1223,44 @@
 	gtk_widget_show_all(pm_widgets.dialog);
 }
 
+
+/** Insert a toolbar item before the Quit button, or after the previous plugin toolbar item.
+ * A separator is added on the first call to this function, and will be shown when @a item is
+ * shown; hidden when @a item is hidden.
+ * @note You should still destroy @a item yourself, usually in @ref plugin_cleanup().
+ * @param plugin Must be @ref geany_plugin.
+ * @param item The item to add. */
+void plugin_add_toolbar_item(GeanyPlugin *plugin, GtkToolItem *item)
+{
+	GtkToolbar *toolbar = GTK_TOOLBAR(main_widgets.toolbar);
+	gint pos;
+	GeanyAutoSeparator *autosep;
+
+	g_return_if_fail(plugin);
+	autosep = &plugin->priv->toolbar_separator;
+
+	if (!autosep->widget)
+	{
+		GtkToolItem *sep;
+
+		pos = ui_get_toolbar_insert_position();
+		/* pos should be valid even if the quit btn is hidden */
+		g_return_if_fail(pos >= 0);
+		gtk_toolbar_insert(toolbar, item, pos);
+
+		sep = gtk_separator_tool_item_new();
+		gtk_toolbar_insert(toolbar, sep, pos + 1);
+		autosep->widget = GTK_WIDGET(sep);
+	}
+	else
+	{
+		pos = gtk_toolbar_get_item_index(toolbar, GTK_TOOL_ITEM(autosep->widget));
+		g_return_if_fail(pos >= 0);
+		gtk_toolbar_insert(toolbar, item, pos);
+	}
+	/* hide the separator widget if there are no toolbar items showing for the plugin */
+	ui_auto_separator_add_ref(autosep, GTK_WIDGET(item));
+}
+
+
 #endif

Modified: trunk/src/ui_utils.c
===================================================================
--- trunk/src/ui_utils.c	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/src/ui_utils.c	2008-10-13 12:38:32 UTC (rev 3074)
@@ -1531,7 +1531,7 @@
 }
 
 
-/** Returns the position for adding new toolbar items. The returned position can be used
+/*  Returns the position for adding new toolbar items. The returned position can be used
  *  to add new toolbar items with @c gtk_toolbar_insert(). The toolbar object can be accessed
  *  with @a geany->main_widgets->toolbar.
  *  The position is always the last one before the Quit button (if it is shown).
@@ -1550,3 +1550,59 @@
 	return pos;
 }
 
+
+static void auto_separator_update(GeanyAutoSeparator *autosep)
+{
+	g_return_if_fail(autosep->ref_count >= 0);
+
+	if (autosep->widget)
+		ui_widget_show_hide(autosep->widget, autosep->ref_count > 0);
+}
+
+
+static void on_auto_separator_item_show_hide(GtkWidget *widget, gpointer user_data)
+{
+	GeanyAutoSeparator *autosep = user_data;
+
+	if (GTK_WIDGET_VISIBLE(widget))
+		autosep->ref_count++;
+	else
+		autosep->ref_count--;
+
+	auto_separator_update(autosep);
+}
+
+
+static void on_auto_separator_item_destroy(GtkWidget *widget, gpointer user_data)
+{
+	GeanyAutoSeparator *autosep = user_data;
+
+	/* GTK_WIDGET_VISIBLE won't work now the widget is being destroyed,
+	 * so assume widget was visible */
+	autosep->ref_count--;
+	autosep->ref_count = MAX(autosep->ref_count, 0);
+	auto_separator_update(autosep);
+}
+
+
+/* Show the separator widget if @a item or another is visible. */
+/* Note: This would be neater taking a widget argument, setting a "visible-count"
+ * property, and using reference counting to keep the widget alive whilst its visible group
+ * is alive. */
+void ui_auto_separator_add_ref(GeanyAutoSeparator *autosep, GtkWidget *item)
+{
+	/* set widget ptr NULL when widget destroyed */
+	if (autosep->ref_count == 0)
+		g_signal_connect(autosep->widget, "destroy",
+			G_CALLBACK(gtk_widget_destroyed), &autosep->widget);
+
+	if (GTK_WIDGET_VISIBLE(item))
+	{
+		autosep->ref_count++;
+		auto_separator_update(autosep);
+	}
+	g_signal_connect(item, "show", G_CALLBACK(on_auto_separator_item_show_hide), autosep);
+	g_signal_connect(item, "hide", G_CALLBACK(on_auto_separator_item_show_hide), autosep);
+	g_signal_connect(item, "destroy", G_CALLBACK(on_auto_separator_item_destroy), autosep);
+}
+

Modified: trunk/src/ui_utils.h
===================================================================
--- trunk/src/ui_utils.h	2008-10-12 17:52:22 UTC (rev 3073)
+++ trunk/src/ui_utils.h	2008-10-13 12:38:32 UTC (rev 3074)
@@ -125,9 +125,17 @@
 extern UIWidgets ui_widgets;
 
 
-/* The following block of functions are more generic functions and closely related to
+/* The following block of types & functions are more generic and closely related to
  * certain GTK+ widgets. */
 
+typedef struct GeanyAutoSeparator
+{
+	GtkWidget	*widget;	/* e.g. GtkSeparatorToolItem, GtkSeparatorMenuItem */
+	gint		ref_count;	/* set to zero initially */
+}
+GeanyAutoSeparator;
+
+
 void ui_widget_show_hide(GtkWidget *widget, gboolean show);
 
 void ui_widget_modify_font_from_string(GtkWidget *wid, const gchar *str);
@@ -151,6 +159,8 @@
 
 void ui_table_add_row(GtkTable *table, gint row, ...) G_GNUC_NULL_TERMINATED;
 
+void ui_auto_separator_add_ref(GeanyAutoSeparator *autosep, GtkWidget *item);
+
 /* End of 'generic' functions */
 
 


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