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