Statistics
| Revision:

root / trunk / client / gui / gui_plugins.c @ 1913

History | View | Annotate | Download (15 KB)

1
/* 
2
    Copyright (C) 2005-2010  Erik van Pienbroek
3

                
4
    This program is free software; you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation; either version 2 of the License, or
7
    (at your option) any later version.
8

                
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13

                
14
    You should have received a copy of the GNU General Public License
15
    along with this program; if not, write to the Free Software
16
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
*/
18

                
19
#include 
20
#include "gui.h"
21
#include "config_gui.h"
22

                
23
#ifdef HAVE_LIBPEAS
24
#include 
25
static PeasExtensionSet *extension_set = NULL;
26
#endif
27

                
28
enum {
29
    FIELD_PLUGIN_NAME,
30
    FIELD_ENABLED,
31
    FIELD_AUTO_LOAD,
32
    LAST_FIELD
33
};
34
static GtkTreeViewColumn *columns[LAST_FIELD] = { 0, 0, 0 };
35

                
36
G_MODULE_EXPORT void
37
on_btnWindowPluginsClose_clicked(GtkWidget *caller, gpointer data)
38
{
39
    GtkWidget *windowPlugins = nntpgrab_gui_base_get_widget("windowPlugins");
40

                
41
    gtk_widget_hide(windowPlugins);
42
}
43

                
44
G_MODULE_EXPORT gboolean
45
on_windowPlugins_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
46
{
47
    gtk_widget_hide(widget);
48

                
49
    return TRUE;
50
}
51

                
52
static void
53
on_tree_view_select (GtkTreeSelection *selection, gpointer user_data)
54
{
55
    NNTPGrabPluginInfo info;
56
    char *plugin_name = NULL;
57
    GtkTreeModel *model = NULL;
58
    GtkTreeIter iter;
59
    GtkWidget *labelPluginName = nntpgrab_gui_base_get_widget("labelPluginName");
60
    GtkWidget *labelPluginAuthor = nntpgrab_gui_base_get_widget("labelPluginAuthor");
61
    GtkWidget *labelPluginVersion = nntpgrab_gui_base_get_widget("labelPluginVersion");
62
    GtkWidget *linkbuttonPluginURL = nntpgrab_gui_base_get_widget("linkbuttonPluginURL");
63
    GtkWidget *labelPluginDesc = nntpgrab_gui_base_get_widget("labelPluginDesc");
64
    char name[128];
65

                
66
    if (gtk_tree_selection_count_selected_rows(selection) == 0) {
67
        // No items selected, blank everything
68
        gtk_label_set_text(GTK_LABEL(labelPluginName), "");
69
        gtk_label_set_text(GTK_LABEL(labelPluginAuthor), "");
70
        gtk_label_set_text(GTK_LABEL(labelPluginVersion), "");
71
        gtk_widget_set_sensitive(linkbuttonPluginURL, FALSE);
72
        gtk_button_set_label(GTK_BUTTON(linkbuttonPluginURL), "");
73
        gtk_label_set_text(GTK_LABEL(labelPluginDesc), "");
74
        return;
75
    }
76

                
77
    gtk_tree_selection_get_selected(selection, &model, &iter);
78
    gtk_tree_model_get(model, &iter, FIELD_PLUGIN_NAME, &plugin_name, -1);
79

                
80
    memset(&info, 0, sizeof(info));
81
    if (!nntpgrab_glue_plugins_get_plugin_info(glue, plugin_name, &info)) {
82
        g_print(__FILE__ ":%i Unable to retrieve plugin information for plugin '%s'\n", __LINE__, plugin_name);
83
        g_free(plugin_name);
84
        return;
85
    }
86

                
87
    memset(&name, 0, sizeof(name));
88
    snprintf(name, sizeof(name) - 1, "%s", info.name);
89

                
90
    gtk_label_set_markup(GTK_LABEL(labelPluginName), name);
91
    gtk_label_set_text(GTK_LABEL(labelPluginAuthor), info.author);
92
    gtk_label_set_text(GTK_LABEL(labelPluginVersion), info.version);
93
    gtk_widget_set_sensitive(linkbuttonPluginURL, TRUE);
94
    gtk_link_button_set_uri(GTK_LINK_BUTTON(linkbuttonPluginURL), info.url);
95
    gtk_button_set_label(GTK_BUTTON(linkbuttonPluginURL), info.url);
96
    gtk_label_set_text(GTK_LABEL(labelPluginDesc), info.description);
97
}
98

                
99
#ifdef HAVE_LIBPEAS
100
static void
101
try_to_load_gtk_plugin(const char *plugin_name)
102
{
103
    const GList *plugins_list;
104

                
105
    g_return_if_fail(plugin_name != NULL);
106

                
107
    /* Check if there's also an GTK plugin for this Core plugin */
108
    plugins_list = peas_engine_get_plugin_list(peas_engine_get_default());
109
    while (plugins_list) {
110
        PeasPluginInfo *info = plugins_list->data;
111

                
112
        if (!g_strcmp0(peas_plugin_info_get_name(info), plugin_name)) {
113
            /* Matching plugin found. Load it if it wasn't loaded already */
114
            if (!peas_plugin_info_is_loaded(info)) {
115
                if (!peas_engine_load_plugin(peas_engine_get_default(), info)) {
116
                    char msg[1024];
117
                    GtkWidget *windowPlugins = nntpgrab_gui_base_get_widget("windowPlugins");
118

                
119
                    memset(&msg, 0, sizeof(msg));
120
                    snprintf(msg, sizeof(msg) - 1, _("Unable to load GTK plugin '%s'"), plugin_name);
121
                    nntpgrab_gui_base_dialog_show(windowPlugins, msg, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK);
122
                }
123
            }
124
            break;
125
        }
126

                
127
        plugins_list = g_list_next(plugins_list);
128
    }
129
}
130

                
131
static void
132
on_extension_added (PeasExtensionSet *set,
133
                    PeasPluginInfo *info,
134
                    PeasExtension *exten,
135
                    gpointer data)
136
{
137
    peas_activatable_activate (PEAS_ACTIVATABLE (exten));
138
}
139

                
140
static void
141
on_extension_removed (PeasExtensionSet *set,
142
                      PeasPluginInfo *info,
143
                      PeasExtension *exten,
144
                      gpointer data)
145
{
146
    peas_activatable_deactivate (PEAS_ACTIVATABLE (exten));
147
}
148
#endif
149

                
150
static void
151
on_plugin_loaded (NntpgrabGlue *obj, const char *plugin_name, gboolean is_persistent)
152
{
153
    GtkWidget *treePlugins = nntpgrab_gui_base_get_widget("treePlugins");
154
    GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(treePlugins));
155
    GtkTreeIter iter;
156

                
157
    if (!gtk_tree_model_get_iter_first(store, &iter)) {
158
        /* Huh? Empty tree */
159
        return;
160
    }
161

                
162
    do {
163
        char *plugin_name_store = NULL;
164

                
165
        gtk_tree_model_get(store, &iter, FIELD_PLUGIN_NAME, &plugin_name_store, -1);
166

                
167
        if (!strcmp(plugin_name, plugin_name_store)) {
168
            gtk_list_store_set(GTK_LIST_STORE(store), &iter, FIELD_ENABLED, TRUE, -1);
169
            g_free(plugin_name_store);
170

                
171
#ifdef HAVE_LIBPEAS
172
            try_to_load_gtk_plugin(plugin_name);
173
#endif
174

                
175
            return;
176
        }
177

                
178
        g_free(plugin_name_store);
179
    } while (gtk_tree_model_iter_next(store, &iter));
180
}
181

                
182
static void
183
on_plugin_unloaded (NntpgrabGlue *obj, const char *plugin_name)
184
{
185
    GtkWidget *treePlugins = nntpgrab_gui_base_get_widget("treePlugins");
186
    GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(treePlugins));
187
    GtkTreeIter iter;
188

                
189
    if (!gtk_tree_model_get_iter_first(store, &iter)) {
190
        /* Huh? Empty tree */
191
        return;
192
    }
193

                
194
    do {
195
        char *plugin_name_store = NULL;
196

                
197
        gtk_tree_model_get(store, &iter, FIELD_PLUGIN_NAME, &plugin_name_store, -1);
198

                
199
        if (!strcmp(plugin_name, plugin_name_store)) {
200
            gtk_list_store_set(GTK_LIST_STORE(store), &iter, FIELD_ENABLED, FALSE, -1);
201
            g_free(plugin_name_store);
202
            return;
203
        }
204

                
205
        g_free(plugin_name_store);
206
    } while (gtk_tree_model_iter_next(store, &iter));
207
}
208

                
209
static void
210
enabled_check_toggled(GtkWidget *caller, gchar *path, gpointer data)
211
{
212
    gboolean value;
213
    GtkTreeIter iter;
214
    GtkWidget *treePlugins;
215
    GtkWidget *windowPlugins;
216
    GtkTreeModel *model;
217
    char *plugin_name = NULL;
218
    char *errmsg = NULL;
219

                
220
    treePlugins = nntpgrab_gui_base_get_widget("treePlugins");
221
    windowPlugins = nntpgrab_gui_base_get_widget("windowPlugins");
222

                
223
    model = gtk_tree_view_get_model(GTK_TREE_VIEW(treePlugins));
224

                
225
    if (gtk_tree_model_get_iter_from_string(model, &iter, path)) {
226
        gtk_tree_model_get(model, &iter, FIELD_ENABLED, &value, FIELD_PLUGIN_NAME, &plugin_name, -1);
227
        if (value) {
228
            /* Unload the plugin */
229
            if (!nntpgrab_glue_plugins_unload_plugin(glue, plugin_name, &errmsg)) {
230
                char msg[1024];
231

                
232
                memset(&msg, 0, sizeof(msg));
233
                snprintf(msg, sizeof(msg) - 1, _("Unable to unload plugin '%s': %s"), plugin_name, errmsg);
234
                nntpgrab_gui_base_dialog_show(windowPlugins, msg, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK);
235
                g_free(errmsg);
236
            }
237
        } else {
238
            /* Load the plugin */
239
            if (!nntpgrab_glue_plugins_load_plugin(glue, plugin_name, &errmsg)) {
240
                char msg[1024];
241

                
242
                memset(&msg, 0, sizeof(msg));
243
                snprintf(msg, sizeof(msg) - 1, _("Unable to load plugin '%s': %s"), plugin_name, errmsg);
244
                nntpgrab_gui_base_dialog_show(windowPlugins, msg, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK);
245
                g_free(errmsg);
246
            }
247
        }
248

                
249
        /* There's no need to update the store here as it will happen automatically when an event is emit */
250

                
251
        g_free(plugin_name);
252
    }
253
}
254

                
255
static void
256
persistent_check_toggled(GtkWidget *caller, gchar *path, gpointer data)
257
{
258
    gboolean value;
259
    GtkTreeIter iter;
260
    GtkWidget *treePlugins;
261
    GtkTreeModel *model;
262

                
263
    treePlugins = nntpgrab_gui_base_get_widget("treePlugins");
264
    model = gtk_tree_view_get_model(GTK_TREE_VIEW(treePlugins));
265

                
266
    if (gtk_tree_model_get_iter_from_string(model, &iter, path)) {
267
        char *plugin_name = NULL;
268
        ConfigGUIOpts opts;
269
        GList *list;
270

                
271
        opts = config_gui_get_opts();
272
        gtk_tree_model_get(model, &iter, FIELD_AUTO_LOAD, &value, FIELD_PLUGIN_NAME, &plugin_name, -1);
273
        if (value) {
274
            list = opts.auto_load_plugins;
275
            while (list) {
276
                char *plugin_name2 = list->data;
277

                
278
                if (!strcmp(plugin_name, plugin_name2)) {
279
                    opts.auto_load_plugins = g_list_remove(opts.auto_load_plugins, plugin_name2);
280
                    g_free(plugin_name2);
281
                    break;
282
                }
283

                
284
                list = g_list_next(list);
285
            }
286

                
287
            value = FALSE;
288
        } else {
289
            opts.auto_load_plugins = g_list_append(opts.auto_load_plugins, g_strdup(plugin_name));
290
            value = TRUE;
291
        }
292

                
293
        config_gui_set_opts(opts);
294
        gtk_list_store_set(GTK_LIST_STORE(model), &iter, FIELD_AUTO_LOAD, value, -1);
295
        g_free(plugin_name);
296
    }
297
}
298

                
299
static gboolean
300
foreach_mark_auto_load_func(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
301
{
302
    char *plugin_name = NULL;
303
    char *plugin_name2 = data;
304

                
305
    gtk_tree_model_get(model, iter, FIELD_PLUGIN_NAME, &plugin_name, -1);
306

                
307
    if (!strcmp(plugin_name, plugin_name2)) {
308
        gtk_list_store_set(GTK_LIST_STORE(model), iter, FIELD_AUTO_LOAD, TRUE, -1);
309
        return TRUE;
310
    }
311

                
312
    return FALSE;
313
}
314

                
315
void
316
gui_plugins_initialize(void)
317
{
318
    GtkListStore *store;
319
    GtkCellRenderer *cellRenderer;
320
    GtkTreeSelection *selection;
321
    NGList *plugins, *list;
322
    GtkWidget *treePlugins = nntpgrab_gui_base_get_widget("treePlugins");
323
    ngboolean beenhere = FALSE;
324
    ConfigGUIOpts opts;
325
    GList *list2;
326

                
327
    cellRenderer = gtk_cell_renderer_toggle_new();
328
    columns[FIELD_ENABLED] = gtk_tree_view_column_new_with_attributes(_("Enabled"), cellRenderer, "active", FIELD_ENABLED, NULL);
329
    gtk_tree_view_column_set_resizable(columns[FIELD_ENABLED], TRUE);
330
    gtk_tree_view_column_set_reorderable(columns[FIELD_ENABLED], TRUE);
331
    gtk_tree_view_insert_column(GTK_TREE_VIEW(treePlugins), columns[FIELD_ENABLED], -1);
332
    g_signal_connect((gpointer) cellRenderer, "toggled", G_CALLBACK(enabled_check_toggled), NULL);
333

                
334
    cellRenderer = gtk_cell_renderer_toggle_new();
335
    columns[FIELD_AUTO_LOAD] = gtk_tree_view_column_new_with_attributes(_("Load on startup"), cellRenderer, "active", FIELD_AUTO_LOAD, NULL);
336
    gtk_tree_view_column_set_resizable(columns[FIELD_AUTO_LOAD], TRUE);
337
    gtk_tree_view_column_set_reorderable(columns[FIELD_AUTO_LOAD], TRUE);
338
    gtk_tree_view_insert_column(GTK_TREE_VIEW(treePlugins), columns[FIELD_AUTO_LOAD], -1);
339
    g_signal_connect((gpointer) cellRenderer, "toggled", G_CALLBACK(persistent_check_toggled), NULL);
340

                
341
    cellRenderer = gtk_cell_renderer_text_new();
342
    columns[FIELD_PLUGIN_NAME] = gtk_tree_view_column_new_with_attributes(_("Plugin name"), cellRenderer, "text", FIELD_PLUGIN_NAME, NULL);
343
    gtk_tree_view_column_set_resizable(columns[FIELD_PLUGIN_NAME], TRUE);
344
    gtk_tree_view_column_set_reorderable(columns[FIELD_PLUGIN_NAME], TRUE);
345
    gtk_tree_view_insert_column(GTK_TREE_VIEW(treePlugins), columns[FIELD_PLUGIN_NAME], -1);
346

                
347
    store = gtk_list_store_new( LAST_FIELD,
348
                                G_TYPE_STRING    /* FIELD_PLUGIN_NAME */,
349
                                G_TYPE_BOOLEAN   /* FIELD_ENABLED */,
350
                                G_TYPE_BOOLEAN); /* FIELD_AUTO_LOAD */
351

                
352
    gtk_tree_view_set_model(GTK_TREE_VIEW(treePlugins), GTK_TREE_MODEL(store));
353

                
354
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treePlugins));
355
    gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_BROWSE);
356

                
357
#ifdef HAVE_LIBPEAS
358
    extension_set = peas_extension_set_new(peas_engine_get_default (),
359
                                           PEAS_TYPE_ACTIVATABLE,
360
                                           "object", glue,
361
                                           NULL);
362

                
363
    //peas_extension_set_call(extension_set, "activate");
364

                
365
    g_signal_connect(extension_set, "extension-added", G_CALLBACK (on_extension_added), NULL);
366
    g_signal_connect(extension_set, "extension-removed", G_CALLBACK (on_extension_removed), NULL);
367
#endif
368

                
369
    /* Fill the tree view with items */
370
    list = plugins = nntpgrab_glue_plugins_get_avail_plugins(glue);
371
    while (list) {
372
        const char *plugin_name = list->data;
373
        NNTPGrabPluginInfo info;
374
        GtkTreeIter iter;
375

                
376
        memset(&info, 0, sizeof(info));
377
        if (!nntpgrab_glue_plugins_get_plugin_info(glue, plugin_name, &info)) {
378
            g_print(__FILE__ ":%i Unable to retrieve plugin information for plugin '%s'\n", __LINE__, plugin_name);
379
            list = ng_list_next(list);
380
            continue;
381
        }
382

                
383
        gtk_list_store_append(store, &iter);
384
        gtk_list_store_set( GTK_LIST_STORE(store), &iter,
385
                            FIELD_PLUGIN_NAME, info.name,
386
                            FIELD_ENABLED, info.is_loaded,
387
                            FIELD_AUTO_LOAD, info.is_persistent,
388
                            -1);
389

                
390
        if (!beenhere) {
391
            beenhere = TRUE;
392
            gtk_tree_selection_select_iter(selection, &iter);
393
        }
394

                
395
#ifdef HAVE_LIBPEAS
396
        if (info.is_loaded) {
397
            try_to_load_gtk_plugin(plugin_name);
398
        }
399
#endif
400

                
401
        list = ng_list_next(list);
402
    }
403
    nntpgrab_glue_plugins_free_avail_plugins(glue, plugins);
404

                
405
    /* Mark the auto-load plugins */
406
    opts = config_gui_get_opts();
407
    list2 = opts.auto_load_plugins;
408
    while (list2) {
409
        char *plugin_name = list2->data;
410

                
411
        gtk_tree_model_foreach(GTK_TREE_MODEL(store), foreach_mark_auto_load_func, plugin_name);
412

                
413
        list2 = g_list_next(list2);
414
    }
415

                
416
    g_signal_connect(selection, "changed", G_CALLBACK(on_tree_view_select), NULL);
417
    on_tree_view_select(selection, NULL);
418

                
419
    nntpgrab_glue_signal_connect(glue, "plugin_loaded", NG_CALLBACK(on_plugin_loaded), NULL);
420
    nntpgrab_glue_signal_connect(glue, "plugin_unloaded", NG_CALLBACK(on_plugin_unloaded), NULL);
421
}
422

                
423
void
424
gui_plugins_cleanup(void)
425
{
426
#ifdef HAVE_LIBPEAS
427
    if (extension_set != NULL) {
428
        g_object_unref(extension_set);
429
        extension_set = NULL;
430
    }
431
#endif
432
}