[geany/geany] bbf8e8: demoproxy: add a demo proxy showcasing how to create a proxy plugin
Thomas Martitz
git-noreply at xxxxx
Tue Oct 6 13:40:34 UTC 2015
Branch: refs/heads/master
Author: Thomas Martitz <kugel at rockbox.org>
Committer: Colomban Wendling <ban at herbesfolles.org>
Date: Tue, 06 Oct 2015 13:40:34 UTC
Commit: bbf8e882c2ea76c2d400decfbd6d5b44978eb3fa
https://github.com/geany/geany/commit/bbf8e882c2ea76c2d400decfbd6d5b44978eb3fa
Log Message:
-----------
demoproxy: add a demo proxy showcasing how to create a proxy plugin
This demo proxy does not actually do anything useful. It simply loads
pseudo-plugins from an ini-style file. The point is that there will be a plugin
in the PM dialog for each ini. Each ini-plugin also causes a menu item to be
generated.
Modified Paths:
--------------
plugins/Makefile.am
plugins/demoproxy.c
plugins/demoproxytest.px
po/POTFILES.skip
Modified: plugins/Makefile.am
10 lines changed, 8 insertions(+), 2 deletions(-)
===================================================================
@@ -1,7 +1,8 @@
# Adapted from Pidgin's plugins/Makefile.am, thanks
EXTRA_DIST = \
- makefile.win32
+ makefile.win32 \
+ demoproxytest.px
plugindir = $(libdir)/geany
@@ -11,6 +12,7 @@ plugins_include_HEADERS = \
geanyplugin.h
demoplugin_la_LDFLAGS = -module -avoid-version -no-undefined
+demoproxy_la_LDFLAGS = -module -avoid-version -no-undefined
classbuilder_la_LDFLAGS = -module -avoid-version -no-undefined
htmlchars_la_LDFLAGS = -module -avoid-version -no-undefined
export_la_LDFLAGS = -module -avoid-version -no-undefined
@@ -30,9 +32,11 @@ plugin_LTLIBRARIES = \
# Plugins not to be installed
noinst_LTLIBRARIES = \
- demoplugin.la
+ demoplugin.la \
+ demoproxy.la
demoplugin_la_SOURCES = demoplugin.c
+demoproxy_la_SOURCES = demoproxy.c
classbuilder_la_SOURCES = classbuilder.c
htmlchars_la_SOURCES = htmlchars.c
export_la_SOURCES = export.c
@@ -41,6 +45,7 @@ filebrowser_la_SOURCES = filebrowser.c
splitwindow_la_SOURCES = splitwindow.c
demoplugin_la_CFLAGS = -DG_LOG_DOMAIN=\""Demoplugin"\" -DLOCALEDIR=\""$(LOCALEDIR)"\"
+demoproxy_la_CFLAGS = -DG_LOG_DOMAIN=\""Demoproxy"\"
classbuilder_la_CFLAGS = -DG_LOG_DOMAIN=\""Classbuilder"\"
htmlchars_la_CFLAGS = -DG_LOG_DOMAIN=\""HTMLChars"\"
export_la_CFLAGS = -DG_LOG_DOMAIN=\""Export"\"
@@ -49,6 +54,7 @@ filebrowser_la_CFLAGS = -DG_LOG_DOMAIN=\""FileBrowser"\"
splitwindow_la_CFLAGS = -DG_LOG_DOMAIN=\""SplitWindow"\"
demoplugin_la_LIBADD = $(top_builddir)/src/libgeany.la $(GTK_LIBS)
+demoproxy_la_LIBADD = $(top_builddir)/src/libgeany.la $(GTK_LIBS)
classbuilder_la_LIBADD = $(top_builddir)/src/libgeany.la $(GTK_LIBS)
htmlchars_la_LIBADD = $(top_builddir)/src/libgeany.la $(GTK_LIBS)
export_la_LIBADD = $(top_builddir)/src/libgeany.la $(GTK_LIBS) -lm
Modified: plugins/demoproxy.c
202 lines changed, 202 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,202 @@
+/*
+ * demoproxy.c - this file is part of Geany, a fast and lightweight IDE
+ *
+ * Copyright 2015 Thomas Martitz <kugel(at)rockbox(dot)org>
+ *
+ * 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.
+ */
+
+/**
+ * Demo proxy - example of a basic proxy plugin for Geany. Sub-plugins add menu items to the
+ * Tools menu and have a help dialog.
+ *
+ * Note: This is compiled but not installed by default. On Unix, you can install it by compiling
+ * Geany and then copying (or symlinking) to the plugins/demoproxy.so and
+ * plugins/demoproxytest.px files to ~/.config/geany/plugins
+ * - it will be loaded at next startup.
+ */
+
+/* plugin API, always comes first */
+#include "geanyplugin.h"
+
+typedef struct {
+ GKeyFile *file;
+ gchar *help_text;
+ GSList *menu_items;
+}
+PluginContext;
+
+
+static gboolean proxy_init(GeanyPlugin *plugin, gpointer pdata)
+{
+ PluginContext *data;
+ gint i = 0;
+ gchar *text;
+
+ data = (PluginContext *) pdata;
+
+ /* Normally, you would instruct the VM/interpreter to call into the actual plugin. The
+ * plugin would be identified by pdata. Because there is no interpreter for
+ * .ini files we do it inline, as this is just a demo */
+ data->help_text = g_key_file_get_locale_string(data->file, "Help", "text", NULL, NULL);
+ while (TRUE)
+ {
+ GtkWidget *item;
+ gchar *key = g_strdup_printf("item%d", i++);
+ text = g_key_file_get_locale_string(data->file, "Init", key, NULL, NULL);
+ g_free(key);
+
+ if (!text)
+ break;
+
+ item = gtk_menu_item_new_with_label(text);
+ gtk_widget_show(item);
+ gtk_container_add(GTK_CONTAINER(plugin->geany_data->main_widgets->tools_menu), item);
+ gtk_widget_set_sensitive(item, FALSE);
+ data->menu_items = g_slist_prepend(data->menu_items, (gpointer) item);
+ g_free(text);
+ }
+
+ return TRUE;
+}
+
+
+static void proxy_help(GeanyPlugin *plugin, gpointer pdata)
+{
+ PluginContext *data;
+ GtkWidget *dialog;
+
+ data = (PluginContext *) pdata;
+
+ dialog = gtk_message_dialog_new(
+ GTK_WINDOW(plugin->geany_data->main_widgets->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_OK,
+ "%s", data->help_text);
+ gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
+ _("(From the %s plugin)"), plugin->info->name);
+
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+}
+
+
+static void proxy_cleanup(GeanyPlugin *plugin, gpointer pdata)
+{
+ PluginContext *data = (PluginContext *) pdata;
+
+ g_slist_free_full(data->menu_items, (GDestroyNotify) gtk_widget_destroy);
+ g_free(data->help_text);
+}
+
+
+static gint demoproxy_probe(GeanyPlugin *proxy, const gchar *filename, gpointer pdata)
+{
+ /* We know the extension is right (Geany checks that). For demo purposes we perform an
+ * additional check. This is not necessary when the extension is unique enough. */
+ gboolean match = FALSE;
+ gchar linebuf[128];
+ FILE *f = fopen(filename, "r");
+ if (f != NULL)
+ {
+ if (fgets(linebuf, sizeof(linebuf), f) != NULL)
+ match = utils_str_equal(linebuf, "#!!PROXY_MAGIC!!\n");
+ fclose(f);
+ }
+ return match ? PROXY_MATCHED : PROXY_IGNORED;
+}
+
+
+static gpointer demoproxy_load(GeanyPlugin *proxy, GeanyPlugin *plugin,
+ const gchar *filename, gpointer pdata)
+{
+ GKeyFile *file;
+ gboolean result;
+
+ file = g_key_file_new();
+ result = g_key_file_load_from_file(file, filename, 0, NULL);
+
+ if (result)
+ {
+ PluginContext *data = g_new0(PluginContext, 1);
+ data->file = file;
+
+ plugin->info->name = g_key_file_get_locale_string(data->file, "Info", "name", NULL, NULL);
+ plugin->info->description = g_key_file_get_locale_string(data->file, "Info", "description", NULL, NULL);
+ plugin->info->version = g_key_file_get_locale_string(data->file, "Info", "version", NULL, NULL);
+ plugin->info->author = g_key_file_get_locale_string(data->file, "Info", "author", NULL, NULL);
+
+ plugin->funcs->init = proxy_init;
+ plugin->funcs->help = proxy_help;
+ plugin->funcs->cleanup = proxy_cleanup;
+
+ /* Cannot pass g_free as free_func be Geany calls it before unloading, and since
+ * demoproxy_unload() accesses the data this would be catastrophic */
+ GEANY_PLUGIN_REGISTER_FULL(plugin, 225, data, NULL);
+ return data;
+ }
+
+ g_key_file_free(file);
+ return NULL;
+}
+
+
+static void demoproxy_unload(GeanyPlugin *proxy, GeanyPlugin *plugin, gpointer load_data, gpointer pdata)
+{
+ PluginContext *data = load_data;
+
+ g_free((gchar *)plugin->info->name);
+ g_free((gchar *)plugin->info->description);
+ g_free((gchar *)plugin->info->version);
+ g_free((gchar *)plugin->info->author);
+
+ g_key_file_free(data->file);
+ g_free(data);
+}
+
+
+/* Called by Geany to initialize the plugin. */
+static gboolean demoproxy_init(GeanyPlugin *plugin, gpointer pdata)
+{
+ const gchar *extensions[] = { "ini", "px", NULL };
+
+ plugin->proxy_funcs->probe = demoproxy_probe;
+ plugin->proxy_funcs->load = demoproxy_load;
+ plugin->proxy_funcs->unload = demoproxy_unload;
+
+ return geany_plugin_register_proxy(plugin, extensions);
+}
+
+
+/* Called by Geany before unloading the plugin. */
+static void demoproxy_cleanup(GeanyPlugin *plugin, gpointer data)
+{
+}
+
+
+G_MODULE_EXPORT
+void geany_load_module(GeanyPlugin *plugin)
+{
+ plugin->info->name = _("Demo Proxy");
+ plugin->info->description = _("Example Proxy.");
+ plugin->info->version = "0.1";
+ plugin->info->author = _("The Geany developer team");
+
+ plugin->funcs->init = demoproxy_init;
+ plugin->funcs->cleanup = demoproxy_cleanup;
+
+ GEANY_PLUGIN_REGISTER(plugin, 225);
+}
Modified: plugins/demoproxytest.px
15 lines changed, 15 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,15 @@
+#!!PLUXY_MAGIC!!
+
+[Init]
+item0 = Bam
+item1 = Foo
+item2 = Bar
+
+[Help]
+text = I'm a simple test. Nothing to see!
+
+[Info]
+name = Demo Pluxy Tester
+description = I'm a simple test. Nothing to see!
+version = 0.1
+author = The Geany developer team
Modified: po/POTFILES.skip
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -6,5 +6,6 @@ geany.desktop.in
geany.glade
# no need to translate these files
plugins/demoplugin.c
+plugins/demoproxy.c
doc/stash-example.c
doc/stash-gui-example.c
--------------
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