[geany/geany] 7b2b96: Add plugin API functions to get/set document data
Matthew Brush
git-noreply at xxxxx
Fri Sep 2 02:46:20 UTC 2016
Branch: refs/heads/master
Author: Matthew Brush <matt at geany.org>
Committer: Matthew Brush <matt at geany.org>
Date: Fri, 02 Sep 2016 02:46:20 UTC
Commit: 7b2b9609e473bdc591010a68794df46dac52e1be
https://github.com/geany/geany/commit/7b2b9609e473bdc591010a68794df46dac52e1be
Log Message:
-----------
Add plugin API functions to get/set document data
TODO: add doc-comment annotations for GObject-Introspection
Modified Paths:
--------------
src/plugins.c
src/pluginutils.c
src/pluginutils.h
Modified: src/plugins.c
39 lines changed, 39 insertions(+), 0 deletions(-)
===================================================================
@@ -31,6 +31,7 @@
#include "app.h"
#include "dialogs.h"
+#include "documentprivate.h"
#include "encodings.h"
#include "geanyobject.h"
#include "geanywraplabel.h"
@@ -59,6 +60,14 @@
#include <string.h>
+typedef struct
+{
+ gchar *prefix;
+ GeanyDocument *document;
+}
+ForEachDocData;
+
+
GList *active_plugin_list = NULL; /* list of only actually loaded plugins, always valid */
@@ -850,6 +859,35 @@ static gboolean is_active_plugin(Plugin *plugin)
}
+static void remove_each_doc_data(GQuark key_id, gpointer data, gpointer user_data)
+{
+ const ForEachDocData *doc_data = user_data;
+ const gchar *key = g_quark_to_string(key_id);
+ if (g_str_has_prefix(key, doc_data->prefix))
+ g_datalist_remove_data(&doc_data->document->priv->data, key);
+}
+
+
+static void remove_doc_data(Plugin *plugin)
+{
+ ForEachDocData data;
+
+ data.prefix = g_strdup_printf("geany/plugins/%s/", plugin->public.info->name);
+
+ for (guint i = 0; i < documents_array->len; i++)
+ {
+ GeanyDocument *doc = documents_array->pdata[i];
+ if (DOC_VALID(doc))
+ {
+ data.document = doc;
+ g_datalist_foreach(&doc->priv->data, remove_each_doc_data, &data);
+ }
+ }
+
+ g_free(data.prefix);
+}
+
+
/* Clean up anything used by an active plugin */
static void
plugin_cleanup(Plugin *plugin)
@@ -859,6 +897,7 @@ plugin_cleanup(Plugin *plugin)
/* With geany_register_plugin cleanup is mandatory */
plugin->cbs.cleanup(&plugin->public, plugin->cb_data);
+ remove_doc_data(plugin);
remove_callbacks(plugin);
remove_sources(plugin);
Modified: src/pluginutils.c
153 lines changed, 153 insertions(+), 0 deletions(-)
===================================================================
@@ -44,6 +44,14 @@
#include "utils.h"
+typedef struct
+{
+ gpointer data;
+ GDestroyNotify free_func;
+}
+PluginDocDataProxy;
+
+
/** Inserts 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.
@@ -599,4 +607,149 @@ void geany_plugin_set_data(GeanyPlugin *plugin, gpointer pdata, GDestroyNotify f
}
+static void plugin_doc_data_proxy_free(gpointer pdata)
+{
+ PluginDocDataProxy *prox = pdata;
+ if (prox != NULL)
+ {
+ if (prox->free_func)
+ prox->free_func(prox->data);
+ g_slice_free(PluginDocDataProxy, prox);
+ }
+}
+
+
+/**
+ * Retrieve plugin-specific data attached to a document.
+ *
+ * @param plugin The plugin who attached the data.
+ * @param doc The document which the data was attached to.
+ * @param key The key name of the attached data.
+ *
+ * @return The attached data pointer or `NULL` if the key is not found
+ * for the given plugin.
+ *
+ * @since 1.29 (Plugin API 228)
+ * @see plugin_set_document_data plugin_set_document_data_full
+ */
+GEANY_API_SYMBOL
+gpointer plugin_get_document_data(struct GeanyPlugin *plugin,
+ struct GeanyDocument *doc, const gchar *key)
+{
+ gchar *real_key;
+ PluginDocDataProxy *data;
+
+ g_return_val_if_fail(plugin != NULL, NULL);
+ g_return_val_if_fail(doc != NULL, NULL);
+ g_return_val_if_fail(key != NULL && *key != '\0', NULL);
+
+ real_key = g_strdup_printf("geany/plugins/%s/%s", plugin->info->name, key);
+ data = document_get_data(doc, real_key);
+ g_free(real_key);
+
+ return (data != NULL) ? data->data : NULL;
+}
+
+
+/**
+ * Attach plugin-specific data to a document.
+ *
+ * @param plugin The plugin attaching data to the document.
+ * @param doc The document to attach the data to.
+ * @param key The key name for the data.
+ * @param data The pointer to attach to the document.
+ *
+ * @since 1.29 (Plugin API 228)
+ * @see plugin_get_document_data plugin_set_document_data_full
+ */
+GEANY_API_SYMBOL
+void plugin_set_document_data(struct GeanyPlugin *plugin, struct GeanyDocument *doc,
+ const gchar *key, gpointer data)
+{
+ plugin_set_document_data_full(plugin, doc, key, data, NULL);
+}
+
+
+/**
+ * Attach plugin-specific data and a free function to a document.
+ *
+ * This is useful for plugins who want to keep some additional data with
+ * the document and even have it auto-released appropriately (see below).
+ *
+ * This is a simple example showing how a plugin might use this to
+ * attach a string to each document and print it when the document is
+ * saved:
+ *
+ * @code
+ * void on_document_open(GObject *unused, GeanyDocument *doc, GeanyPlugin *plugin)
+ * {
+ * plugin_set_document_data_full(plugin, doc, "my-data",
+ * g_strdup("some-data"), g_free);
+ * }
+ *
+ * void on_document_save(GObject *unused, GeanyDocument *doc, GeanyPlugin *plugin)
+ * {
+ * const gchar *some_data = plugin_get_document_data(plugin, doc, "my-data");
+ * g_print("my-data: %s", some_data);
+ * }
+ *
+ * gboolean plugin_init(GeanyPlugin *plugin, gpointer unused)
+ * {
+ * plugin_signal_connect(plugin, NULL, "document-open", TRUE,
+ * G_CALLBACK(on_document_open), plugin);
+ * plugin_signal_connect(plugin, NULL, "document-new", TRUE,
+ * G_CALLBACK(on_document_open), plugin);
+ * plugin_signal_connect(plugin, NULL, "document-save", TRUE,
+ * G_CALLBACK(on_document_save), plugin);
+ * return TRUE;
+ * }
+ *
+ * void geany_load_module(GeanyPlugin *plugin)
+ * {
+ * // ...
+ * plugin->funcs->init = plugin_init;
+ * // ...
+ * }
+ * @endcode
+ *
+ * The @a free_func can be used to tie the lifetime of the data to that
+ * of the @a doc and/or the @a plugin. The @a free_func will be called
+ * in any of the following cases:
+ *
+ * - When a document is closed.
+ * - When the plugin is unloaded.
+ * - When the document data is set again using the same key.
+ *
+ * @param plugin The plugin attaching data to the document.
+ * @param doc The document to attach the data to.
+ * @param key The key name for the data.
+ * @param data The pointer to attach to the document.
+ * @param free_func The function to call with data when removed.
+ *
+ * @since 1.29 (Plugin API 228)
+ * @see plugin_get_document_data plugin_set_document_data
+ */
+GEANY_API_SYMBOL
+void plugin_set_document_data_full(struct GeanyPlugin *plugin,
+ struct GeanyDocument *doc, const gchar *key, gpointer data,
+ GDestroyNotify free_func)
+{
+ PluginDocDataProxy *prox;
+
+ g_return_if_fail(plugin != NULL);
+ g_return_if_fail(doc != NULL);
+ g_return_if_fail(key != NULL);
+
+ prox = g_slice_new(PluginDocDataProxy);
+ if (prox != NULL)
+ {
+ gchar *real_key = g_strdup_printf("geany/plugins/%s/%s", plugin->info->name, key);
+ prox->data = data;
+ prox->free_func = free_func;
+ document_set_data_full(doc, real_key, prox, plugin_doc_data_proxy_free);
+ g_free(real_key);
+ }
+}
+
+
#endif
Modified: src/pluginutils.h
11 lines changed, 11 insertions(+), 0 deletions(-)
===================================================================
@@ -33,6 +33,7 @@ G_BEGIN_DECLS
/* avoid including plugindata.h otherwise this redefines the GEANY() macro */
struct GeanyPlugin;
+struct GeanyDocument;
void plugin_add_toolbar_item(struct GeanyPlugin *plugin, GtkToolItem *item);
@@ -62,6 +63,16 @@ void plugin_show_configure(struct GeanyPlugin *plugin);
void plugin_builder_connect_signals(struct GeanyPlugin *plugin,
GtkBuilder *builder, gpointer user_data);
+gpointer plugin_get_document_data(struct GeanyPlugin *plugin,
+ struct GeanyDocument *doc, const gchar *key);
+
+void plugin_set_document_data(struct GeanyPlugin *plugin, struct GeanyDocument *doc,
+ const gchar *key, gpointer data);
+
+void plugin_set_document_data_full(struct GeanyPlugin *plugin,
+ struct GeanyDocument *doc, const gchar *key, gpointer data,
+ GDestroyNotify free_func);
+
G_END_DECLS
#endif /* HAVE_PLUGINS */
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list