# HG changeset patch # User Sadrul Habib Chowdhury # Date 1155705168 0 # Node ID 44ec6c7cbc76f2497e532a5fb53b4d916c7a1a21 # Parent 7f276f375789793dba43cdf5ad5094975f120b5d [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 diff -r 7f276f375789 -r 44ec6c7cbc76 console/gntplugin.c --- 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 #include +#include #include #include #include @@ -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))); } diff -r 7f276f375789 -r 44ec6c7cbc76 console/gntplugin.h --- 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 + #include +#include + +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(); diff -r 7f276f375789 -r 44ec6c7cbc76 console/libgnt/gnt.h --- 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); diff -r 7f276f375789 -r 44ec6c7cbc76 console/libgnt/gntmain.c --- 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); +} + diff -r 7f276f375789 -r 44ec6c7cbc76 console/plugins/Makefile.am --- /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$@.* diff -r 7f276f375789 -r 44ec6c7cbc76 console/plugins/gntgf.c --- /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 + * + * 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 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#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 ", + "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)