2
* heavily based on code from Gedit
4
* Copyright (C) 2002 Paolo Maggi and James Willcox
5
* Copyright (C) 2003-2005 Paolo Maggi
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor,
20
* Boston, MA 02110-1301 USA.
29
#include <glib/gi18n.h>
30
#include <glade/glade-xml.h>
31
#include <libgnome/gnome-url.h>
33
#include "rb-plugin-manager.h"
34
#include "rb-plugins-engine.h"
35
#include "rb-plugin.h"
37
#include "rb-glade-helpers.h"
46
#define PLUGIN_MANAGER_NAME_TITLE _("Plugin")
47
#define PLUGIN_MANAGER_ACTIVE_TITLE _("Enabled")
49
#define RB_PLUGIN_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), RB_TYPE_PLUGIN_MANAGER, RBPluginManagerPrivate))
51
struct _RBPluginManagerPrivate
56
GtkWidget *configure_button;
57
GtkWidget *site_label;
58
GtkWidget *copyright_label;
59
GtkWidget *authors_label;
60
GtkWidget *description_label;
61
GtkWidget *plugin_icon;
63
GtkWidget *copyright_text;
64
GtkWidget *authors_text;
65
GtkWidget *description_text;
66
GtkWidget *plugin_title;
69
G_DEFINE_TYPE(RBPluginManager, rb_plugin_manager, GTK_TYPE_VBOX)
71
static RBPluginInfo *plugin_manager_get_selected_plugin (RBPluginManager *pm);
72
static void plugin_manager_toggle_active (GtkTreeIter *iter, GtkTreeModel *model, RBPluginManager *pm);
73
static void plugin_manager_toggle_all (RBPluginManager *pm);
76
rb_plugin_manager_class_init (RBPluginManagerClass *klass)
78
GObjectClass *object_class = G_OBJECT_CLASS (klass);
80
g_type_class_add_private (object_class, sizeof (RBPluginManagerPrivate));
84
configure_button_cb (GtkWidget *button,
90
info = plugin_manager_get_selected_plugin (pm);
92
g_return_if_fail (info != NULL);
94
rb_debug ("Configuring: %s", rb_plugins_engine_get_plugin_name (info));
96
toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (pm)));
98
rb_plugins_engine_configure_plugin (info, toplevel);
100
rb_debug ("Done configuring plugin");
104
plugin_manager_view_cell_cb (GtkTreeViewColumn *tree_column,
105
GtkCellRenderer *cell,
106
GtkTreeModel *tree_model,
112
g_return_if_fail (tree_model != NULL);
113
g_return_if_fail (tree_column != NULL);
115
gtk_tree_model_get (tree_model, iter, NAME_COLUMN, &info, -1);
120
g_object_set (G_OBJECT (cell),
122
rb_plugins_engine_get_plugin_name (info),
127
active_toggled_cb (GtkCellRendererToggle *cell,
135
path = gtk_tree_path_new_from_string (path_str);
137
model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
138
g_return_if_fail (model != NULL);
140
if (gtk_tree_model_get_iter (model, &iter, path))
141
plugin_manager_toggle_active (&iter, model, pm);
143
gtk_tree_path_free (path);
147
cursor_changed_cb (GtkTreeSelection *selection,
150
RBPluginManager *pm = data;
155
view = gtk_tree_selection_get_tree_view (selection);
156
info = plugin_manager_get_selected_plugin (pm);
158
/* update info widgets */
159
string = g_strdup_printf ("<span size=\"x-large\">%s</span>",
160
rb_plugins_engine_get_plugin_name (info));
161
gtk_label_set_markup (GTK_LABEL (pm->priv->plugin_title), string);
163
gtk_label_set_text (GTK_LABEL (pm->priv->description_text),
164
rb_plugins_engine_get_plugin_description (info));
165
gtk_label_set_text (GTK_LABEL (pm->priv->copyright_text),
166
rb_plugins_engine_get_plugin_copyright (info));
167
gtk_label_set_text (GTK_LABEL (pm->priv->site_text),
168
rb_plugins_engine_get_plugin_website (info));
170
string = g_strjoinv ("\n", (gchar**)rb_plugins_engine_get_plugin_authors (info));
171
gtk_label_set_text (GTK_LABEL (pm->priv->authors_text), string);
174
gtk_image_set_from_pixbuf (GTK_IMAGE (pm->priv->plugin_icon),
175
rb_plugins_engine_get_plugin_icon (info));
177
gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->configure_button),
179
rb_plugins_engine_plugin_is_configurable (info));
183
row_activated_cb (GtkTreeView *tree_view,
185
GtkTreeViewColumn *column,
188
RBPluginManager *pm = data;
193
model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
194
g_return_if_fail (model != NULL);
196
found = gtk_tree_model_get_iter (model, &iter, path);
197
g_return_if_fail (found);
199
plugin_manager_toggle_active (&iter, model, pm);
203
column_clicked_cb (GtkTreeViewColumn *tree_column,
206
RBPluginManager *pm = data;
208
g_return_if_fail (pm != NULL);
210
plugin_manager_toggle_all (pm);
214
plugin_manager_populate_lists (RBPluginManager *pm)
216
const GList *plugins;
220
plugins = pm->priv->plugins;
222
model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree)));
226
info = (RBPluginInfo *)plugins->data;
228
gtk_list_store_append (model, &iter);
229
gtk_list_store_set (model, &iter,
230
ACTIVE_COLUMN, rb_plugins_engine_plugin_is_active (info),
234
plugins = plugins->next;
237
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)) {
238
GtkTreeSelection *selection;
241
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
242
g_return_if_fail (selection != NULL);
244
gtk_tree_selection_select_iter (selection, &iter);
246
gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
247
NAME_COLUMN, &info, -1);
248
/*cursor_changed_cb (selection, pm);*/
253
plugin_manager_set_active (GtkTreeIter *iter,
260
gtk_tree_model_get (model, iter, NAME_COLUMN, &info, -1);
262
g_return_if_fail (info != NULL);
265
/* activate the plugin */
266
if (!rb_plugins_engine_activate_plugin (info)) {
267
rb_debug ("Could not activate %s.", rb_plugins_engine_get_plugin_name (info));
271
/* deactivate the plugin */
272
if (!rb_plugins_engine_deactivate_plugin (info)) {
273
rb_debug ("Could not deactivate %s.", rb_plugins_engine_get_plugin_name (info));
279
gtk_list_store_set (GTK_LIST_STORE (model),
282
rb_plugins_engine_plugin_is_active (info),
285
/* cause the configure button sensitivity to be updated */
286
cursor_changed_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree)), pm);
290
plugin_manager_toggle_active (GtkTreeIter *iter,
296
gtk_tree_model_get (model, iter, ACTIVE_COLUMN, &active, -1);
299
plugin_manager_set_active (iter, model, active, pm);
302
static RBPluginInfo *
303
plugin_manager_get_selected_plugin (RBPluginManager *pm)
305
RBPluginInfo *info = NULL;
308
GtkTreeSelection *selection;
310
model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
311
g_return_val_if_fail (model != NULL, NULL);
313
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
314
g_return_val_if_fail (selection != NULL, NULL);
316
if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
317
gtk_tree_model_get (model, &iter, NAME_COLUMN, &info, -1);
324
plugin_manager_toggle_all (RBPluginManager *pm)
328
static gboolean active;
332
model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
334
g_return_if_fail (model != NULL);
336
if (gtk_tree_model_get_iter_first (model, &iter)) {
338
plugin_manager_set_active (&iter, model, active, pm);
339
} while (gtk_tree_model_iter_next (model, &iter));
343
/* Callback used as the interactive search comparison function */
345
name_search_cb (GtkTreeModel *model,
352
gchar *normalized_string;
353
gchar *normalized_key;
354
gchar *case_normalized_string;
355
gchar *case_normalized_key;
359
gtk_tree_model_get (model, iter, NAME_COLUMN, &info, -1);
363
normalized_string = g_utf8_normalize (rb_plugins_engine_get_plugin_name (info), -1, G_NORMALIZE_ALL);
364
normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
365
case_normalized_string = g_utf8_casefold (normalized_string, -1);
366
case_normalized_key = g_utf8_casefold (normalized_key, -1);
368
key_len = strlen (case_normalized_key);
370
/* Oddly enough, this callback must return whether to stop the search
371
* because we found a match, not whether we actually matched.
373
retval = (strncmp (case_normalized_key, case_normalized_string, key_len) != 0);
375
g_free (normalized_key);
376
g_free (normalized_string);
377
g_free (case_normalized_key);
378
g_free (case_normalized_string);
384
plugin_manager_construct_tree (RBPluginManager *pm)
386
GtkTreeViewColumn *column;
387
GtkCellRenderer *cell;
390
model = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_POINTER);
392
gtk_tree_view_set_model (GTK_TREE_VIEW (pm->priv->tree), GTK_TREE_MODEL (model));
393
g_object_unref (model);
395
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (pm->priv->tree), TRUE);
396
gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (pm->priv->tree), TRUE);
399
cell = gtk_cell_renderer_toggle_new ();
400
g_signal_connect (cell,
402
G_CALLBACK (active_toggled_cb),
404
column = gtk_tree_view_column_new_with_attributes (PLUGIN_MANAGER_ACTIVE_TITLE,
409
gtk_tree_view_column_set_clickable (column, TRUE);
410
gtk_tree_view_column_set_resizable (column, TRUE);
411
g_signal_connect (column, "clicked", G_CALLBACK (column_clicked_cb), pm);
412
gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column);
415
cell = gtk_cell_renderer_text_new ();
416
column = gtk_tree_view_column_new_with_attributes (PLUGIN_MANAGER_NAME_TITLE, cell, NULL);
417
gtk_tree_view_column_set_resizable (column, TRUE);
418
gtk_tree_view_column_set_cell_data_func (column, cell, plugin_manager_view_cell_cb,
420
gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column);
422
/* Enable search for our non-string column */
423
gtk_tree_view_set_search_column (GTK_TREE_VIEW (pm->priv->tree), NAME_COLUMN);
424
gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (pm->priv->tree),
429
g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree)),
431
G_CALLBACK (cursor_changed_cb),
433
g_signal_connect (pm->priv->tree,
435
G_CALLBACK (row_activated_cb),
438
gtk_widget_show (pm->priv->tree);
442
rb_plugin_manager_init (RBPluginManager *pm)
445
GtkWidget *plugins_tree_vbox;
447
pm->priv = RB_PLUGIN_MANAGER_GET_PRIVATE (pm);
449
xml = rb_glade_xml_new ("plugins.glade",
452
gtk_container_add (GTK_CONTAINER (pm), glade_xml_get_widget (xml, "plugins_vbox"));
454
gtk_box_set_spacing (GTK_BOX (pm), 6);
456
pm->priv->tree = gtk_tree_view_new ();
457
plugins_tree_vbox = glade_xml_get_widget (xml, "plugins_tree_vbox");
458
gtk_container_add (GTK_CONTAINER (plugins_tree_vbox), pm->priv->tree);
460
pm->priv->configure_button = glade_xml_get_widget (xml, "configure_button");
461
g_signal_connect (pm->priv->configure_button,
463
G_CALLBACK (configure_button_cb),
466
pm->priv->plugin_title = glade_xml_get_widget (xml, "plugin_title");
468
pm->priv->site_label = glade_xml_get_widget (xml, "site_label");
469
rb_glade_boldify_label (xml, "site_label");
470
pm->priv->copyright_label = glade_xml_get_widget (xml, "copyright_label");
471
rb_glade_boldify_label (xml, "copyright_label");
472
pm->priv->authors_label = glade_xml_get_widget (xml, "authors_label");
473
rb_glade_boldify_label (xml, "authors_label");
474
pm->priv->description_label = glade_xml_get_widget (xml, "description_label");
475
rb_glade_boldify_label (xml, "description_label");
477
pm->priv->plugin_icon = glade_xml_get_widget (xml, "plugin_icon");
478
pm->priv->site_text = glade_xml_get_widget (xml, "site_text");
479
pm->priv->copyright_text = glade_xml_get_widget (xml, "copyright_text");
480
pm->priv->authors_text = glade_xml_get_widget (xml, "authors_text");
481
pm->priv->description_text = glade_xml_get_widget (xml, "description_text");
483
plugin_manager_construct_tree (pm);
485
/* get the list of available plugins (or installed) */
486
pm->priv->plugins = rb_plugins_engine_get_plugins_list ();
488
plugin_manager_populate_lists (pm);
491
GtkWidget *rb_plugin_manager_new (void)
493
return g_object_new (RB_TYPE_PLUGIN_MANAGER, 0);