1 /*****************************************************************
2 * gmerlin - a general purpose multimedia framework and applications
3 *
4 * Copyright (c) 2001 - 2011 Members of the Gmerlin project
5 * gmerlin-general@lists.sourceforge.net
6 * http://gmerlin.sourceforge.net
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * *****************************************************************/
21
22 #include <gtk/gtk.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25
26 #include <config.h>
27
28 #include <gmerlin/translation.h>
29
30 #include <gmerlin/pluginregistry.h>
31 #include <gmerlin/utils.h>
32 #include <gmerlin/cfg_dialog.h>
33
34 #include <gui_gtk/plugin.h>
35 #include <gui_gtk/gtkutils.h>
36
37 enum
38 {
39 COLUMN_PLUGIN,
40 NUM_COLUMNS
41 };
42
43 struct bg_gtk_plugin_widget_multi_s
44 {
45 GtkWidget * info_button;
46 GtkWidget * config_button;
47
48 GtkWidget * treeview;
49 GtkWidget * widget;
50 GtkWidget * protocols;
51 GtkWidget * extensions;
52 GtkWidget * priority;
53
54 bg_plugin_registry_t * reg;
55 const bg_plugin_info_t * info;
56
57 bg_parameter_info_t * parameters;
58
59 bg_cfg_section_t * section;
60
61 gulong extensions_changed_id;
62 gulong protocols_changed_id;
63 gulong priority_changed_id;
64
65 uint32_t flag_mask;
66 uint32_t type_mask;
67
68 };
69
button_callback(GtkWidget * w,gpointer data)70 static void button_callback(GtkWidget * w, gpointer data)
71 {
72 bg_gtk_plugin_widget_multi_t * win;
73 bg_dialog_t * dialog;
74
75 win = (bg_gtk_plugin_widget_multi_t *)data;
76
77 if(w == win->info_button)
78 {
79 bg_gtk_plugin_info_show(win->info, win->info_button);
80 }
81 else if(w == win->config_button)
82 {
83 dialog = bg_dialog_create(win->section,
84 NULL, NULL, NULL,
85 win->info->parameters,
86 TRD(win->info->long_name, win->info->gettext_domain));
87 bg_dialog_show(dialog, win->config_button);
88 bg_dialog_destroy(dialog);
89 }
90 }
91
select_row_callback(GtkTreeSelection * s,gpointer data)92 static void select_row_callback(GtkTreeSelection * s, gpointer data)
93 {
94 GtkTreeModel * model;
95 GtkTreeIter iter;
96
97 int selected, i;
98
99 bg_gtk_plugin_widget_multi_t * win = (bg_gtk_plugin_widget_multi_t*)data;
100
101 model = gtk_tree_view_get_model(GTK_TREE_VIEW(win->treeview));
102
103 if(!gtk_tree_model_get_iter_first(model, &iter))
104 return;
105 selected = -1;
106 i = 0;
107 while(1)
108 {
109 if(gtk_tree_selection_iter_is_selected(s, &iter))
110 {
111 selected = i;
112 break;
113 }
114 gtk_tree_model_iter_next(model, &iter);
115 i++;
116 }
117 if(selected == -1)
118 return;
119
120 win->info = bg_plugin_find_by_index(win->reg, selected, win->type_mask,
121 win->flag_mask);
122
123 if(win->info->parameters)
124 win->parameters = win->info->parameters;
125 else
126 win->parameters = NULL;
127
128 win->section = bg_plugin_registry_get_section(win->reg, win->info->name);
129
130 if(win->parameters)
131 gtk_widget_set_sensitive(win->config_button, 1);
132 else
133 gtk_widget_set_sensitive(win->config_button, 0);
134
135 if(win->extensions)
136 {
137 g_signal_handler_block(G_OBJECT(win->extensions),
138 win->extensions_changed_id);
139 if((win->info->flags & BG_PLUGIN_FILE) && win->info->extensions)
140 {
141 gtk_entry_set_text(GTK_ENTRY(win->extensions),
142 win->info->extensions);
143 gtk_widget_set_sensitive(win->extensions, 1);
144 }
145 else
146 {
147 gtk_entry_set_text(GTK_ENTRY(win->extensions), "");
148 gtk_widget_set_sensitive(win->extensions, 0);
149 }
150 g_signal_handler_unblock(G_OBJECT(win->extensions),
151 win->extensions_changed_id);
152
153 }
154 if(win->protocols)
155 {
156 g_signal_handler_block(G_OBJECT(win->protocols),
157 win->protocols_changed_id);
158 if(win->info->flags & BG_PLUGIN_URL)
159 {
160 gtk_entry_set_text(GTK_ENTRY(win->protocols),
161 win->info->protocols);
162 gtk_widget_set_sensitive(win->protocols, 1);
163 }
164 else if(win->info->flags & (BG_PLUGIN_REMOVABLE | BG_PLUGIN_TUNER))
165 {
166 gtk_entry_set_text(GTK_ENTRY(win->protocols),
167 win->info->protocols);
168 gtk_widget_set_sensitive(win->protocols, 0);
169 }
170 else
171 {
172 gtk_entry_set_text(GTK_ENTRY(win->protocols), "");
173 gtk_widget_set_sensitive(win->protocols, 0);
174 }
175 g_signal_handler_unblock(G_OBJECT(win->protocols),
176 win->protocols_changed_id);
177
178 }
179
180
181 gtk_widget_set_sensitive(win->info_button, 1);
182
183 if(win->priority)
184 {
185 g_signal_handler_block(G_OBJECT(win->priority), win->priority_changed_id);
186 gtk_spin_button_set_value(GTK_SPIN_BUTTON(win->priority), win->info->priority);
187 g_signal_handler_unblock(G_OBJECT(win->priority), win->priority_changed_id);
188
189 if(win->info->flags & (BG_PLUGIN_URL | BG_PLUGIN_FILE))
190 gtk_widget_set_sensitive(win->priority, 1);
191 else
192 gtk_widget_set_sensitive(win->priority, 0);
193 }
194 }
195
change_callback(GtkWidget * w,gpointer data)196 static void change_callback(GtkWidget * w, gpointer data)
197 {
198 bg_gtk_plugin_widget_multi_t * win = (bg_gtk_plugin_widget_multi_t*)data;
199 if(w == win->extensions)
200 {
201 bg_plugin_registry_set_extensions(win->reg, win->info->name,
202 gtk_entry_get_text(GTK_ENTRY(win->extensions)));
203 }
204 else if(w == win->protocols)
205 {
206 bg_plugin_registry_set_protocols(win->reg, win->info->name,
207 gtk_entry_get_text(GTK_ENTRY(win->protocols)));
208
209 }
210 else if(w == win->priority)
211 {
212 bg_plugin_registry_set_priority(win->reg, win->info->name,
213 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(win->priority)));
214 }
215 }
216
create_pixmap_button(const char * filename,const char * tooltip)217 static GtkWidget * create_pixmap_button(const char * filename,
218 const char * tooltip)
219 {
220 GtkWidget * button;
221 GtkWidget * image;
222 char * path;
223 path = bg_search_file_read("icons", filename);
224 if(path)
225 {
226 image = gtk_image_new_from_file(path);
227 free(path);
228 }
229 else
230 image = gtk_image_new();
231
232 gtk_widget_show(image);
233 button = gtk_button_new();
234 gtk_container_add(GTK_CONTAINER(button), image);
235
236 bg_gtk_tooltips_set_tip(button, tooltip, PACKAGE);
237
238 return button;
239 }
240
241 bg_gtk_plugin_widget_multi_t *
bg_gtk_plugin_widget_multi_create(bg_plugin_registry_t * reg,uint32_t type_mask,uint32_t flag_mask)242 bg_gtk_plugin_widget_multi_create(bg_plugin_registry_t * reg,
243 uint32_t type_mask,
244 uint32_t flag_mask)
245 {
246 bg_gtk_plugin_widget_multi_t * ret;
247 GtkListStore *store;
248 GtkTreeViewColumn *column;
249 GtkTreeIter iter;
250 GtkCellRenderer *renderer;
251 GtkWidget * label;
252 GtkWidget * scrolled;
253 GtkWidget * table;
254 GtkTreeSelection * selection;
255 GtkWidget * hbox;
256
257 const bg_plugin_info_t * info;
258
259 int num_plugins, i;
260
261 ret = calloc(1,sizeof(*ret));
262
263 ret->reg = reg;
264
265 ret->type_mask = type_mask;
266 ret->flag_mask = flag_mask;
267
268 /* Create buttons */
269
270 ret->info_button = create_pixmap_button("info_16.png", TRS("Plugin info"));
271
272 ret->config_button = create_pixmap_button("config_16.png",
273 TRS("Plugin options"));
274
275 g_signal_connect(G_OBJECT(ret->info_button),
276 "clicked", G_CALLBACK(button_callback),
277 (gpointer)ret);
278 g_signal_connect(G_OBJECT(ret->config_button),
279 "clicked", G_CALLBACK(button_callback),
280 (gpointer)ret);
281
282 gtk_widget_show(ret->info_button);
283 gtk_widget_show(ret->config_button);
284
285 /* Create list */
286
287 store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING);
288 ret->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
289
290 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ret->treeview));
291
292 g_signal_connect(G_OBJECT(selection),
293 "changed", G_CALLBACK(select_row_callback),
294 (gpointer)ret);
295
296 renderer = gtk_cell_renderer_text_new ();
297 column = gtk_tree_view_column_new_with_attributes ("Installed Plugins",
298 renderer,
299 "text",
300 COLUMN_PLUGIN,
301 NULL);
302 gtk_tree_view_column_set_sort_column_id (column, COLUMN_PLUGIN);
303 gtk_tree_view_append_column (GTK_TREE_VIEW(ret->treeview), column);
304 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(ret->treeview), FALSE);
305
306 gtk_widget_show(ret->treeview);
307
308 scrolled =
309 gtk_scrolled_window_new(gtk_tree_view_get_hadjustment(GTK_TREE_VIEW(ret->treeview)),
310 gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(ret->treeview)));
311
312 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
313 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
314 gtk_container_add(GTK_CONTAINER(scrolled), ret->treeview);
315 gtk_widget_show(scrolled);
316
317
318 /* Add Plugins */
319
320 num_plugins = bg_plugin_registry_get_num_plugins(reg,
321 type_mask,
322 flag_mask);
323
324 for(i = 0; i < num_plugins; i++)
325 {
326 info = bg_plugin_find_by_index(reg, i, type_mask, flag_mask);
327 gtk_list_store_append(store, &iter);
328 gtk_list_store_set(store, &iter,
329 COLUMN_PLUGIN,
330 TRD(info->long_name, info->gettext_domain),
331 -1);
332 }
333
334 /* Create entries */
335
336 if(type_mask & (BG_PLUGIN_INPUT | BG_PLUGIN_IMAGE_READER))
337 {
338 ret->extensions = gtk_entry_new();
339 ret->protocols = gtk_entry_new();
340 ret->priority = gtk_spin_button_new_with_range(BG_PLUGIN_PRIORITY_MIN,
341 BG_PLUGIN_PRIORITY_MAX, 1.0);
342
343 ret->extensions_changed_id =
344 g_signal_connect(G_OBJECT(ret->extensions),
345 "changed", G_CALLBACK(change_callback),
346 (gpointer)ret);
347
348 ret->protocols_changed_id =
349 g_signal_connect(G_OBJECT(ret->protocols),
350 "changed", G_CALLBACK(change_callback),
351 (gpointer)ret);
352
353 ret->priority_changed_id =
354 g_signal_connect(G_OBJECT(ret->priority),
355 "value-changed", G_CALLBACK(change_callback),
356 (gpointer)ret);
357
358
359 gtk_widget_show(ret->protocols);
360 gtk_widget_show(ret->extensions);
361 gtk_widget_show(ret->priority);
362 }
363
364
365 /* Pack stuff */
366
367 table = gtk_table_new(5, 4, 0);
368 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
369 gtk_table_set_row_spacings(GTK_TABLE(table), 5);
370 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
371
372
373
374 // gtk_table_attach_defaults(GTK_TABLE(table), scrolled, 0, 1, 0, 5);
375
376 gtk_table_attach(GTK_TABLE(table),
377 ret->config_button, 0, 1, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0);
378
379 if(ret->priority)
380 {
381 gtk_table_attach(GTK_TABLE(table),
382 ret->info_button, 1, 2, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0);
383
384 label = gtk_label_new(TR("Priority"));
385 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
386 gtk_widget_show(label);
387 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL,
388 GTK_SHRINK, 0, 0);
389 gtk_table_attach(GTK_TABLE(table), ret->priority, 3, 4, 0, 1, GTK_FILL|GTK_EXPAND,
390 GTK_SHRINK, 0, 0);
391
392
393
394 label = gtk_label_new(TR("Protocols"));
395 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
396 gtk_widget_show(label);
397 gtk_table_attach(GTK_TABLE(table), label, 0, 4, 1, 2, GTK_FILL|GTK_EXPAND,
398 GTK_SHRINK, 0, 0);
399 gtk_table_attach(GTK_TABLE(table), ret->protocols, 0, 4, 2, 3, GTK_FILL|GTK_EXPAND,
400 GTK_SHRINK, 0, 0);
401
402 label = gtk_label_new(TR("Extensions"));
403 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
404 gtk_widget_show(label);
405
406 gtk_table_attach(GTK_TABLE(table), label, 0, 4, 3, 4, GTK_FILL|GTK_EXPAND, GTK_SHRINK, 0, 0);
407 gtk_table_attach(GTK_TABLE(table),
408 ret->extensions, 0, 4, 4, 5, GTK_FILL|GTK_EXPAND, GTK_SHRINK, 0, 0);
409 }
410 else
411 {
412 gtk_table_attach(GTK_TABLE(table),
413 ret->info_button, 0, 1, 1, 2,
414 GTK_FILL, GTK_SHRINK, 0, 0);
415
416 }
417
418
419 gtk_widget_show(table);
420
421 hbox = gtk_hpaned_new();
422
423 gtk_paned_add1(GTK_PANED(hbox), scrolled);
424 gtk_paned_add2(GTK_PANED(hbox), table);
425 gtk_widget_show(hbox);
426 ret->widget = hbox;
427 /* Make things insensitive, because nothing is selected so far */
428
429 if(ret->priority)
430 gtk_widget_set_sensitive(ret->priority, 0);
431 if(ret->protocols)
432 gtk_widget_set_sensitive(ret->protocols, 0);
433
434 if(ret->extensions)
435 gtk_widget_set_sensitive(ret->extensions, 0);
436
437 gtk_widget_set_sensitive(ret->config_button, 0);
438 gtk_widget_set_sensitive(ret->info_button, 0);
439
440 return ret;
441 }
442
443 GtkWidget *
bg_gtk_plugin_widget_multi_get_widget(bg_gtk_plugin_widget_multi_t * w)444 bg_gtk_plugin_widget_multi_get_widget(bg_gtk_plugin_widget_multi_t * w)
445 {
446 return w->widget;
447 }
448
bg_gtk_plugin_widget_multi_destroy(bg_gtk_plugin_widget_multi_t * w)449 void bg_gtk_plugin_widget_multi_destroy(bg_gtk_plugin_widget_multi_t * w)
450 {
451 free(w);
452 }
453