merge of '134eb2e58f255d14d53d8b9463921ce7edb9aa36'
[pidgin-git.git] / finch / gntplugin.c
blob972fe43238e9cd12e34550e38435aafdaffed665
1 /**
2 * @file gntplugin.c GNT Plugins API
3 * @ingroup finch
5 * finch
7 * Finch is the legal property of its developers, whose names are too numerous
8 * to list here. Please refer to the COPYRIGHT file distributed with this
9 * source distribution.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <gnt.h>
26 #include <gntbox.h>
27 #include <gntbutton.h>
28 #include <gntlabel.h>
29 #include <gntline.h>
30 #include <gnttree.h>
32 #include "notify.h"
33 #include "request.h"
35 #include "finch.h"
36 #include "gntplugin.h"
37 #include "gntrequest.h"
39 static struct
41 GntWidget *tree;
42 GntWidget *window;
43 GntWidget *aboot;
44 GntWidget *conf;
45 } plugins;
47 static GHashTable *confwins;
49 static void process_pref_frame(PurplePluginPrefFrame *frame);
51 static void
52 decide_conf_button(PurplePlugin *plugin)
54 if (purple_plugin_is_loaded(plugin) &&
55 ((PURPLE_IS_GNT_PLUGIN(plugin) &&
56 FINCH_PLUGIN_UI_INFO(plugin) != NULL) ||
57 (plugin->info->prefs_info &&
58 plugin->info->prefs_info->get_plugin_pref_frame)))
59 gnt_widget_set_visible(plugins.conf, TRUE);
60 else
61 gnt_widget_set_visible(plugins.conf, FALSE);
63 gnt_box_readjust(GNT_BOX(plugins.window));
64 gnt_widget_draw(plugins.window);
67 static void
68 plugin_toggled_cb(GntWidget *tree, PurplePlugin *plugin, gpointer null)
70 /* TODO: Mark these strings for translation after the freeze */
71 if (gnt_tree_get_choice(GNT_TREE(tree), plugin))
73 if (!purple_plugin_load(plugin)) {
74 purple_notify_error(NULL, "ERROR", "loading plugin failed", NULL);
75 gnt_tree_set_choice(GNT_TREE(tree), plugin, FALSE);
78 else
80 GntWidget *win;
82 if (!purple_plugin_unload(plugin)) {
83 purple_notify_error(NULL, "ERROR", "unloading plugin failed", NULL);
84 gnt_tree_set_choice(GNT_TREE(tree), plugin, TRUE);
87 if ((win = g_hash_table_lookup(confwins, plugin)) != NULL)
89 gnt_widget_destroy(win);
92 decide_conf_button(plugin);
93 finch_plugins_save_loaded();
96 /* Xerox */
97 void
98 finch_plugins_save_loaded(void)
100 purple_plugins_save_loaded("/finch/plugins/loaded");
103 static void
104 selection_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
106 PurplePlugin *plugin = current;
107 char *text;
109 /* XXX: Use formatting and stuff */
110 gnt_text_view_clear(GNT_TEXT_VIEW(plugins.aboot));
111 text = g_strdup_printf(_("Name: %s\nVersion: %s\nDescription: %s\nAuthor: %s\nWebsite: %s\nFilename: %s\n"),
112 SAFE(plugin->info->name), SAFE(plugin->info->version), SAFE(plugin->info->description),
113 SAFE(plugin->info->author), SAFE(plugin->info->homepage), SAFE(plugin->path));
114 gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(plugins.aboot),
115 text, GNT_TEXT_FLAG_NORMAL);
116 gnt_text_view_scroll(GNT_TEXT_VIEW(plugins.aboot), 0);
117 g_free(text);
118 decide_conf_button(plugin);
121 static void
122 reset_plugin_window(GntWidget *window, gpointer null)
124 plugins.window = NULL;
125 plugins.tree = NULL;
126 plugins.aboot = NULL;
129 static int
130 plugin_compare(PurplePlugin *p1, PurplePlugin *p2)
132 char *s1 = g_utf8_strup(p1->info->name, -1);
133 char *s2 = g_utf8_strup(p2->info->name, -1);
134 int ret = g_utf8_collate(s1, s2);
135 g_free(s1);
136 g_free(s2);
137 return ret;
140 static void
141 confwin_init()
143 confwins = g_hash_table_new(g_direct_hash, g_direct_equal);
146 static void
147 remove_confwin(GntWidget *window, gpointer plugin)
149 g_hash_table_remove(confwins, plugin);
152 static void
153 configure_plugin_cb(GntWidget *button, gpointer null)
155 PurplePlugin *plugin;
156 FinchPluginFrame callback;
158 g_return_if_fail(plugins.tree != NULL);
160 plugin = gnt_tree_get_selection_data(GNT_TREE(plugins.tree));
161 if (!purple_plugin_is_loaded(plugin))
163 purple_notify_error(plugin, _("Error"),
164 _("Plugin need to be loaded before you can configure it."), NULL);
165 return;
168 if (confwins && g_hash_table_lookup(confwins, plugin))
169 return;
171 if (PURPLE_IS_GNT_PLUGIN(plugin) &&
172 (callback = FINCH_PLUGIN_UI_INFO(plugin)) != NULL)
174 GntWidget *window = gnt_vbox_new(FALSE);
175 GntWidget *box, *button;
177 gnt_box_set_toplevel(GNT_BOX(window), TRUE);
178 gnt_box_set_title(GNT_BOX(window), plugin->info->name);
179 gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
181 box = callback();
182 gnt_box_add_widget(GNT_BOX(window), box);
184 box = gnt_hbox_new(FALSE);
185 gnt_box_add_widget(GNT_BOX(window), box);
187 button = gnt_button_new(_("Close"));
188 gnt_box_add_widget(GNT_BOX(box), button);
189 g_signal_connect_swapped(G_OBJECT(button), "activate",
190 G_CALLBACK(gnt_widget_destroy), window);
191 g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(remove_confwin), plugin);
193 gnt_widget_show(window);
195 if (confwins == NULL)
196 confwin_init();
197 g_hash_table_insert(confwins, plugin, window);
199 else if (plugin->info->prefs_info &&
200 plugin->info->prefs_info->get_plugin_pref_frame)
202 process_pref_frame(plugin->info->prefs_info->get_plugin_pref_frame(plugin));
203 return;
205 else
207 purple_notify_info(plugin, _("Error"),
208 _("No configuration options for this plugin."), NULL);
209 return;
213 void finch_plugins_show_all()
215 GntWidget *window, *tree, *box, *aboot, *button;
216 GList *iter;
217 if (plugins.window)
218 return;
220 purple_plugins_probe(G_MODULE_SUFFIX);
222 plugins.window = window = gnt_vbox_new(FALSE);
223 gnt_box_set_toplevel(GNT_BOX(window), TRUE);
224 gnt_box_set_title(GNT_BOX(window), _("Plugins"));
225 gnt_box_set_pad(GNT_BOX(window), 0);
226 gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
228 gnt_box_add_widget(GNT_BOX(window),
229 gnt_label_new(_("You can (un)load plugins from the following list.")));
230 gnt_box_add_widget(GNT_BOX(window), gnt_hline_new());
232 box = gnt_hbox_new(FALSE);
233 gnt_box_add_widget(GNT_BOX(window), box);
234 gnt_box_add_widget(GNT_BOX(window), gnt_hline_new());
236 gnt_box_set_pad(GNT_BOX(box), 0);
237 plugins.tree = tree = gnt_tree_new();
238 gnt_tree_set_compare_func(GNT_TREE(tree), (GCompareFunc)plugin_compare);
239 GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER);
240 gnt_box_add_widget(GNT_BOX(box), tree);
241 gnt_box_add_widget(GNT_BOX(box), gnt_vline_new());
243 plugins.aboot = aboot = gnt_text_view_new();
244 gnt_widget_set_size(aboot, 40, 20);
245 gnt_box_add_widget(GNT_BOX(box), aboot);
247 for (iter = purple_plugins_get_all(); iter; iter = iter->next)
249 PurplePlugin *plug = iter->data;
251 if (plug->info->type != PURPLE_PLUGIN_STANDARD ||
252 (plug->info->flags & PURPLE_PLUGIN_FLAG_INVISIBLE) ||
253 plug->error)
254 continue;
256 gnt_tree_add_choice(GNT_TREE(tree), plug,
257 gnt_tree_create_row(GNT_TREE(tree), plug->info->name), NULL, NULL);
258 gnt_tree_set_choice(GNT_TREE(tree), plug, purple_plugin_is_loaded(plug));
260 gnt_tree_set_col_width(GNT_TREE(tree), 0, 30);
261 g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(plugin_toggled_cb), NULL);
262 g_signal_connect(G_OBJECT(tree), "selection_changed", G_CALLBACK(selection_changed), NULL);
264 box = gnt_hbox_new(FALSE);
265 gnt_box_add_widget(GNT_BOX(window), box);
267 button = gnt_button_new(_("Close"));
268 gnt_box_add_widget(GNT_BOX(box), button);
269 g_signal_connect_swapped(G_OBJECT(button), "activate",
270 G_CALLBACK(gnt_widget_destroy), window);
272 plugins.conf = button = gnt_button_new(_("Configure Plugin"));
273 gnt_box_add_widget(GNT_BOX(box), button);
274 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(configure_plugin_cb), NULL);
276 g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(reset_plugin_window), NULL);
278 gnt_widget_show(window);
280 decide_conf_button(gnt_tree_get_selection_data(GNT_TREE(tree)));
283 static void
284 process_pref_frame(PurplePluginPrefFrame *frame)
286 PurpleRequestField *field;
287 PurpleRequestFields *fields;
288 PurpleRequestFieldGroup *group = NULL;
289 GList *prefs;
291 fields = purple_request_fields_new();
293 for (prefs = purple_plugin_pref_frame_get_prefs(frame); prefs; prefs = prefs->next) {
294 PurplePluginPref *pref = prefs->data;
295 const char *name = purple_plugin_pref_get_name(pref);
296 const char *label = purple_plugin_pref_get_label(pref);
297 if(name == NULL) {
298 if(label == NULL)
299 continue;
301 if(purple_plugin_pref_get_type(pref) == PURPLE_PLUGIN_PREF_INFO) {
302 field = purple_request_field_label_new("*", purple_plugin_pref_get_label(pref));
303 purple_request_field_group_add_field(group, field);
304 } else {
305 group = purple_request_field_group_new(label);
306 purple_request_fields_add_group(fields, group);
308 continue;
311 field = NULL;
312 switch(purple_prefs_get_type(name)) {
313 case PURPLE_PREF_BOOLEAN:
314 field = purple_request_field_bool_new(name, label, purple_prefs_get_bool(name));
315 break;
316 case PURPLE_PREF_INT:
317 field = purple_request_field_int_new(name, label, purple_prefs_get_int(name));
318 break;
319 case PURPLE_PREF_STRING:
320 field = purple_request_field_string_new(name, label, purple_prefs_get_string(name),
321 purple_plugin_pref_get_format_type(pref) & PURPLE_STRING_FORMAT_TYPE_MULTILINE);
322 break;
323 default:
324 break;
326 if (field) {
327 if (group == NULL) {
328 group = purple_request_field_group_new(_("Preferences"));
329 purple_request_fields_add_group(fields, group);
331 purple_request_field_group_add_field(group, field);
335 purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields,
336 _("Save"), G_CALLBACK(finch_request_save_in_prefs), _("Cancel"), NULL,
337 NULL, NULL, NULL,
338 NULL);