Add popup menu for some plugins.
[lxde/lxpanel.git] / src / configurator.c
CommitLineData
16fb8c2e 1/**
a99ee9e1
JH
2 * Copyright (c) 2006 LxDE Developers, see the file AUTHORS for details.
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 Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
a52c2257
HJYP
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include "plugin.h"
24#include "panel.h"
25#include "misc.h"
26#include "bg.h"
a52c2257
HJYP
27#include <stdlib.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <unistd.h>
31#include <string.h>
e7cb732b 32#include <glib/gi18n.h>
a52c2257 33
a52c2257
HJYP
34#include "dbg.h"
35
8110399f 36void configure(Panel* p);
a52c2257 37void restart(void);
08ea5341 38void gtk_run(void);
cf701cb7 39void panel_config_save(Panel* panel);
389975e0 40static void logout(void);
a52c2257 41
22242ed4 42Command commands[] = {
8110399f 43 //{ "configure", N_("Preferences"), configure },
08ea5341
HJYP
44 { "run", N_("Run"), gtk_run },
45 { "restart", N_("Restart"), restart },
389975e0 46 { "logout", N_("Logout"), logout },
a52c2257
HJYP
47 { NULL, NULL },
48};
49
cf701cb7
HJYP
50static char* file_manager_cmd = NULL;
51static char* terminal_cmd = NULL;
52static char* logout_cmd = NULL;
53
a52c2257
HJYP
54static GtkWidget *dialog = NULL;
55static GtkSizeGroup *sg;
56
57//width
58static GtkWidget *width_spinb, *width_opt;
59static GtkAdjustment *width_adj;
60
61//height
62static GtkWidget *height_spinb, *height_opt;
63static GtkAdjustment *height_adj;
64
65//margin
66static GtkWidget *margin_label, *margin_spinb;
67static GtkAdjustment *margin_adj;
68
69//allign
70static GtkWidget *allign_opt;
71
72//edge
73static GtkWidget *edge_opt;
74
75//transparency
76static GtkWidget *tr_checkb, *tr_colorl, *tr_colorb;;
77
2de71c90 78//background
781afa7b 79static GtkWidget *bg_checkdis, *bg_checkb, *bg_selfileb;
2de71c90 80
a52c2257
HJYP
81//properties
82static GtkWidget *prop_dt_checkb, *prop_st_checkb;
83
8110399f 84extern GSList* all_panels;
a52c2257
HJYP
85extern gchar *cprofile;
86extern int config;
87extern FILE *pconf;
88
cf701cb7
HJYP
89void panel_global_config_save( Panel* p, FILE *fp);
90void panel_plugin_config_save( Panel* p, FILE *fp);
a52c2257 91
bee4c26e
HJYP
92static void update_opt_menu(GtkWidget *w, int ind);
93static void update_toggle_button(GtkWidget *w, gboolean n);
389975e0 94static void modify_plugin( GtkTreeView* view );
239cb032 95static void on_entry_changed( GtkEditable* edit, gpointer user_data );
bee4c26e 96
24053345
HJYP
97/* older versions of glib don't provde these API */
98#if ! GLIB_CHECK_VERSION(2, 8, 0)
99#include <errno.h>
100
101int g_mkdir_with_parents(const gchar *pathname, int mode)
a52c2257 102{
24053345
HJYP
103 struct stat statbuf;
104 char *dir, *sep;
105 dir = g_strdup( pathname );
106 sep = dir[0] == '/' ? dir + 1 : dir;
107 do {
108 sep = strchr( sep, '/' );
109 if( G_LIKELY( sep ) )
110 *sep = '\0';
111
112 if( stat( dir, &statbuf) == 0 )
113 {
114 if( ! S_ISDIR(statbuf.st_mode) ) /* parent not dir */
115 goto err;
116 }
117 else /* stat failed */
118 {
119 if( errno == ENOENT ) /* not exists */
120 {
121 if( mkdir( dir, mode ) == -1 )
122 goto err;
123 }
124 else
125 goto err; /* unknown error */
126 }
a52c2257 127
24053345
HJYP
128 if( G_LIKELY( sep ) )
129 {
130 *sep = '/';
131 ++sep;
132 }
133 else
134 break;
135 }while( sep );
136 g_free( dir );
137 return 0;
138err:
139 g_free( dir );
140 return -1;
a52c2257 141}
24053345 142#endif
a52c2257
HJYP
143
144static void
145response_event(GtkDialog *widget, gint arg1, gpointer user_data)
146{
8110399f 147 Panel* panel = (Panel*)user_data;
a52c2257
HJYP
148 ENTER;
149 switch (arg1) {
bee4c26e
HJYP
150 /* FIXME: what will happen if the user exit lxpanel without
151 close this config dialog?
152 Then the config won't be save, I guess. */
da76d5cf
HJYP
153 case GTK_RESPONSE_DELETE_EVENT:
154 case GTK_RESPONSE_CLOSE:
155 case GTK_RESPONSE_NONE:
cf701cb7 156 panel_config_save( panel );
9c97f69e 157 /* NOTE: NO BREAK HERE*/
9c97f69e
HJYP
158 gtk_widget_destroy(dialog);
159 dialog = NULL;
a52c2257
HJYP
160 break;
161 }
162 RET();
163}
164
165static void
8110399f 166update_panel_geometry( Panel* p )
bee4c26e
HJYP
167{
168 calculate_position(p);
169 gdk_window_move_resize(p->topgwin->window, p->ax, p->ay, p->aw, p->ah);
170
171 panel_set_wm_strut( p );
172}
173
174static void
8110399f 175set_edge( GtkComboBox *widget, Panel* p )
a52c2257
HJYP
176{
177 int edge;
04883e73
HJYP
178
179 ENTER;
a52c2257 180 edge = gtk_combo_box_get_active(widget) + 1;
bee4c26e 181 p->edge = edge;
a97d06a6 182 panel_set_orientation( p );
8110399f 183 update_panel_geometry(p);
4542c20d 184 panel_update_background( p );
a52c2257
HJYP
185 RET();
186}
187
a52c2257 188static void
8110399f 189set_allign( GtkComboBox *widget, Panel* p )
a52c2257
HJYP
190{
191 int allign;
192 gboolean t;
04883e73
HJYP
193
194 ENTER;
a52c2257 195 allign = gtk_combo_box_get_active(widget) + 1;
a52c2257
HJYP
196 t = (allign != ALLIGN_CENTER);
197 gtk_widget_set_sensitive(margin_label, t);
04883e73 198 gtk_widget_set_sensitive(margin_spinb, t);
bee4c26e 199 p->allign = allign;
8110399f 200 update_panel_geometry(p);
a52c2257
HJYP
201 RET();
202}
203
bee4c26e 204static void
8110399f 205set_margin( GtkSpinButton* spin, Panel* p )
bee4c26e
HJYP
206{
207 p->margin = (int)gtk_spin_button_get_value(spin);
8110399f 208 update_panel_geometry(p);
bee4c26e
HJYP
209}
210
a52c2257
HJYP
211
212GtkWidget *
8110399f 213mk_position( Panel* p )
a52c2257
HJYP
214{
215 GtkWidget *hbox, *hbox2, *label, *frame;
216 GtkWidget *t;
04883e73
HJYP
217
218
a52c2257
HJYP
219 ENTER;
220 frame = gtk_frame_new(NULL);
221 gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_NONE);
222 gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
223 label = gtk_label_new(NULL);
e7cb732b 224 gtk_label_set_markup(GTK_LABEL (label),_("<b>Position</b>"));
04883e73 225 gtk_frame_set_label_widget(GTK_FRAME (frame), label);
a52c2257
HJYP
226
227 hbox2 = gtk_hbox_new(FALSE, 0);
228 gtk_container_set_border_width (GTK_CONTAINER (hbox2), 6);
229 gtk_container_add (GTK_CONTAINER (frame), hbox2);
04883e73 230
a52c2257
HJYP
231 hbox = gtk_hbox_new(FALSE, 0);
232 gtk_widget_set_size_request(hbox, 20, 1);
233 gtk_box_pack_start(GTK_BOX (hbox2), hbox, FALSE, TRUE, 0);
04883e73 234
a52c2257
HJYP
235 t = gtk_table_new(5, 2, FALSE);
236 gtk_table_set_row_spacings(GTK_TABLE(t), 3);
237 gtk_table_set_col_spacings(GTK_TABLE(t), 5);
238 gtk_box_pack_start(GTK_BOX (hbox2), t, FALSE, TRUE, 0);
04883e73 239
a52c2257 240 //Edge
e7cb732b 241 label = gtk_label_new(_("Edge:"));
a52c2257
HJYP
242 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
243 gtk_widget_show(label);
244 gtk_table_attach(GTK_TABLE(t), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
245 gtk_size_group_add_widget(sg, label);
04883e73 246
a52c2257 247 edge_opt = gtk_combo_box_new_text();
e7cb732b
HJYP
248 gtk_combo_box_append_text(GTK_COMBO_BOX(edge_opt), _("Left"));
249 gtk_combo_box_append_text(GTK_COMBO_BOX(edge_opt), _("Right"));
250 gtk_combo_box_append_text(GTK_COMBO_BOX(edge_opt), _("Top"));
251 gtk_combo_box_append_text(GTK_COMBO_BOX(edge_opt), _("Bottom"));
bee4c26e
HJYP
252 update_opt_menu(edge_opt, p->edge - 1);
253
a52c2257 254 g_signal_connect(G_OBJECT(edge_opt), "changed", G_CALLBACK(set_edge), NULL);
04883e73 255
a52c2257 256 gtk_widget_show(edge_opt);
04883e73 257
a52c2257
HJYP
258 hbox = gtk_hbox_new(FALSE, 0);
259 gtk_box_pack_start(GTK_BOX (hbox), edge_opt, FALSE, TRUE, 0);
260 gtk_table_attach(GTK_TABLE(t), hbox, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
261 gtk_label_set_mnemonic_widget(GTK_LABEL(label), edge_opt);
262
e7cb732b
HJYP
263 //Alignment
264 label = gtk_label_new(_("Alignment:"));
a52c2257
HJYP
265 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
266 gtk_widget_show(label);
267 gtk_size_group_add_widget(sg, label);
04883e73 268
a52c2257 269 gtk_table_attach(GTK_TABLE(t), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
04883e73 270
a52c2257 271 allign_opt = gtk_combo_box_new_text();
e7cb732b
HJYP
272 gtk_combo_box_append_text(GTK_COMBO_BOX(allign_opt), _("Left"));
273 gtk_combo_box_append_text(GTK_COMBO_BOX(allign_opt), _("Center"));
274 gtk_combo_box_append_text(GTK_COMBO_BOX(allign_opt), _("Right"));
bee4c26e 275 update_opt_menu(allign_opt, p->allign - 1);
a52c2257
HJYP
276 g_signal_connect(G_OBJECT(allign_opt), "changed", G_CALLBACK(set_allign), NULL);
277 gtk_widget_show(allign_opt);
278
279 hbox = gtk_hbox_new(FALSE, 0);
280 gtk_box_pack_start(GTK_BOX (hbox), allign_opt, FALSE, TRUE, 0);
04883e73 281 gtk_table_attach(GTK_TABLE(t), hbox, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
a52c2257
HJYP
282 gtk_label_set_mnemonic_widget(GTK_LABEL(label), allign_opt);
283
284
285 //Margin
e7cb732b 286 margin_label = gtk_label_new(_("Margin:"));
a52c2257
HJYP
287 gtk_misc_set_alignment(GTK_MISC(margin_label), 0.0, 0.5);
288 gtk_widget_show(margin_label);
289
290 gtk_table_attach(GTK_TABLE(t), margin_label, 2, 3, 1, 2, GTK_FILL, 0, 0, 0);
291
292 margin_adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, gdk_screen_width(), 1.0, 5.0, 5.0);
293 margin_spinb = gtk_spin_button_new (margin_adj, 1.0, 0);
bee4c26e
HJYP
294 gtk_spin_button_set_value(GTK_SPIN_BUTTON(margin_spinb), p->margin);
295 g_signal_connect( margin_spinb, "value-changed",
5a343ad5 296 G_CALLBACK(set_margin), NULL);
a52c2257
HJYP
297 gtk_table_attach(GTK_TABLE(t), margin_spinb, 3, 4, 1, 2, GTK_FILL, 0, 0, 0);
298 gtk_table_set_col_spacing(GTK_TABLE(t), 1, 20);
299
300 RET(frame);
301}
302
bee4c26e 303static void
8110399f 304set_width( Panel* p, GtkSpinButton* spin, gpointer user_data )
bee4c26e
HJYP
305{
306 p->width = (int)gtk_spin_button_get_value(spin);
8110399f 307 update_panel_geometry(p);
bee4c26e 308}
a52c2257
HJYP
309
310static void
8110399f 311set_height( Panel* p, GtkSpinButton* spin, gpointer user_data )
bee4c26e
HJYP
312{
313 p->height = (int)gtk_spin_button_get_value(spin);
8110399f 314 update_panel_geometry(p);
bee4c26e
HJYP
315}
316
317static void
8110399f 318set_width_type( Panel* p,GtkWidget *item, gpointer bp)
a52c2257
HJYP
319{
320 int widthtype;
321 gboolean t;
04883e73 322
a52c2257 323 ENTER;
04883e73 324
a52c2257 325 widthtype = gtk_combo_box_get_active(GTK_COMBO_BOX(item)) + 1;
bee4c26e 326 p->widthtype = widthtype;
a52c2257
HJYP
327 t = (widthtype != WIDTH_REQUEST);
328 gtk_widget_set_sensitive(width_spinb, t);
329 if (widthtype == WIDTH_PERCENT) {
330 width_adj->upper = 100;
331 width_adj->value = width_adj->upper;
332 } else if (widthtype == WIDTH_PIXEL) {
333 width_adj->upper = gdk_screen_width();
334 width_adj->value = width_adj->upper;
335 } else
336 RET();
04883e73 337
a52c2257
HJYP
338 gtk_adjustment_changed(width_adj);
339 gtk_adjustment_value_changed(width_adj);
04883e73 340
8110399f 341 update_panel_geometry(p);
a52c2257
HJYP
342 RET();
343}
344
345
8110399f
HJYP
346static GtkWidget *
347mk_size( Panel* p )
a52c2257
HJYP
348{
349 GtkWidget *hbox, *hbox2, *label, *frame;
350 GtkWidget *t;
04883e73 351
a52c2257
HJYP
352 ENTER;
353 frame = gtk_frame_new(NULL);
354 gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_NONE);
355 gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
356 label = gtk_label_new(NULL);
e7cb732b 357 gtk_label_set_markup(GTK_LABEL (label),_("<b>Size</b>"));
04883e73 358 gtk_frame_set_label_widget(GTK_FRAME (frame), label);
a52c2257
HJYP
359
360 hbox2 = gtk_hbox_new(FALSE, 0);
361 gtk_container_set_border_width (GTK_CONTAINER (hbox2), 6);
362 gtk_container_add (GTK_CONTAINER (frame), hbox2);
04883e73 363
a52c2257
HJYP
364 hbox = gtk_hbox_new(FALSE, 0);
365 gtk_widget_set_size_request(hbox, 20, 1);
366 gtk_box_pack_start(GTK_BOX (hbox2), hbox, FALSE, TRUE, 0);
04883e73 367
a52c2257
HJYP
368 t = gtk_table_new(3, 2, FALSE);
369 gtk_table_set_row_spacings(GTK_TABLE(t), 3);
370 gtk_table_set_col_spacings(GTK_TABLE(t), 5);
371 gtk_box_pack_start(GTK_BOX (hbox2), t, FALSE, TRUE, 0);
04883e73 372
a52c2257 373 //width
e7cb732b 374 label = gtk_label_new(_("Width:"));
a52c2257
HJYP
375 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
376 gtk_widget_show(label);
377 gtk_table_attach(GTK_TABLE(t), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
378 gtk_size_group_add_widget(sg, label);
04883e73 379
a52c2257
HJYP
380 width_adj = (GtkAdjustment *) gtk_adjustment_new (20.0, 0.0, 2100.0, 1.0, 5.0, 5.0);
381 width_spinb = gtk_spin_button_new (width_adj, 1.0, 0);
bee4c26e
HJYP
382 gtk_adjustment_set_value(width_adj, p->width);
383 g_signal_connect( width_spinb, "value-changed",
384 G_CALLBACK(set_width), NULL );
a52c2257 385 gtk_table_attach(GTK_TABLE(t), width_spinb, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
04883e73 386
a52c2257 387 width_opt = gtk_combo_box_new_text();
e7cb732b
HJYP
388 gtk_combo_box_append_text(GTK_COMBO_BOX(width_opt), _("dynamic"));
389 gtk_combo_box_append_text(GTK_COMBO_BOX(width_opt), _("pixels"));
390 gtk_combo_box_append_text(GTK_COMBO_BOX(width_opt), _("% of edge"));
bee4c26e
HJYP
391 update_opt_menu(width_opt, p->widthtype - 1);
392 g_signal_connect(G_OBJECT(width_opt), "changed",
393 G_CALLBACK(set_width_type), NULL);
a52c2257
HJYP
394 gtk_widget_show(width_opt);
395
a52c2257
HJYP
396 hbox = gtk_hbox_new(FALSE, 0);
397 gtk_box_pack_start(GTK_BOX (hbox), width_opt, FALSE, TRUE, 0);
398 gtk_table_attach(GTK_TABLE(t), hbox, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
399 gtk_label_set_mnemonic_widget(GTK_LABEL(label), width_opt);
400
401
402 //height
e7cb732b 403 label = gtk_label_new(_("Height:"));
a52c2257
HJYP
404 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
405 gtk_widget_show(label);
406 gtk_table_attach(GTK_TABLE(t), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
407 gtk_size_group_add_widget(sg, label);
04883e73 408
a52c2257
HJYP
409 height_adj = (GtkAdjustment *) gtk_adjustment_new (30.0, 0.0, 300.0, 1.0, 5.0, 5.0);
410 height_spinb = gtk_spin_button_new (height_adj, 1.0, 0);
bee4c26e
HJYP
411 gtk_adjustment_set_value(height_adj, p->height);
412 g_signal_connect( height_spinb, "value-changed",
413 G_CALLBACK(set_height), NULL );
a52c2257 414 gtk_table_attach(GTK_TABLE(t), height_spinb, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
04883e73 415
a52c2257 416 height_opt = gtk_combo_box_new_text();
e7cb732b 417 gtk_combo_box_append_text(GTK_COMBO_BOX(height_opt), _("pixels"));
bee4c26e 418 update_opt_menu(height_opt, HEIGHT_PIXEL - 1);
a52c2257
HJYP
419 //g_signal_connect(G_OBJECT(height_opt), "changed", G_CALLBACK(set_height), NULL);
420 gtk_widget_show(height_opt);
421
422 hbox = gtk_hbox_new(FALSE, 0);
423 gtk_box_pack_start(GTK_BOX (hbox), height_opt, FALSE, TRUE, 0);
424 gtk_table_attach(GTK_TABLE(t), hbox, 2, 3, 1, 2, GTK_FILL, 0, 0, 0);
425 gtk_label_set_mnemonic_widget(GTK_LABEL(label), height_opt);
426
427 RET(frame);
428}
429
430static void
8110399f 431transparency_toggle( GtkWidget *b, Panel* p)
a52c2257
HJYP
432{
433 gboolean t;
434
435 ENTER;
436 t = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b));
437 gtk_widget_set_sensitive(tr_colorl, t);
438 gtk_widget_set_sensitive(tr_colorb, t);
bee4c26e 439
be933927 440 /* Update background immediately. */
6576fd40
FC
441 if (t&&!p->transparent) {
442 p->transparent = 1;
4542c20d 443 p->background = 0;
4542c20d
HJYP
444 panel_update_background( p );
445 //restart();
368409ba 446 }
a52c2257
HJYP
447 RET();
448}
449
450GtkWidget *
8110399f 451mk_transparency( Panel* p )
a52c2257 452{
2de71c90 453 GtkWidget *label, *frame;
04883e73 454
a52c2257 455 ENTER;
2de71c90 456 frame = gtk_hbox_new(FALSE, 0);
04883e73 457
2de71c90 458 tr_checkb = gtk_radio_button_new_with_label(NULL, _("Enable Transparency"));
a52c2257 459 gtk_widget_show(tr_checkb);
2de71c90
FC
460 gtk_box_pack_start(GTK_BOX (frame), tr_checkb, FALSE, FALSE, 0);
461
e7cb732b 462 tr_colorl = gtk_label_new(_("Tint color:"));
a52c2257
HJYP
463 gtk_misc_set_alignment(GTK_MISC(tr_colorl), 0.0, 0.5);
464 gtk_widget_show(tr_colorl);
2de71c90 465 gtk_box_pack_start(GTK_BOX (frame), tr_colorl, FALSE, FALSE, 5);
04883e73 466
a52c2257
HJYP
467 tr_colorb = gtk_color_button_new();
468 gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(tr_colorb), TRUE);
469 gtk_color_button_set_alpha (GTK_COLOR_BUTTON(tr_colorb), 65535/256*125);
2de71c90 470 gtk_box_pack_start(GTK_BOX (frame), tr_colorb, FALSE, FALSE, 0);
bee4c26e
HJYP
471 gtk_color_button_set_color(GTK_COLOR_BUTTON(tr_colorb), &p->gtintcolor);
472 gtk_color_button_set_alpha (GTK_COLOR_BUTTON(tr_colorb), 256*p->alpha);
2de71c90
FC
473
474 if (!p->transparent) {
475 gtk_widget_set_sensitive(tr_colorb, FALSE);
476 }
477
478 RET(frame);
479}
480
481static void
8110399f 482background_toggle( GtkWidget *b, Panel* p)
2de71c90
FC
483{
484 ENTER;
485 gtk_widget_set_sensitive(bg_selfileb, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b)));
368409ba 486 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b))) {
6576fd40
FC
487 if (!p->background) {
488 p->transparent = 0;
489 p->background = 1;
be933927 490 /* Update background immediately. */
4542c20d
HJYP
491 panel_update_background( p );
492 //restart();
493 }
14f92387 494 }
2de71c90 495
2de71c90
FC
496 RET();
497}
498
499static void
8110399f 500background_changed(GtkFileChooser *file_chooser, Panel* p )
2de71c90
FC
501{
502 ENTER;
cf701cb7 503
781afa7b 504 p->transparent = 0;
1970b674 505 p->background = 1;
2de71c90 506 p->background_file = g_strdup(gtk_file_chooser_get_filename(file_chooser));
be933927 507 /* Update background immediately. */
4542c20d
HJYP
508 panel_update_background( p );
509 //restart();
2de71c90
FC
510 RET();
511}
512
513GtkWidget *
8110399f 514mk_appearanceimg( Panel* p )
2de71c90
FC
515{
516 GtkWidget *frame;
517
518 ENTER;
519 frame = gtk_vbox_new(FALSE, 0);
520
521 bg_checkb = gtk_radio_button_new_with_label(NULL, _("Enable Image:"));
67e88af2 522 gtk_box_pack_start(GTK_BOX(frame), GTK_WIDGET(bg_checkb), FALSE, FALSE, 5);
2de71c90 523
2de71c90 524 bg_selfileb = gtk_file_chooser_button_new (_("Select a background image file"), GTK_FILE_CHOOSER_ACTION_OPEN);
67e88af2 525 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (bg_selfileb), PACKAGE_DATA_DIR "/lxpanel/images");
2de71c90 526
2de71c90
FC
527 gtk_box_pack_start(GTK_BOX (frame), bg_selfileb, FALSE, FALSE, 0);
528
5b6ce65c 529 if (p->background_file)
2de71c90 530 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (bg_selfileb), p->background_file);
5b6ce65c
FC
531
532 if (!p->background)
533 gtk_widget_set_sensitive(bg_selfileb, FALSE);
2de71c90 534
92d76f06
HJYP
535 g_signal_connect (GTK_FILE_CHOOSER (bg_selfileb), "file-set", G_CALLBACK (background_changed), NULL);
536
2de71c90
FC
537 RET(frame);
538}
539
781afa7b 540static void
8110399f 541background_disable_toggle( GtkWidget *b, Panel* p )
781afa7b
FC
542{
543 ENTER;
544 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b))) {
6576fd40
FC
545 if (p->background!=0||p->transparent!=0) {
546 p->background = 0;
547 p->transparent = 0;
be933927 548 /* Update background immediately. */
4542c20d
HJYP
549 panel_update_background( p );
550 //restart();
6576fd40 551 }
781afa7b
FC
552 }
553
781afa7b
FC
554 RET();
555}
556
d2669858 557static void
8110399f 558on_font_color_set( GtkColorButton* clr, Panel* p )
d2669858 559{
cf701cb7
HJYP
560 gtk_color_button_get_color( clr, &p->gfontcolor );
561 /* FIXME: need some better mechanism to update the panel */
562 if( p->usefontcolor )
563 gtk_widget_queue_draw( p->topgwin );
d2669858
HJYP
564}
565
cf701cb7 566static void
8110399f 567on_use_font_color_toggled( GtkToggleButton* btn, Panel* p )
d2669858 568{
cf701cb7
HJYP
569 GtkWidget* clr = (GtkWidget*)g_object_get_data( btn, "clr" );
570 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(btn)))
571 gtk_widget_set_sensitive( clr, TRUE );
572 else
573 gtk_widget_set_sensitive( clr, FALSE );
574 p->usefontcolor = gtk_toggle_button_get_active( btn );
575 /* FIXME: need some better mechanism to update the panel */
576 gtk_widget_queue_draw( p->topgwin );
d2669858
HJYP
577}
578
2de71c90 579GtkWidget *
8110399f 580mk_appearance( Panel* p )
2de71c90 581{
d2669858 582 GtkWidget *top_vbox, *vbox, *vbox2, *label, *frame, *incframe, *hbox, *fnt, *clr, *use_fnt_clr;
781afa7b 583 GSList *check_group;
2de71c90
FC
584
585 ENTER;
d2669858
HJYP
586 top_vbox = gtk_vbox_new( FALSE, 1 );
587
2de71c90 588 frame = gtk_frame_new(NULL);
d2669858
HJYP
589 gtk_box_pack_start( (GtkBox*)top_vbox, frame, FALSE, TRUE, 0 );
590
2de71c90
FC
591 gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_NONE);
592 gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
593 label = gtk_label_new(NULL);
594 gtk_label_set_markup(GTK_LABEL (label),_("<b>Background</b>"));
595 gtk_frame_set_label_widget(GTK_FRAME (frame), label);
596
597 vbox2 = gtk_vbox_new(FALSE, 0);
598 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6);
599 gtk_container_add (GTK_CONTAINER (frame), vbox2);
600
601 vbox = gtk_vbox_new(FALSE, 0);
602 gtk_box_pack_start(GTK_BOX (vbox2), vbox, FALSE, TRUE, 0);
603 gtk_widget_set_size_request(vbox, 20, 1);
604
605 vbox = gtk_vbox_new(FALSE, 5);
606 gtk_box_pack_start(GTK_BOX (vbox2), vbox, FALSE, TRUE, 0);
607
781afa7b
FC
608 /* Disable Background option */
609 bg_checkdis = gtk_radio_button_new_with_label(NULL, _("None (Use system theme)"));
610 gtk_widget_show(bg_checkdis);
611
612 gtk_box_pack_start(GTK_BOX (vbox), bg_checkdis, FALSE, FALSE, 0);
613
8110399f 614 incframe = mk_transparency( p );
2de71c90
FC
615 gtk_box_pack_start(GTK_BOX (vbox), incframe, FALSE, FALSE, 0);
616
8110399f 617 incframe = mk_appearanceimg( p );
2de71c90
FC
618 gtk_box_pack_start(GTK_BOX (vbox), incframe, FALSE, FALSE, 0);
619
620 /* set group */
781afa7b 621 check_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(bg_checkdis));
67e88af2 622 gtk_radio_button_set_group(GTK_RADIO_BUTTON(bg_checkb), check_group);
781afa7b 623 check_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(bg_checkb));
67e88af2 624 gtk_radio_button_set_group(GTK_RADIO_BUTTON(tr_checkb), check_group);
781afa7b
FC
625
626 /* default */
627 if (p->background)
628 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bg_checkb), TRUE);
629 else if (p->transparent)
630 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tr_checkb), TRUE);
631 else
632 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bg_checkdis), TRUE);
633
d2669858
HJYP
634 frame = gtk_frame_new(NULL);
635 gtk_box_pack_start( (GtkBox*)top_vbox, frame, FALSE, TRUE, 0 );
781afa7b 636
d2669858
HJYP
637 gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_NONE);
638 gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
639 label = gtk_label_new(NULL);
640 gtk_label_set_markup(GTK_LABEL (label),_("<b>Font</b>"));
641 gtk_frame_set_label_widget(GTK_FRAME (frame), label);
642
643 hbox = gtk_hbox_new(FALSE, 0);
644 gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
645 gtk_container_add (GTK_CONTAINER (frame), hbox);
646
cf701cb7
HJYP
647// fnt = gtk_font_button_new();
648// gtk_box_pack_start( (GtkBox*)hbox, fnt, TRUE, TRUE, 4 );
d2669858 649
cf701cb7
HJYP
650 use_fnt_clr = gtk_check_button_new_with_label( _("Custom Color") );
651 gtk_box_pack_start( (GtkBox*)hbox, use_fnt_clr, FALSE, FALSE, 4 );
652 gtk_toggle_button_set_active( (GtkToggleButton*) use_fnt_clr, p->usefontcolor );
d2669858 653
cf701cb7
HJYP
654 clr = gtk_color_button_new();
655 gtk_box_pack_start( (GtkBox*)hbox, clr, FALSE, FALSE, 4 );
656 gtk_color_button_set_color( (GtkColorButton*)clr, &p->gfontcolor );
657 g_signal_connect( clr, "color-set", G_CALLBACK( on_use_font_color_toggled ), p );
d2669858 658
cf701cb7 659 gtk_widget_show_all( top_vbox );
d2669858 660
cf701cb7
HJYP
661 /* background */
662 g_signal_connect(bg_checkdis, "toggled", G_CALLBACK(background_disable_toggle), p);
663 g_signal_connect(bg_checkb, "toggled", G_CALLBACK(background_toggle), p);
664 g_signal_connect(tr_checkb, "toggled", G_CALLBACK(transparency_toggle), p);
d2669858 665
cf701cb7
HJYP
666 /* font */
667 g_object_set_data( use_fnt_clr, "clr", clr );
668 g_signal_connect(use_fnt_clr, "toggled", G_CALLBACK(on_use_font_color_toggled), p);
1b2208cb 669
d2669858 670 RET(top_vbox);
a52c2257
HJYP
671}
672
bee4c26e 673static void
8110399f 674set_dock_type(GtkToggleButton* toggle, Panel* p )
bee4c26e
HJYP
675{
676 p->setdocktype = gtk_toggle_button_get_active(toggle) ? 1 : 0;
677 panel_set_dock_type( p );
8110399f 678 update_panel_geometry(p);
bee4c26e
HJYP
679 /* FIXME: apparently, this doesn't work,
680 but we don't know the reason yet! */
681}
682
683static void
8110399f 684set_struct(GtkToggleButton* toggle, Panel* p )
bee4c26e
HJYP
685{
686 p->setstrut = gtk_toggle_button_get_active(toggle) ? 1 : 0;
8110399f 687 update_panel_geometry(p);
bee4c26e
HJYP
688}
689
a52c2257 690GtkWidget *
8110399f 691mk_properties( Panel* p )
a52c2257
HJYP
692{
693 GtkWidget *vbox, *hbox, *hbox2, *label, *frame;
04883e73 694
a52c2257
HJYP
695 ENTER;
696 frame = gtk_frame_new(NULL);
697 gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_NONE);
698 gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
699 label = gtk_label_new(NULL);
e7cb732b 700 gtk_label_set_markup(GTK_LABEL (label),_("<b>Properties</b>"));
04883e73 701 gtk_frame_set_label_widget(GTK_FRAME (frame), label);
a52c2257
HJYP
702
703 hbox2 = gtk_hbox_new(FALSE, 0);
704 gtk_container_add (GTK_CONTAINER (frame), hbox2);
705 gtk_container_set_border_width (GTK_CONTAINER (hbox2), 6);
04883e73 706
a52c2257
HJYP
707 hbox = gtk_hbox_new(FALSE, 0);
708 gtk_box_pack_start(GTK_BOX (hbox2), hbox, FALSE, TRUE, 0);
709 gtk_widget_set_size_request(hbox, 20, 1);
710
711 vbox = gtk_vbox_new(FALSE, 0);
712 gtk_box_pack_start(GTK_BOX (hbox2), vbox, FALSE, TRUE, 0);
04883e73 713
239cb032
HJYP
714 /* Explaination from Ruediger Arp <ruediger@gmx.net>:
715 "Set Dock Type", it is referring to the behaviour of
716 dockable applications such as those found in WindowMaker (e.g.
717 http://www.cs.mun.ca/~gstarkes/wmaker/dockapps ) and other
718 lightweight window managers. These dockapps are probably being
719 treated in some special way.
720 */
721 prop_dt_checkb = gtk_check_button_new_with_label(
722 _("Make window managers treat the panel as dock"));
bee4c26e
HJYP
723 update_toggle_button(prop_dt_checkb, p->setdocktype);
724 g_signal_connect( prop_dt_checkb, "toggled",
725 G_CALLBACK(set_dock_type), NULL );
a52c2257
HJYP
726 gtk_box_pack_start(GTK_BOX (vbox), prop_dt_checkb, FALSE, FALSE, 0);
727
239cb032
HJYP
728 /* Explaination from Ruediger Arp <ruediger@gmx.net>:
729 "Set Strut": Reserve panel's space so that it will not be
730 covered by maximazied windows.
731 This is clearly an option to avoid the panel being
732 covered/hidden by other applications so that it always is
733 accessible. The panel "steals" some screen estate which cannot
734 be accessed by other applications.
735 GNOME Panel acts this way, too.
736 */
737 prop_st_checkb = gtk_check_button_new_with_label(
738 _("Reserve space, and not covered by maximized windows"));
bee4c26e
HJYP
739 update_toggle_button(prop_st_checkb, p->setstrut);
740 g_signal_connect( prop_st_checkb, "toggled",
741 G_CALLBACK(set_struct), NULL );
a52c2257
HJYP
742 gtk_box_pack_start(GTK_BOX (vbox), prop_st_checkb, FALSE, FALSE, 0);
743
744 RET(frame);
745}
746
747static void
748dialog_destroy_event(GtkWidget * widget, GdkEvent * event, gpointer data)
749{
04883e73 750 ENTER;
a52c2257
HJYP
751 dialog = NULL;
752 RET();
753}
754
755static gint
756dialog_delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
757{
758
04883e73 759 ENTER;
a52c2257
HJYP
760 //if (!p->self_destroy)
761 RET(FALSE);
762}
763
ce522551 764static void
04883e73 765on_sel_plugin_changed( GtkTreeSelection* tree_sel, GtkWidget* label )
a52c2257 766{
8ccd023a
HJYP
767 GtkTreeIter it;
768 GtkTreeModel* model;
22242ed4 769 Plugin* pl;
a52c2257 770
8ccd023a
HJYP
771 if( gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
772 {
cfc83537 773 GtkTreeView* view = gtk_tree_selection_get_tree_view( tree_sel );
5a343ad5 774 GtkWidget *edit_btn = GTK_WIDGET(g_object_get_data( G_OBJECT(view), "edit_btn" ));
8ccd023a 775 gtk_tree_model_get( model, &it, 1, &pl, -1 );
5a343ad5 776 gtk_label_set_text( GTK_LABEL(label), _(pl->class->description) );
cfc83537 777 gtk_widget_set_sensitive( edit_btn, pl->class->config != NULL );
8ccd023a 778 }
ce522551 779}
a52c2257 780
8110399f 781static void init_plugin_list( Panel* p, GtkTreeView* view, GtkWidget* label )
ce522551 782{
ce522551
HJYP
783 GtkListStore* list;
784 GtkTreeViewColumn* col;
785 GtkCellRenderer* render;
786 GtkTreeSelection* tree_sel;
787 GList* l;
8ccd023a 788 GtkTreeIter it;
ce522551 789
cf701cb7 790 g_object_set_data( view, "panel", p );
8110399f 791
ce522551
HJYP
792 render = gtk_cell_renderer_text_new();
793 col = gtk_tree_view_column_new_with_attributes(
794 _("Currently loaded plugins"),
795 render, "text", 0, NULL );
796 gtk_tree_view_append_column( view, col );
797
798 list = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_POINTER );
799 for( l = p->plugins; l; l = l->next )
800 {
801 GtkTreeIter it;
22242ed4 802 Plugin* pl = (Plugin*)l->data;
ce522551
HJYP
803 gtk_list_store_append( list, &it );
804 gtk_list_store_set( list, &it,
805 0, _(pl->class->name),
806 1, pl, -1);
807 }
808 gtk_tree_view_set_model( view, GTK_TREE_MODEL( list ) );
389975e0
HJYP
809 g_signal_connect( view, "row-activated",
810 G_CALLBACK(modify_plugin), NULL );
ce522551 811 tree_sel = gtk_tree_view_get_selection( view );
16fb8c2e 812 gtk_tree_selection_set_mode( tree_sel, GTK_SELECTION_BROWSE );
ce522551 813 g_signal_connect( tree_sel, "changed",
04883e73 814 G_CALLBACK(on_sel_plugin_changed), label);
8ccd023a
HJYP
815 if( gtk_tree_model_get_iter_first( GTK_TREE_MODEL(list), &it ) )
816 gtk_tree_selection_select_iter( tree_sel, &it );
ce522551
HJYP
817}
818
16fb8c2e
HJYP
819static void on_add_plugin_response( GtkDialog* dlg,
820 int response,
821 GtkTreeView* _view )
ce522551 822{
cf701cb7 823 Panel* p = (Panel*) g_object_get_data( _view, "panel" );
16fb8c2e
HJYP
824 if( response == GTK_RESPONSE_OK )
825 {
826 GtkTreeView* view;
827 GtkTreeSelection* tree_sel;
828 GtkTreeIter it;
829 GtkTreeModel* model;
830
67e88af2 831 view = (GtkTreeView*)g_object_get_data( G_OBJECT(dlg), "avail-plugins" );
16fb8c2e
HJYP
832 tree_sel = gtk_tree_view_get_selection( view );
833 if( gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
834 {
835 char* type = NULL;
22242ed4 836 Plugin* pl;
16fb8c2e
HJYP
837 gtk_tree_model_get( model, &it, 1, &type, -1 );
838 if( pl = plugin_load( type ) )
839 {
1d0f0857
HJYP
840 GtkTreePath* tree_path;
841
16fb8c2e
HJYP
842 pl->panel = p;
843 plugin_start( pl, NULL );
1d0f0857 844 p->plugins = g_list_append(p->plugins, pl);
5297da29
HJYP
845 /* FIXME: will show all cause problems? */
846 gtk_widget_show_all( pl->pwid );
1d0f0857 847
cf701cb7 848 /* update background of the newly added plugin */
f37da9d7
HJYP
849 plugin_widget_set_background( pl->pwid, pl->panel );
850
1d0f0857
HJYP
851 model = gtk_tree_view_get_model( _view );
852 gtk_list_store_append( (GtkListStore*)model, &it );
853 gtk_list_store_set( (GtkListStore*)model, &it,
854 0, _(pl->class->name),
855 1, pl, -1 );
856 tree_sel = gtk_tree_view_get_selection( _view );
857 gtk_tree_selection_select_iter( tree_sel, &it );
858 if( tree_path = gtk_tree_model_get_path( model, &it ) )
859 {
860 gtk_tree_view_scroll_to_cell( _view, tree_path, NULL, FALSE, 0, 0 );
861 gtk_tree_path_free( tree_path );
862 }
16fb8c2e
HJYP
863 }
864 g_free( type );
865 }
866 }
1d0f0857
HJYP
867/*
868 gtk_widget_set_sensitive( (GtkWidget*)gtk_window_get_transient_for( (GtkWindow*)dlg ),
869 TRUE );
870*/
16fb8c2e
HJYP
871 gtk_widget_destroy( (GtkWidget*)dlg );
872}
873
874static void on_add_plugin( GtkButton* btn, GtkTreeView* _view )
875{
876 GtkWidget* dlg, *parent_win, *scroll;
877 GList* classes;
6a6ad54e 878 GList* tmp;
16fb8c2e
HJYP
879 GtkTreeViewColumn* col;
880 GtkCellRenderer* render;
881 GtkTreeView* view;
882 GtkListStore* list;
883 GtkTreeSelection* tree_sel;
884
cf701cb7 885 Panel* p = (Panel*) g_object_get_data( _view, "panel" );
8110399f 886
16fb8c2e
HJYP
887 classes = plugin_get_available_classes();
888
889 parent_win = gtk_widget_get_toplevel( (GtkWidget*)_view );
890 dlg = gtk_dialog_new_with_buttons( _("Add plugin to panel"),
67e88af2 891 GTK_WINDOW(parent_win), 0,
16fb8c2e
HJYP
892 GTK_STOCK_CANCEL,
893 GTK_RESPONSE_CANCEL,
894 GTK_STOCK_ADD,
895 GTK_RESPONSE_OK, NULL );
5420dd00
FC
896
897 /* fix background */
5b6ce65c
FC
898 if (p->background)
899 gtk_widget_set_style(dlg, p->defstyle);
5420dd00 900
1d0f0857 901 /* gtk_widget_set_sensitive( parent_win, FALSE ); */
16fb8c2e
HJYP
902 scroll = gtk_scrolled_window_new( NULL, NULL );
903 gtk_scrolled_window_set_shadow_type( (GtkScrolledWindow*)scroll,
904 GTK_SHADOW_IN );
905 gtk_scrolled_window_set_policy((GtkScrolledWindow*)scroll,
906 GTK_POLICY_AUTOMATIC,
907 GTK_POLICY_AUTOMATIC );
908 gtk_box_pack_start( (GtkBox*)GTK_DIALOG(dlg)->vbox, scroll,
909 TRUE, TRUE, 4 );
67e88af2 910 view = (GtkTreeView*)gtk_tree_view_new();
16fb8c2e
HJYP
911 gtk_container_add( (GtkContainer*)scroll, view );
912 tree_sel = gtk_tree_view_get_selection( view );
913 gtk_tree_selection_set_mode( tree_sel, GTK_SELECTION_BROWSE );
914
915 render = gtk_cell_renderer_text_new();
916 col = gtk_tree_view_column_new_with_attributes(
917 _("Available plugins"),
918 render, "text", 0, NULL );
919 gtk_tree_view_append_column( view, col );
920
921 list = gtk_list_store_new( 2,
922 G_TYPE_STRING,
923 G_TYPE_STRING );
924
6a6ad54e 925 for( tmp = classes; tmp; tmp = tmp->next ) {
22242ed4 926 PluginClass* pc = (PluginClass*)tmp->data;
16fb8c2e
HJYP
927 if( ! pc->invisible ) {
928 /* FIXME: should we display invisible plugins? */
929 GtkTreeIter it;
930 gtk_list_store_append( list, &it );
931 gtk_list_store_set( list, &it,
932 0, _(pc->name),
933 1, pc->type, -1 );
934 /* g_debug( "%s (%s)", pc->type, _(pc->name) ); */
935 }
6a6ad54e 936 }
16fb8c2e
HJYP
937
938 gtk_tree_view_set_model( view, GTK_TREE_MODEL(list) );
939 g_object_unref( list );
940
941 g_signal_connect( dlg, "response",
942 on_add_plugin_response, _view );
943 g_object_set_data( dlg, "avail-plugins", view );
944 g_object_weak_ref( dlg, plugin_class_list_free, classes );
945
1d0f0857 946 gtk_window_set_default_size( (GtkWindow*)dlg, 320, 400 );
16fb8c2e 947 gtk_widget_show_all( dlg );
ce522551
HJYP
948}
949
04883e73 950static void on_remove_plugin( GtkButton* btn, GtkTreeView* view )
ce522551 951{
8ccd023a
HJYP
952 GtkTreeIter it;
953 GtkTreePath* tree_path;
954 GtkTreeModel* model;
955 GtkTreeSelection* tree_sel = gtk_tree_view_get_selection( view );
22242ed4 956 Plugin* pl;
ce522551 957
cf701cb7 958 Panel* p = (Panel*) g_object_get_data( view, "panel" );
8110399f 959
8ccd023a
HJYP
960 if( gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
961 {
962 tree_path = gtk_tree_model_get_path( model, &it );
963 gtk_tree_model_get( model, &it, 1, &pl, -1 );
964 if( gtk_tree_path_get_indices(tree_path)[0] >= gtk_tree_model_iter_n_children( model, NULL ) )
965 gtk_tree_path_prev( tree_path );
966 gtk_list_store_remove( GTK_LIST_STORE(model), &it );
967 p->plugins = g_list_remove( p->plugins, pl );
968 plugin_stop( pl ); /* free the plugin widget & its data */
4542c20d 969 plugin_put( pl ); /* free the lib if necessary */
8ccd023a
HJYP
970
971 gtk_tree_selection_select_path( tree_sel, tree_path );
972 gtk_tree_path_free( tree_path );
973 }
ce522551
HJYP
974}
975
389975e0 976void modify_plugin( GtkTreeView* view )
04883e73
HJYP
977{
978 GtkTreeSelection* tree_sel = gtk_tree_view_get_selection( view );
979 GtkTreeModel* model;
980 GtkTreeIter it;
22242ed4 981 Plugin* pl;
04883e73
HJYP
982
983 if( ! gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
984 return;
985
986 gtk_tree_model_get( model, &it, 1, &pl, -1 );
987 if( pl->class->config )
5a343ad5 988 pl->class->config( pl, (GtkWindow*)gtk_widget_get_toplevel(GTK_WIDGET(view)) );
04883e73
HJYP
989}
990
cf701cb7 991static int get_widget_index( Panel* p, Plugin* pl )
ce522551
HJYP
992{
993 GList* l;
994 int i;
995 for( i = 0, l = p->plugins; l; l = l->next )
996 {
22242ed4 997 Plugin* _pl = (Plugin*)l->data;
ce522551
HJYP
998 if( _pl == pl )
999 return i;
1000 if( _pl->pwid )
1001 ++i;
1002 }
1003 return -1;
1004}
1005
1006static void on_moveup_plugin( GtkButton* btn, GtkTreeView* view )
1007{
1008 GList *l;
1009 GtkTreeIter it, prev;
1010 GtkTreeModel* model = gtk_tree_view_get_model( view );
1011 GtkTreeSelection* tree_sel = gtk_tree_view_get_selection( view );
1012 int i;
1013
cf701cb7 1014 Panel* panel = (Panel*) g_object_get_data( view, "panel" );
8110399f 1015
ce522551
HJYP
1016 if( ! gtk_tree_model_get_iter_first( model, &it ) )
1017 return;
1018 if( gtk_tree_selection_iter_is_selected( tree_sel, &it ) )
1019 return;
1020 do{
1021 if( gtk_tree_selection_iter_is_selected(tree_sel, &it) )
1022 {
22242ed4 1023 Plugin* pl;
ce522551
HJYP
1024 gtk_tree_model_get( model, &it, 1, &pl, -1 );
1025 gtk_list_store_move_before( GTK_LIST_STORE( model ),
1026 &it, &prev );
1027
1028 i = 0;
8110399f 1029 for( l = panel->plugins; l; l = l->next, ++i )
ce522551
HJYP
1030 {
1031 if( l->data == pl )
1032 {
8110399f
HJYP
1033 panel->plugins = g_list_insert( panel->plugins, pl, i - 1);
1034 panel->plugins = g_list_delete_link( panel->plugins, l);
ce522551
HJYP
1035 }
1036 }
1037 if( pl->pwid )
1038 {
8110399f 1039 gtk_box_reorder_child( GTK_BOX(panel->box), pl->pwid, get_widget_index( panel, pl ) );
ce522551
HJYP
1040 }
1041 return;
1042 }
1043 prev = it;
1044 }while( gtk_tree_model_iter_next( model, &it ) );
1045}
1046
1047static void on_movedown_plugin( GtkButton* btn, GtkTreeView* view )
1048{
1049 GList *l;
1050 GtkTreeIter it, next;
1051 GtkTreeModel* model;
1052 GtkTreeSelection* tree_sel = gtk_tree_view_get_selection( view );
22242ed4 1053 Plugin* pl;
ce522551
HJYP
1054 int i;
1055
cf701cb7 1056 Panel* panel = (Panel*) g_object_get_data( view, "panel" );
8110399f 1057
ce522551
HJYP
1058 if( ! gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
1059 return;
1060 next = it;
1061
1062 if( ! gtk_tree_model_iter_next( model, &next) )
1063 return;
1064
1065 gtk_tree_model_get( model, &it, 1, &pl, -1 );
1066
1067 gtk_list_store_move_after( GTK_LIST_STORE( model ), &it, &next );
1068
1069 i = 0;
8110399f 1070 for( l = panel->plugins; l; l = l->next, ++i )
ce522551
HJYP
1071 {
1072 if( l->data == pl )
1073 {
8110399f
HJYP
1074 panel->plugins = g_list_insert( panel->plugins, pl, i + 2);
1075 panel->plugins = g_list_delete_link( panel->plugins, l);
ce522551
HJYP
1076 }
1077 }
1078 if( pl->pwid )
1079 {
8110399f 1080 gtk_box_reorder_child( GTK_BOX(panel->box), pl->pwid, get_widget_index( panel, pl ) );
ce522551
HJYP
1081 }
1082}
1083
1084static GtkWidget *
8110399f 1085mk_tab_plugins( Panel* p )
ce522551 1086{
5a343ad5
JH
1087 GtkWidget *hbox, *vbox, *label;
1088 GtkWidget *scroll, *plugin_list, *button;
ce522551 1089
04883e73 1090 hbox = gtk_hbox_new( FALSE, 2 );
239cb032 1091 gtk_container_set_border_width( (GtkContainer*)hbox, 4 );
04883e73 1092
ce522551 1093 vbox = gtk_vbox_new( FALSE, 2 );
5a343ad5 1094 gtk_box_pack_start( GTK_BOX(hbox), vbox, TRUE, TRUE, 2 );
ce522551
HJYP
1095
1096 /* Left pane */
1097 plugin_list = gtk_tree_view_new();
1098 /* plugin list */
1099 scroll = gtk_scrolled_window_new(NULL, NULL);
16fb8c2e 1100 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scroll),
92d76f06
HJYP
1101 GTK_POLICY_AUTOMATIC,
1102 GTK_POLICY_AUTOMATIC);
16fb8c2e 1103 gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(scroll),
92d76f06 1104 GTK_SHADOW_IN );
ce522551
HJYP
1105 gtk_container_add( GTK_CONTAINER(scroll), plugin_list );
1106 gtk_box_pack_start( GTK_BOX( vbox ), scroll, TRUE, TRUE, 4 );
1107
04883e73
HJYP
1108 /* Label displaying plugin descriptions */
1109 label = gtk_label_new("");
1110 gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
1111
1112 gtk_box_pack_start( GTK_BOX(vbox), label, FALSE, FALSE, 4 );
1113
1114 vbox = gtk_vbox_new( FALSE, 2 );
1115 gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 2 );
1116
ce522551 1117 /* buttons used to edit plugin list */
04883e73
HJYP
1118 button = gtk_button_new_from_stock( GTK_STOCK_ADD );
1119 gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 2 );
ce522551
HJYP
1120 g_signal_connect( button, "clicked", G_CALLBACK(on_add_plugin), plugin_list );
1121
04883e73
HJYP
1122 button = gtk_button_new_from_stock( GTK_STOCK_EDIT );
1123 gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 2 );
389975e0 1124 g_signal_connect_swapped( button, "clicked", G_CALLBACK(modify_plugin), plugin_list );
5a343ad5 1125 g_object_set_data( G_OBJECT(plugin_list), "edit_btn", button );
04883e73
HJYP
1126
1127 button = gtk_button_new_from_stock( GTK_STOCK_REMOVE );
1128 gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 2 );
ce522551
HJYP
1129 g_signal_connect( button, "clicked", G_CALLBACK(on_remove_plugin), plugin_list );
1130
1131 button = gtk_button_new();
16fb8c2e 1132 gtk_container_add( GTK_CONTAINER(button),
92d76f06
HJYP
1133 gtk_image_new_from_stock(GTK_STOCK_GO_UP,
1134 GTK_ICON_SIZE_BUTTON) );
04883e73 1135 gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 2 );
ce522551
HJYP
1136 g_signal_connect( button, "clicked", G_CALLBACK(on_moveup_plugin), plugin_list );
1137
1138 button = gtk_button_new();
16fb8c2e 1139 gtk_container_add( GTK_CONTAINER(button),
92d76f06
HJYP
1140 gtk_image_new_from_stock(GTK_STOCK_GO_DOWN,
1141 GTK_ICON_SIZE_BUTTON) );
04883e73 1142 gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 2 );
ce522551
HJYP
1143 g_signal_connect( button, "clicked", G_CALLBACK(on_movedown_plugin), plugin_list );
1144
8110399f 1145 init_plugin_list( p, GTK_TREE_VIEW( plugin_list ), label );
a52c2257 1146
04883e73 1147 RET(hbox);
a52c2257
HJYP
1148}
1149
1150static GtkWidget *
8110399f 1151mk_tab_general( Panel* p )
a52c2257
HJYP
1152{
1153 GtkWidget *frame, *page;
1154
1155 /*
1156 sw = gtk_scrolled_window_new(NULL, NULL);
1157 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1158 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_NONE);
1159 gtk_container_set_border_width(GTK_CONTAINER(sw), 0);
1160 */
1161 page = gtk_vbox_new(FALSE, 1);
04883e73 1162
a52c2257 1163 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
04883e73
HJYP
1164
1165 //position
8110399f 1166 frame = mk_position( p );
a52c2257 1167 gtk_box_pack_start(GTK_BOX (page), frame, FALSE, TRUE, 0);
04883e73
HJYP
1168
1169 //size
8110399f 1170 frame = mk_size( p );
a52c2257 1171 gtk_box_pack_start(GTK_BOX (page), frame, FALSE, TRUE, 0);
04883e73 1172
04883e73 1173 //properties
8110399f 1174 frame = mk_properties( p );
a52c2257
HJYP
1175 gtk_box_pack_start(GTK_BOX (page), frame, FALSE, TRUE, 0);
1176 /*
1177 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW (sw), page);
1178 */
1179 RET(page);
1180}
1181
239cb032 1182static GtkWidget *
8110399f 1183mk_tab_appearance( Panel* p )
ace72ca9
FC
1184{
1185 GtkWidget *frame, *page;
1186 page = gtk_vbox_new(FALSE, 1);
1187
1188 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1189
4542c20d 1190 //appearance
8110399f 1191 frame = mk_appearance(p);
ace72ca9
FC
1192 gtk_box_pack_start(GTK_BOX (page), frame, FALSE, TRUE, 0);
1193
1194 RET(page);
1195}
1196
1197static GtkWidget *
8110399f 1198mk_tab_app( Panel* p )
239cb032
HJYP
1199{
1200 GtkWidget *vbox, *label, *entry;
1201 GtkTable *tbl;
1202
1203 vbox = gtk_vbox_new( FALSE, 2 );
67e88af2 1204 gtk_container_set_border_width( GTK_CONTAINER(vbox), 8 );
239cb032
HJYP
1205
1206 label = gtk_label_new("");
67e88af2 1207 gtk_label_set_markup(GTK_LABEL(label), _("<b>Set Preferred Applications</b>"));
239cb032 1208 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
67e88af2 1209 gtk_box_pack_start( GTK_BOX(vbox), label, FALSE, FALSE, 2 );
239cb032
HJYP
1210
1211 tbl = (GtkTable*)gtk_table_new( 3, 2, FALSE );
67e88af2 1212 gtk_box_pack_start( GTK_BOX(vbox), (GtkWidget*)tbl, TRUE, TRUE, 2 );
239cb032
HJYP
1213
1214 gtk_table_set_col_spacings( tbl, 4 );
1215 gtk_table_set_row_spacings( tbl, 4 );
1216
1217 label = gtk_label_new( _("File Manager:") );
1218 gtk_misc_set_alignment( label, 0, 0.5 );
1219 entry = gtk_entry_new();
cf701cb7
HJYP
1220 if (file_manager_cmd)
1221 gtk_entry_set_text( GTK_ENTRY(entry), file_manager_cmd );
239cb032
HJYP
1222 g_signal_connect( entry, "changed",
1223 G_CALLBACK(on_entry_changed),
cf701cb7 1224 &file_manager_cmd);
239cb032
HJYP
1225 gtk_table_attach( tbl, label, 0, 1, 0, 1,
1226 GTK_FILL, GTK_FILL, 2, 2 );
1227 gtk_table_attach( tbl, entry, 1, 2, 0, 1,
1228 GTK_FILL|GTK_EXPAND, GTK_FILL, 2, 2 );
1229
1230 label = gtk_label_new( _("Terminal Emulator:") );
1231 gtk_misc_set_alignment( label, 0, 0.5 );
1232 entry = gtk_entry_new();
cf701cb7
HJYP
1233 if (terminal_cmd)
1234 gtk_entry_set_text( GTK_ENTRY(entry), terminal_cmd );
239cb032
HJYP
1235 g_signal_connect( entry, "changed",
1236 G_CALLBACK(on_entry_changed),
cf701cb7 1237 &terminal_cmd);
239cb032
HJYP
1238 gtk_table_attach( tbl, label, 0, 1, 1, 2,
1239 GTK_FILL, GTK_FILL, 2, 2 );
1240 gtk_table_attach( tbl, entry, 1, 2, 1, 2,
1241 GTK_FILL|GTK_EXPAND, GTK_FILL, 2, 2 );
1242
1243 /* If we are under LXSession, setting logout command is unnecessary. */
1244 if( ! getenv("_LXSESSION_PID") ) {
1245 label = gtk_label_new( _("Logout Command:") );
1246 gtk_misc_set_alignment( label, 0, 0.5 );
1247 entry = gtk_entry_new();
cf701cb7
HJYP
1248 if(logout_cmd)
1249 gtk_entry_set_text( GTK_ENTRY(entry), logout_cmd );
239cb032
HJYP
1250 g_signal_connect( entry, "changed",
1251 G_CALLBACK(on_entry_changed),
cf701cb7 1252 &logout_cmd);
239cb032
HJYP
1253 gtk_table_attach( tbl, label, 0, 1, 2, 3,
1254 GTK_FILL, GTK_FILL, 2, 2 );
1255 gtk_table_attach( tbl, entry, 1, 2, 2, 3,
1256 GTK_FILL|GTK_EXPAND, GTK_FILL, 2, 2 );
1257 }
1258 return vbox;
1259}
a52c2257 1260
8110399f 1261static GtkWidget* mk_dialog( Panel* p )
a52c2257
HJYP
1262{
1263 GtkWidget *sw, *nb, *label;
04883e73 1264
e7cb732b 1265 dialog = gtk_dialog_new_with_buttons (_("lxpanel configurator"),
a52c2257
HJYP
1266 NULL,
1267 0, //GTK_DIALOG_DESTROY_WITH_PARENT,
a52c2257
HJYP
1268 GTK_STOCK_CLOSE,
1269 GTK_RESPONSE_CLOSE,
1270 NULL);
8110399f
HJYP
1271
1272 g_signal_connect (G_OBJECT(dialog), "response", (GCallback) response_event, p);
a52c2257
HJYP
1273 g_signal_connect (G_OBJECT(dialog), "destroy", (GCallback) dialog_destroy_event, NULL);
1274 g_signal_connect (G_OBJECT(dialog), "delete_event", (GCallback) dialog_delete_event, NULL);
1275 gtk_window_set_modal(GTK_WINDOW(dialog), FALSE);
5a343ad5 1276 gtk_window_set_position( GTK_WINDOW(dialog), GTK_WIN_POS_CENTER );
a52c2257 1277
5420dd00 1278 /* fix background */
5b6ce65c
FC
1279 if (p->background)
1280 gtk_widget_set_style(dialog, p->defstyle);
5420dd00 1281
04883e73
HJYP
1282 /*
1283 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE);
1284 gtk_window_set_skip_pager_hint(GTK_WINDOW(dialog), TRUE);
1285 */
a52c2257
HJYP
1286 nb = gtk_notebook_new();
1287 gtk_notebook_set_show_border (GTK_NOTEBOOK(nb), FALSE);
1288 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), nb);
1289
8110399f 1290 sw = mk_tab_general(p);
e7cb732b 1291 label = gtk_label_new(_("General"));
a52c2257
HJYP
1292 gtk_misc_set_padding(GTK_MISC(label), 4, 1);
1293 gtk_notebook_append_page(GTK_NOTEBOOK(nb), sw, label);
1294
8110399f 1295 sw = mk_tab_appearance(p);
4542c20d 1296 label = gtk_label_new(_("Appearance"));
ace72ca9
FC
1297 gtk_misc_set_padding(GTK_MISC(label), 4, 1);
1298 gtk_notebook_append_page(GTK_NOTEBOOK(nb), sw, label);
1299
8110399f 1300 sw = mk_tab_plugins(p);
e7cb732b 1301 label = gtk_label_new(_("Plugins"));
a52c2257
HJYP
1302 gtk_misc_set_padding(GTK_MISC(label), 4, 1);
1303 gtk_notebook_append_page(GTK_NOTEBOOK(nb), sw, label);
04883e73 1304
8110399f 1305 sw = mk_tab_app(p);
239cb032
HJYP
1306 label = gtk_label_new(_("Applications"));
1307 gtk_misc_set_padding(GTK_MISC(label), 4, 1);
1308 gtk_notebook_append_page(GTK_NOTEBOOK(nb), sw, label);
1309
a52c2257 1310 g_object_unref(sg);
04883e73 1311
a52c2257
HJYP
1312 //gtk_widget_show_all(page);
1313 gtk_widget_show_all(dialog);
04883e73 1314
a52c2257
HJYP
1315 RET(dialog);
1316}
1317
1318static void
1319update_opt_menu(GtkWidget *w, int ind)
1320{
1321 int i;
1322
1323 ENTER;
1324 /* this trick will trigger "changed" signal even if active entry is
1325 * not actually changing */
1326 i = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
1327 if (i == ind) {
1328 i = i ? 0 : 1;
1329 gtk_combo_box_set_active(GTK_COMBO_BOX(w), i);
1330 }
1331 gtk_combo_box_set_active(GTK_COMBO_BOX(w), ind);
1332 RET();
1333}
1334
1335static void
1336update_toggle_button(GtkWidget *w, gboolean n)
1337{
1338 gboolean c;
1339
1340 ENTER;
1341 /* this trick will trigger "changed" signal even if active entry is
1342 * not actually changing */
1343 c = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
1344 if (c == n) {
1345 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), !n);
1346 }
1347 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), n);
1348 RET();
1349}
1350
a52c2257 1351void
8110399f 1352configure( Panel* p )
a52c2257
HJYP
1353{
1354 ENTER;
cfc83537 1355 if( ! dialog )
8110399f 1356 dialog = mk_dialog( p );
3806c5aa 1357 gtk_window_present((GtkWindow*)dialog);
a52c2257
HJYP
1358 RET();
1359}
1360
1361void
cf701cb7 1362panel_global_config_save( Panel* p, FILE *fp)
a52c2257
HJYP
1363{
1364 GdkColor c;
04883e73 1365
389975e0
HJYP
1366 fprintf(fp, "# lxpanel <profile> config file\n"
1367 "# see http://lxpanel.sf.net/docs.html for complete configuration guide\n");
1368 lxpanel_put_line(fp, "Global {");
1369 lxpanel_put_str(fp, "edge", num2str(edge_pair, gtk_combo_box_get_active(GTK_COMBO_BOX(edge_opt)) + 1, "none"));
1370 lxpanel_put_str(fp, "allign", num2str(allign_pair, gtk_combo_box_get_active(GTK_COMBO_BOX(allign_opt)) + 1, "none"));
1371 lxpanel_put_int(fp, "margin", (int)margin_adj->value);
1372 lxpanel_put_str(fp, "widthtype", num2str(width_pair, gtk_combo_box_get_active(GTK_COMBO_BOX(width_opt)) + 1, "none"));
1373 lxpanel_put_int(fp, "width", (int) width_adj->value);
1374 lxpanel_put_int(fp, "height", (int) height_adj->value);
1375 lxpanel_put_str(fp, "transparent", num2str(bool_pair, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tr_checkb)), "false"));
a52c2257 1376 gtk_color_button_get_color(GTK_COLOR_BUTTON(tr_colorb), &c);
389975e0
HJYP
1377 lxpanel_put_line(fp, "tintcolor = #%06x", gcolor2rgb24(&c));
1378 lxpanel_put_int(fp, "alpha", gtk_color_button_get_alpha(GTK_COLOR_BUTTON(tr_colorb)) * 0xff / 0xffff);
1379 lxpanel_put_str(fp, "setdocktype", num2str(bool_pair, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prop_dt_checkb)), "true"));
1380 lxpanel_put_str(fp, "setpartialstrut", num2str(bool_pair, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prop_st_checkb)), "true"));
2de71c90
FC
1381 lxpanel_put_str(fp, "useFontColor", p->usefontcolor ? "true" : "false");
1382 lxpanel_put_line(fp, "FontColor = #%06x", gcolor2rgb24(&p->gfontcolor));
1970b674 1383 lxpanel_put_str(fp, "Background", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bg_checkb)) ? "true" : "false");
2de71c90 1384 lxpanel_put_str(fp, "BackgroundFile", p->background_file );
389975e0 1385 lxpanel_put_line(fp, "}\n");
a52c2257
HJYP
1386}
1387
a52c2257 1388void
cf701cb7 1389panel_plugin_config_save( Panel* p, FILE *fp)
a52c2257 1390{
9c97f69e
HJYP
1391 GList* l;
1392 for( l = p->plugins; l; l = l->next )
1393 {
22242ed4 1394 Plugin* pl = (Plugin*)l->data;
9c97f69e
HJYP
1395 lxpanel_put_line( fp, "Plugin {" );
1396 lxpanel_put_line( fp, "type = %s", pl->class->type );
da76d5cf
HJYP
1397 if( pl->expand )
1398 lxpanel_put_bool( fp, "expand", TRUE );
1399 if( pl->padding > 0 )
1400 lxpanel_put_int( fp, "padding", pl->padding );
1401 if( pl->border > 0 )
1402 lxpanel_put_int( fp, "border", pl->border );
1403
9c97f69e
HJYP
1404 if( pl->class->save )
1405 {
1406 lxpanel_put_line( fp, "Config {" );
1407 pl->class->save( pl, fp );
1408 lxpanel_put_line( fp, "}" );
a52c2257 1409 }
9c97f69e 1410 lxpanel_put_line( fp, "}\n" );
a52c2257 1411 }
a52c2257
HJYP
1412}
1413
cf701cb7 1414void panel_config_save( Panel* p )
368409ba 1415{
8110399f 1416 gchar *fname, *dir;
368409ba 1417 FILE *fp;
24053345 1418
cf701cb7 1419 dir = get_config_file( cprofile, "panels", FALSE );
8110399f
HJYP
1420 fname = g_build_filename( dir, p->name, NULL );
1421 g_free( dir );
24053345 1422
368409ba 1423 if (!(fp = fopen(fname, "w"))) {
24053345 1424 g_free( fname );
368409ba
FC
1425 ERR("can't open for write %s:", fname);
1426 perror(NULL);
1427 RET();
1428 }
cf701cb7
HJYP
1429 panel_global_config_save(p, fp);
1430 panel_plugin_config_save(p, fp);
368409ba 1431 fclose(fp);
24053345 1432 g_free( fname );
cf701cb7
HJYP
1433
1434 /* save the global config file */
1435 save_global_config();
368409ba
FC
1436}
1437
389975e0 1438void restart(void)
a52c2257 1439{
f7cb330e
HJYP
1440 /* This is defined in panel.c */
1441 extern gboolean is_restarting;
a52c2257 1442 ENTER;
f7cb330e 1443 is_restarting = TRUE;
be933927
HJYP
1444
1445 /* processing any possible idle handlers before we restart */
1446 while (gtk_events_pending ())
1447 gtk_main_iteration ();
f7cb330e 1448 gtk_main_quit();
a52c2257
HJYP
1449 RET();
1450}
1451
389975e0
HJYP
1452void logout(void)
1453{
cf701cb7 1454 const char* logout_cmd = logout_cmd;
00555dcf 1455 /* If LXSession is running, _LXSESSION_PID will be set */
cf701cb7
HJYP
1456 if( ! logout_cmd && getenv("_LXSESSION_PID") )
1457 logout_cmd = "lxsession-logout";
00555dcf 1458
cf701cb7 1459 if( logout_cmd ) {
389975e0 1460 GError* err = NULL;
cf701cb7 1461 if( ! g_spawn_command_line_async( logout_cmd, &err ) ) {
389975e0
HJYP
1462 show_error( NULL, err->message );
1463 g_error_free( err );
1464 }
1465 }
1466 else {
1467 show_error( NULL, _("Logout command is not set") );
1468 }
1469}
1470
04883e73
HJYP
1471static void notify_apply_config( GtkWidget* widget )
1472{
1473 GSourceFunc apply_func;
1474 GtkWidget* dlg;
1475
1476 dlg = gtk_widget_get_toplevel( widget );
5a343ad5 1477 apply_func = g_object_get_data( G_OBJECT(dlg), "apply_func" );
04883e73 1478 if( apply_func )
5a343ad5 1479 apply_func( g_object_get_data(G_OBJECT(dlg), "plugin") );
04883e73
HJYP
1480}
1481
1482static void on_entry_changed( GtkEditable* edit, gpointer user_data )
1483{
1484 char** val = (char**)user_data;
f7cb330e 1485 const char *new_val;
04883e73 1486 g_free( *val );
f7cb330e
HJYP
1487 new_val = gtk_entry_get_text(GTK_ENTRY(edit));
1488 *val = (new_val && *new_val) ? g_strdup( new_val ) : NULL;
5a343ad5 1489 notify_apply_config( GTK_WIDGET(edit) );
04883e73
HJYP
1490}
1491
1492static void on_spin_changed( GtkSpinButton* spin, gpointer user_data )
1493{
1494 int* val = (int*)user_data;
1495 *val = (int)gtk_spin_button_get_value( spin );
5a343ad5 1496 notify_apply_config( GTK_WIDGET(spin) );
04883e73
HJYP
1497}
1498
1499static void on_toggle_changed( GtkToggleButton* btn, gpointer user_data )
1500{
1501 gboolean* val = (gboolean*)user_data;
1502 *val = gtk_toggle_button_get_active( btn );
5a343ad5 1503 notify_apply_config( GTK_WIDGET(btn) );
04883e73
HJYP
1504}
1505
bb6d6422 1506/* Parameters: const char* name, gpointer ret_value, GType type, ....NULL */
04883e73
HJYP
1507GtkWidget* create_generic_config_dlg( const char* title, GtkWidget* parent,
1508 GSourceFunc apply_func, gpointer plugin,
1509 const char* name, ... )
bb6d6422
HJYP
1510{
1511 va_list args;
cf701cb7 1512 Panel* p = ((Plugin*)plugin)->panel;
5a343ad5 1513 GtkWidget* dlg = gtk_dialog_new_with_buttons( title, GTK_WINDOW(parent), 0,
04883e73
HJYP
1514 GTK_STOCK_CLOSE,
1515 GTK_RESPONSE_CLOSE,
1516 NULL );
1517
5420dd00 1518 /* fix background */
5b6ce65c
FC
1519 if (p->background)
1520 gtk_widget_set_style(dlg, p->defstyle);
5420dd00 1521
04883e73
HJYP
1522 /* this is a dirty hack. We need to check if this response is GTK_RESPONSE_CLOSE or not. */
1523 g_signal_connect( dlg, "response", G_CALLBACK(gtk_widget_destroy), NULL );
1524 if( apply_func )
5a343ad5 1525 g_object_set_data( G_OBJECT(dlg), "apply_func", apply_func );
04883e73 1526 if( plugin )
5a343ad5 1527 g_object_set_data( G_OBJECT(dlg), "plugin", plugin );
04883e73 1528
5a343ad5 1529 gtk_box_set_spacing( GTK_BOX(GTK_DIALOG(dlg)->vbox), 4 );
04883e73 1530
bb6d6422
HJYP
1531 va_start( args, name );
1532 while( name )
1533 {
1534 GtkWidget* label = gtk_label_new( name );
1535 GtkWidget* entry = NULL;
1536 gpointer val = va_arg( args, gpointer );
1537 GType type = va_arg( args, GType );
1538 switch( type )
1539 {
1540 case G_TYPE_STRING:
1541 entry = gtk_entry_new();
7414a73f
HJYP
1542 if( *(char**)val )
1543 gtk_entry_set_text( GTK_ENTRY(entry), *(char**)val );
16fb8c2e 1544 g_signal_connect( entry, "changed",
92d76f06 1545 G_CALLBACK(on_entry_changed), val );
bb6d6422
HJYP
1546 break;
1547 case G_TYPE_INT:
1548 {
1549 /* FIXME: the range shouldn't be hardcoded */
1550 entry = gtk_spin_button_new_with_range( 0, 1000, 1 );
5a343ad5 1551 gtk_spin_button_set_value( GTK_SPIN_BUTTON(entry), *(int*)val );
16fb8c2e 1552 g_signal_connect( entry, "value-changed",
92d76f06 1553 G_CALLBACK(on_spin_changed), val );
bb6d6422
HJYP
1554 break;
1555 }
1556 case G_TYPE_BOOLEAN:
1557 entry = gtk_check_button_new();
5a343ad5
JH
1558 gtk_container_add( GTK_CONTAINER(entry), label );
1559 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(entry), *(gboolean*)val );
16fb8c2e 1560 g_signal_connect( entry, "toggled",
92d76f06 1561 G_CALLBACK(on_toggle_changed), val );
bb6d6422
HJYP
1562 break;
1563 }
1564 if( entry )
1565 {
1566 if( type == G_TYPE_BOOLEAN )
5a343ad5 1567 gtk_box_pack_start( GTK_BOX(GTK_DIALOG(dlg)->vbox), entry, FALSE, FALSE, 2 );
bb6d6422
HJYP
1568 else
1569 {
1570 GtkWidget* hbox = gtk_hbox_new( FALSE, 2 );
5a343ad5
JH
1571 gtk_box_pack_start( GTK_BOX(hbox), label, FALSE, FALSE, 2 );
1572 gtk_box_pack_start( GTK_BOX(hbox), entry, TRUE, TRUE, 2 );
1573 gtk_box_pack_start( GTK_BOX(GTK_DIALOG(dlg)->vbox), hbox, FALSE, FALSE, 2 );
bb6d6422
HJYP
1574 }
1575 }
1576 name = va_arg( args, const char* );
1577 }
1578 va_end( args );
04a2f050
HJYP
1579
1580 /* weird... why this doesn't work? */
1581 /* gtk_container_set_border_width( GTK_CONTAINER(GTK_DIALOG(dlg)->vbox), 12 ); */
1582 gtk_container_set_border_width( GTK_CONTAINER(dlg), 8 );
1583
04883e73
HJYP
1584 gtk_widget_show_all( dlg );
1585 return dlg;
bb6d6422
HJYP
1586}
1587
8110399f 1588char* get_config_file( const char* profile, const char* file_name, gboolean is_global )
24053345
HJYP
1589{
1590 char* path;
1591 if( is_global )
1592 {
8110399f 1593 path = g_build_filename( PACKAGE_DATA_DIR, "lxpanel/profile", profile, file_name, NULL );
24053345
HJYP
1594 }
1595 else
1596 {
8110399f 1597 char* dir = g_build_filename( g_get_user_config_dir(), "lxpanel" , profile, NULL);
24053345 1598 /* make sure the private profile dir exists */
8110399f
HJYP
1599 /* FIXME: Should we do this everytime this func gets called?
1600 * Maybe simply doing this before saving config files is enough. */
24053345 1601 g_mkdir_with_parents( dir, 0700 );
8110399f 1602 path = g_build_filename( dir,file_name, NULL);
24053345
HJYP
1603 g_free( dir );
1604 }
1605 return path;
1606}
8110399f 1607
cf701cb7
HJYP
1608const char command_group[] = "Command";
1609void load_global_config()
1610{
1611 GKeyFile* kf = g_key_file_new();
1612 char* file = get_config_file( cprofile, "config", FALSE );
1613 gboolean loaded = g_key_file_load_from_file( kf, file, 0, NULL );
1614 if( ! loaded )
1615 {
1616 g_free( file );
1617 file = get_config_file( cprofile, "config", TRUE ); /* get the system-wide config file */
1618 loaded = g_key_file_load_from_file( kf, file, 0, NULL );
1619 }
1620
1621 if( loaded )
1622 {
1623 file_manager_cmd = g_key_file_get_string( kf, command_group, "FileManager", NULL );
1624 terminal_cmd = g_key_file_get_string( kf, command_group, "Terminal", NULL );
1625 logout_cmd = g_key_file_get_string( kf, command_group, "Logout", NULL );
1626 }
1627 g_key_file_free( kf );
1628}
1629
1630void save_global_config()
1631{
1632 char* file = get_config_file( cprofile, "config", FALSE );
1633 FILE* f = fopen( file, "w" );
1634 if( f )
1635 {
1636 fprintf( f, "[%s]\n", command_group );
1637 if( file_manager_cmd )
1638 fprintf( f, "FileManager=%s\n", file_manager_cmd );
1639 if( terminal_cmd )
1640 fprintf( f, "Terminal=%s\n", terminal_cmd );
1641 if( logout_cmd )
1642 fprintf( f, "Logout=%s\n", logout_cmd );
1643 fclose( f );
1644 }
1645}
1646
1647void free_global_config()
1648{
1649 g_free( file_manager_cmd );
1650 g_free( terminal_cmd );
1651 g_free( logout_cmd );
1652}
1653
1654extern const char*
1655lxpanel_get_file_manager()
1656{
1657 return file_manager_cmd ? file_manager_cmd : "pcmanfm %s";
1658}
1659
1660extern const char*
1661lxpanel_get_terminal()
1662{
1663 return terminal_cmd ? terminal_cmd : "xterm -e";
1664}
1665