changeset 14139:44ec6c7cbc76

[gaim-migrate @ 16781] Allow setting the preferences for gnt-plugins. Add a guifications-like plugin for gntgaim. You can set its preferences. The preferences for core plugins are still not accessible. The makefile-foo will require changes once the split is complete. I am now just committing whatever works for me. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 16 Aug 2006 05:12:48 +0000
parents 7f276f375789
children ee80f766b7e3
files console/gntplugin.c console/gntplugin.h console/libgnt/gnt.h console/libgnt/gntmain.c console/plugins/Makefile.am console/plugins/gntgf.c
diffstat 6 files changed, 427 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/console/gntplugin.c	Wed Aug 16 04:50:27 2006 +0000
+++ b/console/gntplugin.c	Wed Aug 16 05:12:48 2006 +0000
@@ -1,5 +1,6 @@
 #include <gnt.h>
 #include <gntbox.h>
+#include <gntbutton.h>
 #include <gntlabel.h>
 #include <gntline.h>
 #include <gnttree.h>
@@ -14,9 +15,26 @@
 	GntWidget *tree;
 	GntWidget *window;
 	GntWidget *aboot;
+	GntWidget *conf;
 } plugins;
 
 static void
+decide_conf_button(GaimPlugin *plugin)
+{
+	if (gaim_plugin_is_loaded(plugin) && 
+		((GAIM_IS_GNT_PLUGIN(plugin) &&
+			GAIM_GNT_PLUGIN_UI_INFO(plugin) != NULL) ||
+		(plugin->info->prefs_info &&
+			plugin->info->prefs_info->get_plugin_pref_frame)))
+		gnt_widget_set_visible(plugins.conf, TRUE);
+	else
+		gnt_widget_set_visible(plugins.conf, FALSE);
+
+	gnt_box_readjust(GNT_BOX(plugins.window));
+	gnt_widget_draw(plugins.window);
+}
+
+static void
 plugin_toggled_cb(GntWidget *tree, GaimPlugin *plugin, gpointer null)
 {
 	if (gnt_tree_get_choice(GNT_TREE(tree), plugin))
@@ -29,6 +47,7 @@
 		if (!gaim_plugin_unload(plugin))
 			gaim_notify_error(NULL, "ERROR", "unloading plugin failed", NULL);
 	}
+	decide_conf_button(plugin);
 	gg_plugins_save_loaded();
 }
 
@@ -69,6 +88,7 @@
 			text, GNT_TEXT_FLAG_NORMAL);
 	gnt_text_view_scroll(GNT_TEXT_VIEW(plugins.aboot), 0);
 	g_free(text);
+	decide_conf_button(plugin);
 }
 
 static void
@@ -90,9 +110,63 @@
 	return ret;
 }
 
+static void
+configure_plugin_cb(GntWidget *button, gpointer null)
+{
+	GaimPlugin *plugin;
+	GGPluginFrame callback;
+
+	g_return_if_fail(plugins.tree != NULL);
+
+	plugin = gnt_tree_get_selection_data(GNT_TREE(plugins.tree));
+	if (!gaim_plugin_is_loaded(plugin))
+	{
+		gaim_notify_error(plugin, _("Error"),
+			_("Plugin need to be loaded before you can configure it."), NULL);
+		return;
+	}
+
+	if (GAIM_IS_GNT_PLUGIN(plugin) &&
+			(callback = GAIM_GNT_PLUGIN_UI_INFO(plugin)) != NULL)
+	{
+		GntWidget *window = gnt_vbox_new(FALSE);
+		GntWidget *box, *button;
+
+		gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+		gnt_box_set_title(GNT_BOX(window), plugin->info->name);
+		gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+
+		box = callback();
+		gnt_box_add_widget(GNT_BOX(window), box);
+
+		box = gnt_hbox_new(FALSE);
+		gnt_box_add_widget(GNT_BOX(window), box);
+
+		button = gnt_button_new(_("Close"));
+		gnt_box_add_widget(GNT_BOX(box), button);
+		g_signal_connect_swapped(G_OBJECT(button), "activate",
+				G_CALLBACK(gnt_widget_destroy), window);
+
+		gnt_widget_show(window);  /* XXX: This window needs to be closed when the plugin is unloaded */
+	}
+	else if (plugin->info->prefs_info &&
+			plugin->info->prefs_info->get_plugin_pref_frame)
+	{
+		gaim_notify_info(plugin, _("..."),
+			_("Still need to do something about this."), NULL);
+		return;
+	}
+	else
+	{
+		gaim_notify_info(plugin, _("Error"),
+			_("No configuration options for this plugin."), NULL);
+		return;
+	}
+}
+
 void gg_plugins_show_all()
 {
-	GntWidget *window, *tree, *box, *aboot;
+	GntWidget *window, *tree, *box, *aboot, *button;
 	GList *iter;
 	if (plugins.window)
 		return;
@@ -103,6 +177,7 @@
 	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
 	gnt_box_set_title(GNT_BOX(window), _("Plugins"));
 	gnt_box_set_pad(GNT_BOX(window), 0);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
 
 	gnt_box_add_widget(GNT_BOX(window),
 			gnt_label_new(_("You can (un)load plugins from the following list.")));
@@ -139,8 +214,23 @@
 	gnt_tree_set_col_width(GNT_TREE(tree), 0, 30);
 	g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(plugin_toggled_cb), NULL);
 	g_signal_connect(G_OBJECT(tree), "selection_changed", G_CALLBACK(selection_changed), NULL);
+
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	button = gnt_button_new(_("Close"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate",
+			G_CALLBACK(gnt_widget_destroy), window);
+
+	plugins.conf = button = gnt_button_new(_("Configure Plugin"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(configure_plugin_cb), NULL);
+
 	g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(reset_plugin_window), NULL);
 
 	gnt_widget_show(window);
+
+	decide_conf_button(gnt_tree_get_selection_data(GNT_TREE(tree)));
 }
 
--- a/console/gntplugin.h	Wed Aug 16 04:50:27 2006 +0000
+++ b/console/gntplugin.h	Wed Aug 16 05:12:48 2006 +0000
@@ -1,5 +1,21 @@
+#include <gnt.h>
+
 #include <plugin.h>
 
+#include <string.h>
+
+typedef GntWidget* (*GGPluginFrame) ();
+
+/* Guess where these came from */
+#define GAIM_GNT_PLUGIN_TYPE "gnt"
+
+#define GAIM_IS_GNT_PLUGIN(plugin) \
+	((plugin)->info != NULL && (plugin)->info->ui_info != NULL && \
+	 !strcmp((plugin)->info->ui_requirement, GAIM_GNT_PLUGIN_TYPE))
+
+#define GAIM_GNT_PLUGIN_UI_INFO(plugin) \
+	(GGPluginFrame)((plugin)->info->ui_info)
+
 void gg_plugins_show_all();
 
 void gg_plugins_save_loaded();
--- a/console/libgnt/gnt.h	Wed Aug 16 04:50:27 2006 +0000
+++ b/console/libgnt/gnt.h	Wed Aug 16 05:12:48 2006 +0000
@@ -19,6 +19,8 @@
 
 void gnt_screen_resize_widget(GntWidget *widget, int width, int height);
 
+void gnt_screen_move_widget(GntWidget *widget, int x, int y);
+
 gboolean gnt_widget_has_focus(GntWidget *widget);
 
 void gnt_widget_set_urgent(GntWidget *widget);
--- a/console/libgnt/gntmain.c	Wed Aug 16 04:50:27 2006 +0000
+++ b/console/libgnt/gntmain.c	Wed Aug 16 05:12:48 2006 +0000
@@ -586,10 +586,7 @@
 
 			if (changed)
 			{
-				GntNode *node = g_hash_table_lookup(nodes, widget);
-				gnt_widget_set_position(widget, x, y);
-				move_panel(node->panel, y, x);
-				update_screen(NULL);
+				gnt_screen_move_widget(widget, x, y);
 			}
 		}
 		else if (*buffer == '\r')
@@ -879,3 +876,11 @@
 	}
 }
 
+void gnt_screen_move_widget(GntWidget *widget, int x, int y)
+{
+	GntNode *node = g_hash_table_lookup(nodes, widget);
+	gnt_widget_set_position(widget, x, y);
+	move_panel(node->panel, y, x);
+	update_screen(NULL);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/plugins/Makefile.am	Wed Aug 16 05:12:48 2006 +0000
@@ -0,0 +1,38 @@
+gntgf_la_LDFLAGS             = -module -avoid-version $(GLIB_LIBS)
+
+if PLUGINS
+
+plugin_LTLIBRARIES = \
+	gntgf.la
+
+plugindir = $(libdir)/gaim
+
+gntgf_la_SOURCES             = gntgf.c
+
+endif # PLUGINS
+
+EXTRA_DIST = 
+
+GNT_CFLAGS = `pkg-config --cflags gnt` -I..
+
+AM_CPPFLAGS = \
+	-DDATADIR=\"$(datadir)\" \
+	-DVERSION=\"$(VERSION)\" \
+	-I$(top_builddir)/src \
+	-I$(top_srcdir)/src \
+	$(DEBUG_CFLAGS) \
+	$(GNT_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	$(PLUGIN_CFLAGS)
+
+#
+# This part allows people to build their own plugins in here.
+# Yes, it's a mess.
+#
+SUFFIXES = .c .so
+.c.so:
+	$(LIBTOOL) --mode=compile $(CC) -DHAVE_CONFIG_H -I$(top_srcdir) $(AM_CPPFLAGS) $(CFLAGS) -c $< -o tmp$@.lo $(PLUGIN_CFLAGS)
+	$(LIBTOOL) --mode=link    $(CC) $(CFLAGS) -o libtmp$@.la -rpath $(plugindir) tmp$@.lo $(LIBS) $(LDFLAGS) -module -avoid-version $(PLUGIN_LIBS)
+	@rm -f tmp$@.lo tmp$@.o libtmp$@.la
+	@cp .libs/libtmp$@.so* $@
+	@rm -f .libs/libtmp$@.*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/plugins/gntgf.c	Wed Aug 16 05:12:48 2006 +0000
@@ -0,0 +1,271 @@
+/**
+ * @file gntgf.c Minimal toaster plugin in Gnt.
+ *
+ * Copyright (C) 2006 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define GAIM_PLUGINS
+
+#define PLUGIN_STATIC_NAME	"GntGf"
+
+#define PREFS_EVENT           "/plugins/gnt/gntgf/events"
+#define PREFS_EVENT_SIGNONF   PREFS_EVENT "/signonf"
+#define PREFS_EVENT_IM_MSG    PREFS_EVENT "/immsg"
+#define PREFS_EVENT_CHAT_MSG  PREFS_EVENT "/chatmsg"
+#define PREFS_EVENT_CHAT_NICK PREFS_EVENT "/chatnick"
+
+#include <glib.h>
+
+#include <plugin.h>
+#include <version.h>
+#include <blist.h>
+#include <conversation.h>
+
+#include <gnt.h>
+#include <gntbox.h>
+#include <gntbutton.h>
+#include <gntlabel.h>
+#include <gnttree.h>
+
+#include <gntplugin.h>
+
+#define _(X) X
+
+typedef struct
+{
+	GntWidget *window;
+	int timer;
+} GntToast;
+
+static GList *toasters;
+static int gpsy;
+
+static void
+destroy_toaster(GntToast *toast)
+{
+	toasters = g_list_remove(toasters, toast);
+	gnt_widget_destroy(toast->window);
+	g_source_remove(toast->timer);
+	g_free(toast);
+}
+
+static gboolean
+remove_toaster(GntToast *toast)
+{
+	GList *iter;
+	int h;
+
+	gnt_widget_get_size(toast->window, NULL, &h);
+	gpsy -= h;
+
+	destroy_toaster(toast);
+
+	for (iter = toasters; iter; iter = iter->next)
+	{
+		int x, y;
+		toast = iter->data;
+		gnt_widget_get_position(toast->window, &x, &y);
+		y += h;
+		gnt_screen_move_widget(toast->window, x, y);
+	}
+
+	return FALSE;
+}
+
+static void
+notify(const char *fmt, ...)
+{
+	GntWidget *window;
+	GntToast *toast = g_new0(GntToast, 1);
+	char *str;
+	int h, w;
+	va_list args;
+
+	toast->window = window = gnt_vbox_new(FALSE);
+	GNT_WIDGET_SET_FLAGS(window, GNT_WIDGET_TRANSIENT);
+	GNT_WIDGET_UNSET_FLAGS(window, GNT_WIDGET_NO_BORDER);
+
+	va_start(args, fmt);
+	str = g_strdup_vprintf(fmt, args);
+	va_end(args);
+
+	gnt_box_add_widget(GNT_BOX(window),
+			gnt_label_new_with_format(str, GNT_TEXT_FLAG_HIGHLIGHT));
+
+	g_free(str);
+	gnt_widget_size_request(window);
+	gnt_widget_get_size(window, &w, &h);
+	gpsy += h;
+	gnt_widget_set_position(window, getmaxx(stdscr) - w - 1,
+			getmaxy(stdscr) - gpsy - 1);
+	gnt_widget_draw(window);
+
+	toast->timer = g_timeout_add(4000, (GSourceFunc)remove_toaster, toast);
+	toasters = g_list_prepend(toasters, toast);
+}
+
+static void
+buddy_signed_on(GaimBuddy *buddy, gpointer null)
+{
+	if (gaim_prefs_get_bool(PREFS_EVENT_SIGNONF))
+		notify(_("%s just signed on"), gaim_buddy_get_alias(buddy));
+}
+
+static void
+buddy_signed_off(GaimBuddy *buddy, gpointer null)
+{
+	if (gaim_prefs_get_bool(PREFS_EVENT_SIGNONF))
+		notify(_("%s just signed off"), gaim_buddy_get_alias(buddy));
+}
+
+static void
+received_im_msg(GaimAccount *account, const char *sender, const char *msg,
+		GaimConversation *conv, GaimMessageFlags flags, gpointer null)
+{
+	if (gaim_prefs_get_bool(PREFS_EVENT_IM_MSG))
+		notify(_("%s sent you a message"), sender);
+}
+
+static void
+received_chat_msg(GaimAccount *account, const char *sender, const char *msg,
+		GaimConversation *conv, GaimMessageFlags flags, gpointer null)
+{
+	if (gaim_prefs_get_bool(PREFS_EVENT_CHAT_NICK) && (flags & GAIM_MESSAGE_NICK))
+		notify(_("%s said your nick in %s"), sender, gaim_conversation_get_name(conv));
+	else if (gaim_prefs_get_bool(PREFS_EVENT_CHAT_MSG))
+		notify(_("%s sent a message in %s"), sender, gaim_conversation_get_name(conv));
+}
+
+static gboolean
+plugin_load(GaimPlugin *plugin)
+{
+	gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", plugin,
+			GAIM_CALLBACK(buddy_signed_on), NULL);
+	gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-off", plugin,
+			GAIM_CALLBACK(buddy_signed_off), NULL);
+	gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg", plugin,
+			GAIM_CALLBACK(received_im_msg), NULL);
+	gaim_signal_connect(gaim_conversations_get_handle(), "received-chat-msg", plugin,
+			GAIM_CALLBACK(received_chat_msg), NULL);
+
+	gpsy = 0;
+
+	return TRUE;
+}
+
+static gboolean
+plugin_unload(GaimPlugin *plugin)
+{
+	while (toasters)
+	{
+		GntToast *toast = toasters->data;
+		destroy_toaster(toast);
+	}
+	return TRUE;
+}
+
+static struct
+{
+	char *pref;
+	char *display;
+} prefs[] =
+{
+	{PREFS_EVENT_SIGNONF, _("Buddy signs on/off")},
+	{PREFS_EVENT_IM_MSG, _("You receive an IMs")},
+	{PREFS_EVENT_CHAT_MSG, _("Someone speaks in a chat")},
+	{PREFS_EVENT_CHAT_NICK, _("Someone says your name in a chat")},
+	{NULL, NULL}
+};
+
+static void
+pref_toggled(GntTree *tree, char *key, gpointer null)
+{
+	gaim_prefs_set_bool(key, gnt_tree_get_choice(tree, key));
+}
+
+static GntWidget *
+config_frame()
+{
+	GntWidget *window, *tree;
+	int i;
+
+	window = gnt_vbox_new(FALSE);
+	gnt_box_set_pad(GNT_BOX(window), 0);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+	gnt_box_set_fill(GNT_BOX(window), TRUE);
+
+	gnt_box_add_widget(GNT_BOX(window),
+			gnt_label_new(_("Notify with a toaster when")));
+
+	tree = gnt_tree_new();
+	gnt_box_add_widget(GNT_BOX(window), tree);
+
+	for (i = 0; prefs[i].pref; i++)
+	{
+		gnt_tree_add_choice(GNT_TREE(tree), prefs[i].pref,
+				gnt_tree_create_row(GNT_TREE(tree), prefs[i].display), NULL, NULL);
+		gnt_tree_set_choice(GNT_TREE(tree), prefs[i].pref,
+				gaim_prefs_get_bool(prefs[i].pref));
+	}
+	gnt_tree_set_col_width(GNT_TREE(tree), 0, 40);
+	g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(pref_toggled), NULL);
+
+	return window;
+}
+
+static GaimPluginInfo info =
+{
+	GAIM_PLUGIN_MAGIC,
+	GAIM_MAJOR_VERSION,
+	GAIM_MINOR_VERSION,
+	GAIM_PLUGIN_STANDARD,
+	GAIM_GNT_PLUGIN_TYPE,
+	0,
+	NULL,
+	GAIM_PRIORITY_DEFAULT,
+	"gntgf",
+	N_("GntGf"),
+	VERSION,
+	N_("Toaster plugin for GntGaim."),
+	N_("Toaster plugin for GntGaim."),
+	"Sadrul H Chowdhury <sadrul@users.sourceforge.net>",
+	"http://gaim.sourceforge.net",
+	plugin_load,
+	plugin_unload,
+	NULL,
+	config_frame,
+	NULL,
+	NULL,
+	NULL
+};
+
+static void
+init_plugin(GaimPlugin *plugin)
+{
+	gaim_prefs_add_none("/plugins");
+	gaim_prefs_add_none("/plugins/gnt");
+	
+	gaim_prefs_add_none("/plugins/gnt/gntgf");
+	gaim_prefs_add_none(PREFS_EVENT);
+
+	gaim_prefs_add_bool(PREFS_EVENT_SIGNONF, TRUE);
+	gaim_prefs_add_bool(PREFS_EVENT_IM_MSG, TRUE);
+	gaim_prefs_add_bool(PREFS_EVENT_CHAT_MSG, TRUE);
+	gaim_prefs_add_bool(PREFS_EVENT_CHAT_NICK, TRUE);
+}
+
+GAIM_INIT_PLUGIN(PLUGIN_STATIC_NAME, init_plugin, info)