1 /* cssed (c) Iago Rubio 2003, 2005 - A tiny CSS editor.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Library General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <string.h>
25 #include <stdio.h>
26
27 #include <gdk/gdkkeysyms.h>
28 #include <gtk/gtk.h>
29 #include <gmodule.h>
30
31 #include "cssedwindow.h"
32 #include "plugin.h"
33 #include "support.h"
34 #include "utils.h"
35
36 #define GLADE_HOOKUP_OBJECT(component,widget,name) \
37 g_object_set_data_full (G_OBJECT (component), name, \
38 gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
39
40 #define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
41 g_object_set_data (G_OBJECT (component), name, widget)
42
43 // util func
44 void
scan_and_output_dir(CssedWindow * window,gchar * dirname,GtkListStore * list_store)45 scan_and_output_dir (CssedWindow * window, gchar * dirname,
46 GtkListStore * list_store)
47 {
48 GDir *dir;
49 GError *error = NULL;
50 GPatternSpec *pattern;
51 G_CONST_RETURN gchar *filename;
52 GtkTreeIter iter;
53 CssedPlugin *plugin;
54
55 #ifdef WIN32
56 pattern = g_pattern_spec_new ("*.dll");
57 #else
58 pattern = g_pattern_spec_new ("*.so");
59 #endif
60
61 dir = g_dir_open (dirname, 0, &error);
62
63 if (dir != NULL)
64 {
65 gtk_list_store_clear (list_store);
66 filename = g_dir_read_name (dir);
67 while (filename)
68 {
69 if (g_pattern_match (pattern, strlen (filename), filename, NULL))
70 {
71 gchar *fullname = g_build_filename (dirname, filename, NULL);
72 if ((plugin =cssed_get_plugin_if_file_loaded (window, fullname)
73 ) == NULL )
74 {
75 gtk_list_store_append (list_store,
76 &iter);
77 gtk_list_store_set (list_store, &iter,
78 0, fullname,
79 1, "",
80 2, "",
81 3, FALSE,
82 -1);
83 }
84 else
85 {
86 gtk_list_store_append (list_store, &iter);
87 gtk_list_store_set (list_store, &iter,
88 0, fullname, 1,
89 plugin->name, 2,
90 plugin->
91 description, 3,
92 TRUE, -1);
93 }
94 g_free (fullname);
95 }
96 filename = g_dir_read_name (dir);
97 }
98 g_dir_close (dir);
99 g_pattern_spec_free (pattern);
100 }else{
101 g_error_free(error);
102 }
103 }
104
105 // callbacks
106 void
on_dialog_close(GtkDialog * dialog,gpointer user_data)107 on_dialog_close (GtkDialog * dialog, gpointer user_data)
108 {
109 gtk_widget_destroy (GTK_WIDGET (dialog));
110 }
111
112
113 void
on_button_refresh_clicked(GtkButton * button,gpointer user_data)114 on_button_refresh_clicked (GtkButton * button, gpointer user_data)
115 {
116 CssedWindow *window;
117 GtkTreeModel *model;
118 GtkWidget *view;
119 gchar *plugins_dir;
120
121 window = CSSED_WINDOW (user_data);
122 view = lookup_widget (GTK_WIDGET (button), "treeview_plugins");
123 model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
124
125 plugins_dir = g_build_filename(PACKAGE_LIB_DIR,"plugins", NULL);
126 scan_and_output_dir (window, plugins_dir, GTK_LIST_STORE (model));
127 g_free(plugins_dir);
128 }
129
130
131 void
on_button_load_clicked(GtkButton * button,gpointer user_data)132 on_button_load_clicked (GtkButton * button, gpointer user_data)
133 {
134 CssedWindow *window;
135 CssedPlugin *plugin;
136 GtkTreeSelection *select;
137 GtkTreeModel *model;
138 GtkTreeView *view;
139 GtkTreeIter iter;
140 gchar *path;
141
142
143 window = CSSED_WINDOW (user_data);
144 view = (GtkTreeView *) lookup_widget (GTK_WIDGET (button),
145 "treeview_plugins");
146 model = gtk_tree_view_get_model (view);
147 select = gtk_tree_view_get_selection (view);
148
149 if (gtk_tree_selection_get_selected (select, NULL, &iter))
150 {
151 gtk_tree_model_get (model, &iter, 0, &path, -1);
152 if (cssed_is_plugin_file_loaded (window, path))
153 {
154 //errmsg = g_strdup_printf (_("Plugin is loaded\n%s\n\nPlease click Refresh if the dialog shows inaccurate values"),
155 // path);
156 cssed_error_message (_("Plugin loaded"), _("Plugin is loaded\n%s\n\nPlease click Refresh if the dialog shows inaccurate values"), path);
157 //g_free (errmsg);
158 }
159 else
160 {
161 plugin = cssed_init_plugin (window, path);
162 if (plugin)
163 {
164 cssed_load_plugin (plugin);
165 gtk_list_store_set (GTK_LIST_STORE (model),
166 &iter, 0, path, 1,
167 plugin->name, 2,
168 plugin->description, 3,
169 TRUE, -1);
170 }
171 }
172 g_free (path);
173 }
174 }
175
176
177 void
on_button_unload_clicked(GtkButton * button,gpointer user_data)178 on_button_unload_clicked (GtkButton * button, gpointer user_data)
179 {
180 CssedWindow *window;
181 CssedPlugin *plugin;
182 GtkTreeSelection *select;
183 GtkTreeModel *model;
184 GtkTreeView *view;
185 GtkTreeIter iter;
186 gchar *path;
187
188
189 window = CSSED_WINDOW (user_data);
190 view = (GtkTreeView*) lookup_widget (GTK_WIDGET (button),"treeview_plugins");
191 model = gtk_tree_view_get_model (view);
192 select = gtk_tree_view_get_selection (view);
193
194 if (gtk_tree_selection_get_selected (select, NULL, &iter))
195 {
196 gtk_tree_model_get (model, &iter, 0, &path, -1);
197 if ((plugin =
198 cssed_get_plugin_if_file_loaded (window, path)) != NULL)
199 {
200 cssed_unload_plugin (plugin);
201 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
202 0, path,
203 1, "",
204 2, "",
205 3, FALSE,
206 -1);
207 }
208 else
209 {
210 //errmsg = g_strdup_printf (_("Plugin is not loaded\n%s\n\nPlease click Refresh if the dialog shows false values"), path);
211 cssed_error_message (_("Not loaded"), _("Plugin is not loaded\n%s\n\nPlease click Refresh if the dialog shows false values"));
212 //g_free (errmsg);
213 }
214 g_free (path);
215 }
216 }
217
218
219 void
on_button_close_clicked(GtkButton * button,gpointer user_data)220 on_button_close_clicked (GtkButton * button, gpointer user_data)
221 {
222 gtk_widget_destroy (GTK_WIDGET (user_data));
223 }
224
225 // create UI
226 GtkWidget *
create_plugins_dialog(CssedWindow * window)227 create_plugins_dialog (CssedWindow * window)
228 {
229 GtkWidget *dialog;
230 GtkWidget *dialog_vbox;
231 GtkWidget *scrolledwindow;
232 GtkWidget *treeview_plugins;
233 GtkWidget *dialog_action_area;
234 GtkWidget *button_refresh;
235 GtkWidget *button_load;
236 GtkWidget *alignment2;
237 GtkWidget *hbox2;
238 GtkWidget *image2;
239 GtkWidget *label2;
240 GtkWidget *button_unload;
241 GtkWidget *alignment3;
242 GtkWidget *hbox3;
243 GtkWidget *image3;
244 GtkWidget *label3;
245 GtkWidget *button_close;
246 // list store and stuff
247 GtkListStore *store;
248 GtkTreeViewColumn *col_file;
249 GtkTreeViewColumn *col_name;
250 GtkTreeViewColumn *col_description;
251 GtkTreeViewColumn *col_loaded;
252 GtkCellRenderer *text_renderer;
253 GtkCellRenderer *bool_renderer;
254 // window widget
255 GtkWidget *main_window;
256 gchar *plugins_dir;
257
258 dialog = gtk_dialog_new ();
259 gtk_window_set_title (GTK_WINDOW (dialog), _("Plugins dialog"));
260 main_window = cssed_window_get_window_widget( window );
261 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
262 gtk_window_set_default_size (GTK_WINDOW (dialog), 650, 400);
263
264 dialog_vbox = GTK_DIALOG (dialog)->vbox;
265 gtk_widget_show (dialog_vbox);
266
267 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
268 gtk_widget_show (scrolledwindow);
269 gtk_box_pack_start (GTK_BOX (dialog_vbox), scrolledwindow, TRUE, TRUE,
270 0);
271
272 treeview_plugins = gtk_tree_view_new ();
273 gtk_widget_show (treeview_plugins);
274 gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview_plugins);
275
276
277 store = gtk_list_store_new (4, G_TYPE_STRING,
278 G_TYPE_STRING,
279 G_TYPE_STRING,
280 G_TYPE_BOOLEAN);
281
282 gtk_tree_view_set_model (GTK_TREE_VIEW (treeview_plugins),
283 GTK_TREE_MODEL (store));
284 g_object_unref(store);
285
286 text_renderer = gtk_cell_renderer_text_new ();
287 bool_renderer = gtk_cell_renderer_toggle_new ();
288
289 col_file =
290 gtk_tree_view_column_new_with_attributes (_("File"),
291 text_renderer,
292 "markup", 0, NULL);
293 col_name =
294 gtk_tree_view_column_new_with_attributes (_("Name"),
295 text_renderer,
296 "markup", 1, NULL);
297 col_description =
298 gtk_tree_view_column_new_with_attributes (_("Description"),
299 text_renderer,
300 "markup", 2, NULL);
301 col_loaded =
302 gtk_tree_view_column_new_with_attributes (_("Loaded"),
303 bool_renderer,
304 "active", 3, NULL);
305
306 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_plugins),
307 TRUE);
308
309 gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview_plugins),
310 col_file, 0);
311 gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview_plugins),
312 col_name, 1);
313 gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview_plugins),
314 col_description, 2);
315 gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview_plugins),
316 col_loaded, 3);
317
318
319 dialog_action_area = GTK_DIALOG (dialog)->action_area;
320 gtk_widget_show (dialog_action_area);
321 gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area),
322 GTK_BUTTONBOX_END);
323
324 button_refresh = gtk_button_new_from_stock ("gtk-refresh");
325 gtk_widget_show (button_refresh);
326 gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button_refresh, 0);
327 GTK_WIDGET_SET_FLAGS (button_refresh, GTK_CAN_DEFAULT);
328
329 button_load = gtk_button_new ();
330 gtk_widget_show (button_load);
331 gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button_load, 0);
332 GTK_WIDGET_SET_FLAGS (button_load, GTK_CAN_DEFAULT);
333
334 alignment2 = gtk_alignment_new (0.5, 0.5, 0, 0);
335 gtk_widget_show (alignment2);
336 gtk_container_add (GTK_CONTAINER (button_load), alignment2);
337
338 hbox2 = gtk_hbox_new (FALSE, 2);
339 gtk_widget_show (hbox2);
340 gtk_container_add (GTK_CONTAINER (alignment2), hbox2);
341
342 image2 = gtk_image_new_from_stock ("gtk-yes", GTK_ICON_SIZE_BUTTON);
343 gtk_widget_show (image2);
344 gtk_box_pack_start (GTK_BOX (hbox2), image2, FALSE, FALSE, 0);
345
346 label2 = gtk_label_new_with_mnemonic (_("Load"));
347 gtk_widget_show (label2);
348 gtk_box_pack_start (GTK_BOX (hbox2), label2, FALSE, FALSE, 0);
349 gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
350
351 button_unload = gtk_button_new ();
352 gtk_widget_show (button_unload);
353 gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button_unload, 0);
354 GTK_WIDGET_SET_FLAGS (button_unload, GTK_CAN_DEFAULT);
355
356 alignment3 = gtk_alignment_new (0.5, 0.5, 0, 0);
357 gtk_widget_show (alignment3);
358 gtk_container_add (GTK_CONTAINER (button_unload), alignment3);
359
360 hbox3 = gtk_hbox_new (FALSE, 2);
361 gtk_widget_show (hbox3);
362 gtk_container_add (GTK_CONTAINER (alignment3), hbox3);
363
364 image3 = gtk_image_new_from_stock ("gtk-no", GTK_ICON_SIZE_BUTTON);
365 gtk_widget_show (image3);
366 gtk_box_pack_start (GTK_BOX (hbox3), image3, FALSE, FALSE, 0);
367
368 label3 = gtk_label_new_with_mnemonic (_("Unload"));
369 gtk_widget_show (label3);
370 gtk_box_pack_start (GTK_BOX (hbox3), label3, FALSE, FALSE, 0);
371 gtk_label_set_justify (GTK_LABEL (label3), GTK_JUSTIFY_LEFT);
372
373 button_close = gtk_button_new_from_stock ("gtk-close");
374 gtk_widget_show (button_close);
375 gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button_close,
376 GTK_RESPONSE_CLOSE);
377 GTK_WIDGET_SET_FLAGS (button_close, GTK_CAN_DEFAULT);
378
379 g_signal_connect ((gpointer) dialog, "close",
380 G_CALLBACK (on_dialog_close), NULL);
381 g_signal_connect ((gpointer) button_refresh, "clicked",
382 G_CALLBACK (on_button_refresh_clicked), window);
383 g_signal_connect ((gpointer) button_load, "clicked",
384 G_CALLBACK (on_button_load_clicked), window);
385 g_signal_connect ((gpointer) button_unload, "clicked",
386 G_CALLBACK (on_button_unload_clicked), window);
387 g_signal_connect ((gpointer) button_close, "clicked",
388 G_CALLBACK (on_button_close_clicked), dialog);
389
390 /* Store pointers to all widgets, for use by lookup_widget(). */
391 GLADE_HOOKUP_OBJECT_NO_REF (dialog, dialog, "dialog");
392 GLADE_HOOKUP_OBJECT (dialog, treeview_plugins, "treeview_plugins");
393 GLADE_HOOKUP_OBJECT (dialog, button_refresh, "button_refresh");
394 GLADE_HOOKUP_OBJECT (dialog, button_load, "button_load");
395 GLADE_HOOKUP_OBJECT (dialog, button_unload, "button_unload");
396 GLADE_HOOKUP_OBJECT (dialog, button_close, "button_close");
397
398 // fill the tree
399 plugins_dir = g_build_filename(PACKAGE_LIB_DIR,"plugins", NULL);
400 scan_and_output_dir (window, plugins_dir, GTK_LIST_STORE (store));
401 g_free(plugins_dir);
402
403 return dialog;
404 }
405
406