1 /* GKrellM
2 | Copyright (C) 1999-2019 Bill Wilson
3 |
4 | Author: Bill Wilson billw@gkrellm.net
5 | Latest versions might be found at: http://gkrellm.net
6 |
7 |
8 | GKrellM is free software: you can redistribute it and/or modify it
9 | under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | GKrellM is distributed in the hope that it will be useful, but WITHOUT
14 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 | 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 | Additional permission under GNU GPL version 3 section 7
23 |
24 | If you modify this program, or any covered work, by linking or
25 | combining it with the OpenSSL project's OpenSSL library (or a
26 | modified version of that library), containing parts covered by
27 | the terms of the OpenSSL or SSLeay licenses, you are granted
28 | additional permission to convey the resulting work.
29 | Corresponding Source for a non-source form of such a combination
30 | shall include the source code for the parts of OpenSSL used as well
31 | as that of the covered work.
32 */
33
34 #include "gkrellm.h"
35 #include "gkrellm-private.h"
36
37
38 GtkWidget *config_window;
39
40
41 void
gkrellm_message_dialog(gchar * title,gchar * message)42 gkrellm_message_dialog(gchar *title, gchar *message)
43 {
44 GtkWidget *top_win;
45 GtkWidget *dialog;
46 GtkWidget *scrolled;
47 GtkWidget *vbox, *vbox1;
48 GtkWidget *label;
49 gchar *s;
50 gint nlines;
51
52 if (!message)
53 return;
54 top_win = gkrellm_get_top_window();
55 dialog = gtk_dialog_new_with_buttons(title ? title : "GKrellM",
56 GTK_WINDOW(top_win),
57 GTK_DIALOG_DESTROY_WITH_PARENT,
58 GTK_STOCK_OK, GTK_RESPONSE_NONE,
59 NULL);
60 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
61 G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(dialog));
62 gtk_window_set_wmclass(GTK_WINDOW(dialog),
63 "Gkrellm_dialog", "Gkrellm");
64
65 vbox = gtk_vbox_new(FALSE, 0);
66 gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
67 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox,
68 FALSE, FALSE, 0);
69
70 label = gtk_label_new(message);
71 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
72
73 for (nlines = 0, s = message; *s; ++s)
74 if (*s == '\n')
75 ++nlines;
76 if (nlines > 20)
77 {
78 vbox1 = gkrellm_gtk_scrolled_vbox(vbox, &scrolled,
79 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
80 gtk_widget_set_size_request(scrolled, -1, 300);
81 gtk_box_pack_start(GTK_BOX(vbox1), label, FALSE, FALSE, 0);
82 }
83 else
84 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
85
86 gtk_widget_show_all(dialog);
87 }
88
89 void
gkrellm_config_message_dialog(gchar * title,gchar * message)90 gkrellm_config_message_dialog(gchar *title, gchar *message)
91 {
92 GtkWidget *dialog;
93 GtkWidget *vbox;
94 GtkWidget *label;
95
96 if (!message || !config_window)
97 return;
98 dialog = gtk_dialog_new_with_buttons(title ? title : "GKrellM",
99 GTK_WINDOW(config_window),
100 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
101 GTK_STOCK_OK, GTK_RESPONSE_OK,
102 NULL);
103 gtk_window_set_wmclass(GTK_WINDOW(dialog),
104 "Gkrellm_dialog", "Gkrellm");
105 vbox = gtk_vbox_new(FALSE, 0);
106 gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
107 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox,
108 FALSE, FALSE, 0);
109
110 label = gtk_label_new(message);
111 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
112
113 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
114
115 gtk_widget_show_all(vbox);
116 gtk_dialog_run(GTK_DIALOG(dialog));
117 gtk_widget_destroy(dialog);
118 }
119
120 #undef gkrellm_message_window
121 #undef gkrellm_config_message_window
122
123 void
gkrellm_message_window(gchar * title,gchar * message,GtkWidget * widget)124 gkrellm_message_window(gchar *title, gchar *message, GtkWidget *widget)
125 {
126 gkrellm_message_dialog(title, message);
127 }
128
129 void
gkrellm_config_message_window(gchar * title,gchar * message,GtkWidget * widget)130 gkrellm_config_message_window(gchar *title, gchar *message, GtkWidget *widget)
131 {
132 gkrellm_config_message_dialog(title, message);
133 }
134
135 static void
text_view_append(GtkWidget * view,gchar * s)136 text_view_append(GtkWidget *view, gchar *s)
137 {
138 GtkTextIter iter;
139 GtkTextBuffer *buffer;
140
141 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
142 gtk_text_buffer_get_end_iter(buffer, &iter);
143 // gtk_text_iter_forward_to_end(&iter);
144
145 if (strncmp(s, "<b>", 3) == 0)
146 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
147 s + 3, -1, "bold", NULL);
148 else if (strncmp(s, "<i>", 3) == 0)
149 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
150 s + 3, -1, "italic", NULL);
151 else if (strncmp(s, "<h>", 3) == 0)
152 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
153 s + 3, -1, "heading", NULL);
154 else if (strncmp(s, "<c>", 3) == 0)
155 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
156 s + 3, -1, "center", NULL);
157 else if (strncmp(s, "<ul>", 4) == 0)
158 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
159 s + 4, -1, "underline", NULL);
160 else
161 gtk_text_buffer_insert(buffer, &iter, s, -1);
162 }
163
164 void
gkrellm_gtk_text_view_append(GtkWidget * view,gchar * string)165 gkrellm_gtk_text_view_append(GtkWidget *view, gchar *string)
166 {
167 static gchar *tag;
168 gchar *s;
169
170 s = string;
171 if ( *s == '<'
172 && ( (*(s + 2) == '>' && !*(s + 3))
173 || (*(s + 3) == '>' && !*(s + 4))
174 )
175 )
176 {
177 tag = g_strdup(s);
178 return;
179 }
180 if (tag)
181 {
182 s = g_strconcat(tag, string, NULL);
183 text_view_append(view, s);
184 g_free(s);
185 g_free(tag);
186 tag = NULL;
187 }
188 else
189 text_view_append(view, string);
190 }
191
192 void
gkrellm_gtk_text_view_append_strings(GtkWidget * view,gchar ** string,gint n_strings)193 gkrellm_gtk_text_view_append_strings(GtkWidget *view, gchar **string,
194 gint n_strings)
195 {
196 gchar *tag = NULL;
197 gchar *s, *t;
198 gint i;
199
200 for (i = 0; i < n_strings; ++i)
201 {
202 s = string[i];
203 if ( *s == '<'
204 && ( (*(s + 2) == '>' && !*(s + 3))
205 || (*(s + 3) == '>' && !*(s + 4))
206 )
207 )
208 {
209 tag = g_strdup(s);
210 continue;
211 }
212 #if defined(ENABLE_NLS)
213 s = gettext(string[i]);
214 #else
215 s = string[i];
216 #endif
217 if (tag)
218 {
219 t = g_strconcat(tag, s, NULL);
220 text_view_append(view, t);
221 g_free(t);
222 g_free(tag);
223 tag = NULL;
224 }
225 else
226 text_view_append(view, s);
227 }
228 }
229
230 GtkWidget *
gkrellm_gtk_scrolled_text_view(GtkWidget * box,GtkWidget ** scr,GtkPolicyType h_policy,GtkPolicyType v_policy)231 gkrellm_gtk_scrolled_text_view(GtkWidget *box, GtkWidget **scr,
232 GtkPolicyType h_policy, GtkPolicyType v_policy)
233 {
234 GtkWidget *scrolled,
235 *view;
236 GtkTextBuffer *buffer;
237
238 scrolled = gtk_scrolled_window_new(NULL, NULL);
239 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
240 h_policy, v_policy);
241 gtk_box_pack_start(GTK_BOX(box), scrolled, TRUE, TRUE, 0);
242
243 view = gtk_text_view_new();
244 gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
245 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
246 gtk_container_add(GTK_CONTAINER(scrolled), view);
247 gtk_text_buffer_create_tag(buffer, "heading",
248 "weight", PANGO_WEIGHT_BOLD,
249 "size", 14 * PANGO_SCALE, NULL);
250 gtk_text_buffer_create_tag(buffer, "italic",
251 "style", PANGO_STYLE_ITALIC, NULL);
252 gtk_text_buffer_create_tag (buffer, "bold",
253 "weight", PANGO_WEIGHT_BOLD, NULL);
254 gtk_text_buffer_create_tag (buffer, "center",
255 "justification", GTK_JUSTIFY_CENTER, NULL);
256 gtk_text_buffer_create_tag (buffer, "underline",
257 "underline", PANGO_UNDERLINE_SINGLE, NULL);
258 if (scr)
259 *scr = scrolled;
260 return view;
261 }
262
263 GtkTreeSelection *
gkrellm_gtk_scrolled_selection(GtkTreeView * treeview,GtkWidget * box,GtkSelectionMode s_mode,GtkPolicyType h_policy,GtkPolicyType v_policy,void (* func_cb)(),gpointer data)264 gkrellm_gtk_scrolled_selection(GtkTreeView *treeview, GtkWidget *box,
265 GtkSelectionMode s_mode,
266 GtkPolicyType h_policy, GtkPolicyType v_policy,
267 void (*func_cb)(), gpointer data)
268 {
269 GtkTreeSelection *selection;
270 GtkWidget *scrolled;
271
272 if (!box || !treeview)
273 return NULL;
274
275 scrolled = gtk_scrolled_window_new(NULL, NULL);
276 gtk_box_pack_start(GTK_BOX(box), scrolled, TRUE, TRUE, 0);
277 gtk_container_add(GTK_CONTAINER(scrolled), GTK_WIDGET(treeview));
278 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
279 h_policy, v_policy);
280 selection = gtk_tree_view_get_selection(treeview);
281 gtk_tree_selection_set_mode(selection, s_mode);
282 if (func_cb)
283 g_signal_connect(G_OBJECT(selection), "changed",
284 G_CALLBACK(func_cb), data);
285 return selection;
286 }
287
288 void
gkrellm_launch_button_cb(GkrellmDecalbutton * button)289 gkrellm_launch_button_cb(GkrellmDecalbutton *button)
290 {
291 GkrellmLauncher *launch;
292
293 launch = (GkrellmLauncher *) button->data;
294 g_spawn_command_line_async(launch->command, NULL /* GError */);
295 }
296
297 void
gkrellm_remove_launcher(GkrellmLauncher * launch)298 gkrellm_remove_launcher(GkrellmLauncher *launch)
299 {
300 if (launch->button)
301 gkrellm_destroy_button(launch->button);
302 launch->button = NULL;
303 }
304
305 void
gkrellm_configure_tooltip(GkrellmPanel * p,GkrellmLauncher * launch)306 gkrellm_configure_tooltip(GkrellmPanel *p, GkrellmLauncher *launch)
307 {
308 launch->widget = p->drawing_area;
309 if (*launch->tooltip_comment && *launch->command)
310 {
311 gtk_widget_set_tooltip_text(p->drawing_area,
312 launch->tooltip_comment);
313 }
314 else
315 gtk_widget_set_tooltip_text(p->drawing_area,
316 NULL);
317 }
318
319 void
gkrellm_apply_launcher(GtkWidget ** launch_entry,GtkWidget ** tooltip_entry,GkrellmPanel * p,GkrellmLauncher * launch,void (* func)())320 gkrellm_apply_launcher(GtkWidget **launch_entry, GtkWidget **tooltip_entry,
321 GkrellmPanel *p, GkrellmLauncher *launch, void (*func)())
322 {
323 gchar *command, *tip_comment;
324
325 if (!launch_entry || !launch || !p)
326 return;
327 command = gkrellm_gtk_entry_get_text(launch_entry);
328 tip_comment = tooltip_entry ?
329 gkrellm_gtk_entry_get_text(tooltip_entry) : "";
330 if ( launch->command && !strcmp(command, launch->command)
331 && launch->tooltip_comment
332 && !strcmp(tip_comment, launch->tooltip_comment)
333 )
334 return;
335 if (*command)
336 {
337 if (!launch->button)
338 {
339 if (launch->type == METER_LAUNCHER)
340 launch->button = gkrellm_put_label_in_meter_button(p, func,
341 launch, launch->pad);
342 else if (launch->type == PANEL_LAUNCHER)
343 launch->button = gkrellm_put_label_in_panel_button(p, func,
344 launch, launch->pad);
345 else if (launch->type == DECAL_LAUNCHER)
346 launch->button = gkrellm_put_decal_in_meter_button(p,
347 launch->decal,
348 gkrellm_launch_button_cb, launch, &launch->margin);
349 }
350 gkrellm_dup_string(&launch->command, command);
351 }
352 else
353 {
354 if (launch->button)
355 gkrellm_destroy_button(launch->button);
356 launch->button = NULL;
357 launch->pipe = NULL; /* Close?? */
358 gkrellm_dup_string(&launch->command, "");
359 }
360 gkrellm_dup_string(&launch->tooltip_comment, tip_comment);
361 gkrellm_configure_tooltip(p, launch);
362 }
363
364 GtkWidget *
gkrellm_gtk_launcher_table_new(GtkWidget * vbox,gint n_launchers)365 gkrellm_gtk_launcher_table_new(GtkWidget *vbox, gint n_launchers)
366 {
367 GtkWidget *table;
368
369 table = gtk_table_new(2 * n_launchers, 2, FALSE /*non-homogeneous*/);
370 gtk_table_set_col_spacings(GTK_TABLE(table), 2);
371 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2);
372 return table;
373 }
374
375 void
gkrellm_gtk_config_launcher(GtkWidget * table,gint n,GtkWidget ** launch_entry,GtkWidget ** tooltip_entry,gchar * desc,GkrellmLauncher * launch)376 gkrellm_gtk_config_launcher(GtkWidget *table, gint n, GtkWidget **launch_entry,
377 GtkWidget **tooltip_entry, gchar *desc, GkrellmLauncher *launch)
378 {
379 GtkWidget *label, *hbox;
380 gchar buf[64];
381 gint row;
382
383 if (!table || !launch_entry)
384 return;
385 row = (tooltip_entry ? 2 : 1) * n;
386 hbox = gtk_hbox_new(FALSE, 0);
387 /* Attach left right top bottom */
388 gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, row, row + 1,
389 GTK_FILL, GTK_SHRINK, 0, 0);
390
391 snprintf(buf, sizeof(buf), _("%s command"), desc);
392 label = gtk_label_new(buf);
393 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
394 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 4);
395
396 *launch_entry = gtk_entry_new();
397 gtk_entry_set_max_length(GTK_ENTRY(*launch_entry), 255);
398 gtk_table_attach_defaults(GTK_TABLE(table), *launch_entry,
399 1, 2, row, row + 1);
400 gtk_entry_set_text(GTK_ENTRY(*launch_entry),
401 (launch && launch->command) ? launch->command : "");
402
403 if (tooltip_entry)
404 {
405 hbox = gtk_hbox_new(FALSE, 0);
406 gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, row + 1, row + 2,
407 GTK_FILL, GTK_SHRINK, 0, 0);
408
409 label = gtk_label_new(_("comment"));
410 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
411 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 4);
412 *tooltip_entry = gtk_entry_new();
413 gtk_entry_set_max_length(GTK_ENTRY(*tooltip_entry), 255);
414 gtk_table_attach_defaults(GTK_TABLE(table), *tooltip_entry,
415 1, 2, row + 1, row + 2);
416 gtk_entry_set_text(GTK_ENTRY(*tooltip_entry),
417 (launch && launch->tooltip_comment)
418 ? launch->tooltip_comment : "");
419 }
420 }
421
422 /* FIXME: this guy is called on panels at create events
423 | when this situation has occurred: the GKrellM rebuild has destroyed
424 | the decal button list. But existing launchers have not had their
425 | button pointer set to NULL! This could cause a problem with
426 | code that tries to check for button pointers in the create routines.
427 */
428 void
gkrellm_setup_launcher(GkrellmPanel * p,GkrellmLauncher * launch,gint type,gint pad)429 gkrellm_setup_launcher(GkrellmPanel *p, GkrellmLauncher *launch,
430 gint type, gint pad)
431 {
432 if (!launch)
433 return;
434 if (!launch->command)
435 launch->command = g_strdup("");
436 if (!launch->tooltip_comment)
437 launch->tooltip_comment = g_strdup("");
438 launch->type = type;
439 launch->pad = pad;
440 if (p)
441 {
442 gkrellm_configure_tooltip(p, launch);
443 if (*(launch->command))
444 launch->button = gkrellm_put_label_in_meter_button(p,
445 gkrellm_launch_button_cb, launch, launch->pad);
446 else
447 launch->button = NULL; /* In case dangling pointer, see above */
448 }
449 }
450
451 void
gkrellm_setup_decal_launcher(GkrellmPanel * p,GkrellmLauncher * launch,GkrellmDecal * d)452 gkrellm_setup_decal_launcher(GkrellmPanel *p, GkrellmLauncher *launch,
453 GkrellmDecal *d)
454 {
455 if (!launch)
456 return;
457 if (!launch->command)
458 launch->command = g_strdup("");
459 if (!launch->tooltip_comment)
460 launch->tooltip_comment = g_strdup("");
461 launch->type = DECAL_LAUNCHER;
462 launch->pad = 0;
463 launch->decal = d;
464 if (p)
465 {
466 gkrellm_configure_tooltip(p, launch);
467 if (*(launch->command))
468 launch->button = gkrellm_put_decal_in_meter_button(p, d,
469 gkrellm_launch_button_cb, launch, &launch->margin);
470 else
471 launch->button = NULL; /* In case dangling pointer, see above */
472 }
473 }
474
475 void
gkrellm_gtk_check_button(GtkWidget * box,GtkWidget ** button,gboolean active,gboolean expand,gint pad,gchar * string)476 gkrellm_gtk_check_button(GtkWidget *box, GtkWidget **button, gboolean active,
477 gboolean expand, gint pad, gchar *string)
478 {
479 GtkWidget *b;
480
481 if (!string)
482 return;
483 b = gtk_check_button_new_with_label(string);
484 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), active);
485 if (box)
486 gtk_box_pack_start(GTK_BOX(box), b, expand, FALSE, pad);
487 if (button)
488 *button = b;
489 }
490
491 void
gkrellm_gtk_check_button_connected(GtkWidget * box,GtkWidget ** button,gboolean active,gboolean expand,gboolean fill,gint pad,void (* cb_func)(),gpointer data,gchar * string)492 gkrellm_gtk_check_button_connected(GtkWidget *box, GtkWidget **button,
493 gboolean active, gboolean expand, gboolean fill, gint pad,
494 void (*cb_func)(), gpointer data, gchar *string)
495 {
496 GtkWidget *b;
497
498 if (!string)
499 return;
500 b = gtk_check_button_new_with_label(string);
501
502 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), active);
503 if (box)
504 {
505 if (pad < 0)
506 gtk_box_pack_end(GTK_BOX(box), b, expand, fill, -(pad + 1));
507 else
508 gtk_box_pack_start(GTK_BOX(box), b, expand, fill, pad);
509 }
510 if (cb_func)
511 g_signal_connect(G_OBJECT(b), "toggled",
512 G_CALLBACK(cb_func), data);
513 if (button)
514 *button = b;
515 }
516
517 void
gkrellm_gtk_button_connected(GtkWidget * box,GtkWidget ** button,gboolean expand,gboolean fill,gint pad,void (* cb_func)(),gpointer data,gchar * string)518 gkrellm_gtk_button_connected(GtkWidget *box, GtkWidget **button,
519 gboolean expand, gboolean fill, gint pad,
520 void (*cb_func)(), gpointer data, gchar *string)
521 {
522 GtkWidget *b;
523
524 if (!string)
525 return;
526 if (!strncmp(string, "gtk-", 4))
527 b = gtk_button_new_from_stock(string);
528 else
529 b = gtk_button_new_with_label(string);
530 if (box)
531 {
532 if (pad < 0)
533 gtk_box_pack_end(GTK_BOX(box), b, expand, fill, -(pad + 1));
534 else
535 gtk_box_pack_start(GTK_BOX(box), b, expand, fill, pad);
536 }
537 if (cb_func)
538 g_signal_connect(G_OBJECT(b), "clicked",
539 G_CALLBACK(cb_func), data);
540 if (button)
541 *button = b;
542 }
543
544 void
gkrellm_gtk_alert_button(GtkWidget * box,GtkWidget ** button,gboolean expand,gboolean fill,gint pad,gboolean pack_start,void (* cb_func)(),gpointer data)545 gkrellm_gtk_alert_button(GtkWidget *box, GtkWidget **button,
546 gboolean expand, gboolean fill, gint pad, gboolean pack_start,
547 void (*cb_func)(), gpointer data)
548 {
549 GtkWidget *b, *hbox;
550 GtkWidget *image, *label;
551
552 hbox = gtk_hbox_new(FALSE, 0);
553 gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
554 image = gtk_image_new_from_pixbuf(gkrellm_alert_pixbuf());
555 label = gtk_label_new(_("Alerts"));
556 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 3);
557 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3);
558 b = gtk_button_new();
559 if (button)
560 *button = b;
561 if (cb_func)
562 g_signal_connect(G_OBJECT(b), "clicked", G_CALLBACK(cb_func), data);
563 gtk_widget_show_all(hbox);
564 gtk_container_add(GTK_CONTAINER(b), hbox);
565 if (box)
566 {
567 if (pack_start)
568 gtk_box_pack_start(GTK_BOX(box), b, expand, fill, pad);
569 else
570 gtk_box_pack_end(GTK_BOX(box), b, expand, fill, pad);
571 }
572 }
573
574 void
gkrellm_gtk_spin_button(GtkWidget * box,GtkWidget ** spin_button,gfloat value,gfloat low,gfloat high,gfloat step0,gfloat step1,gint digits,gint width,void (* cb_func)(),gpointer data,gboolean right_align,gchar * string)575 gkrellm_gtk_spin_button(GtkWidget *box, GtkWidget **spin_button, gfloat value,
576 gfloat low, gfloat high, gfloat step0, gfloat step1,
577 gint digits, gint width,
578 void (*cb_func)(), gpointer data, gboolean right_align, gchar *string)
579 {
580 GtkWidget *hbox = NULL,
581 *label,
582 *button;
583 GtkSpinButton *spin;
584 GtkAdjustment *adj;
585
586 if (string && box)
587 {
588 hbox = gtk_hbox_new (FALSE, 0);
589 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 2);
590 box = hbox;
591 }
592 adj = (GtkAdjustment *) gtk_adjustment_new (value,
593 low, high, step0, step1, 0.0);
594 button = gtk_spin_button_new(adj, 0.5, digits);
595 if (spin_button)
596 *spin_button = button;
597 if (width > 0)
598 gtk_widget_set_size_request(button, width, -1);
599 spin = GTK_SPIN_BUTTON(button);
600 gtk_spin_button_set_numeric(spin, TRUE);
601 if (!data)
602 data = (gpointer) spin;
603 if (cb_func)
604 g_signal_connect(G_OBJECT(adj), "value_changed",
605 G_CALLBACK(cb_func), data);
606 if (box)
607 {
608 if (right_align && string)
609 {
610 label = gtk_label_new(string);
611 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
612 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 2);
613 }
614 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 2);
615 if (!right_align && string)
616 {
617 label = gtk_label_new(string);
618 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
619 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 2);
620 }
621 }
622 }
623
624 GtkWidget *
gkrellm_gtk_scrolled_vbox(GtkWidget * box,GtkWidget ** scr,GtkPolicyType h_policy,GtkPolicyType v_policy)625 gkrellm_gtk_scrolled_vbox(GtkWidget *box, GtkWidget **scr,
626 GtkPolicyType h_policy, GtkPolicyType v_policy)
627 {
628 GtkWidget *scrolled,
629 *vbox;
630
631 scrolled = gtk_scrolled_window_new(NULL, NULL);
632 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
633 h_policy, v_policy);
634 gtk_box_pack_start(GTK_BOX(box), scrolled, TRUE, TRUE, 0);
635 vbox = gtk_vbox_new(FALSE, 2);
636 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), vbox);
637 if (scr)
638 *scr = scrolled;
639 return vbox;
640 }
641
642 /* frame_border_width - border around outside of frame.
643 | vbox_pad - pad between widgets to be packed in returned vbox.
644 | vbox_border_width - border between returned vbox and frame.
645 */
646 GtkWidget *
gkrellm_gtk_framed_vbox(GtkWidget * box,gchar * label,gint frame_border_width,gboolean frame_expand,gint vbox_pad,gint vbox_border_width)647 gkrellm_gtk_framed_vbox(GtkWidget *box, gchar *label, gint frame_border_width,
648 gboolean frame_expand, gint vbox_pad, gint vbox_border_width)
649 {
650 GtkWidget *frame, *lbl;
651 GtkWidget *vbox;
652
653 frame = gtk_frame_new(NULL);
654 /* gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); */
655 lbl = gtk_label_new(NULL);
656 gtk_label_set_markup(GTK_LABEL(lbl), label);
657 gtk_frame_set_label_widget(GTK_FRAME(frame), lbl);
658
659 gtk_container_set_border_width(GTK_CONTAINER(frame), frame_border_width);
660 gtk_box_pack_start(GTK_BOX(box), frame, frame_expand, frame_expand, 0);
661 vbox = gtk_vbox_new(FALSE, vbox_pad);
662 gtk_container_set_border_width(GTK_CONTAINER(vbox), vbox_border_width);
663 gtk_container_add(GTK_CONTAINER(frame), vbox);
664 return vbox;
665 }
666
667 GtkWidget *
gkrellm_gtk_framed_vbox_end(GtkWidget * box,gchar * label,gint frame_border_width,gboolean frame_expand,gint vbox_pad,gint vbox_border_width)668 gkrellm_gtk_framed_vbox_end(GtkWidget *box, gchar *label,
669 gint frame_border_width, gboolean frame_expand,
670 gint vbox_pad, gint vbox_border_width)
671 {
672 GtkWidget *frame;
673 GtkWidget *vbox;
674
675 frame = gtk_frame_new(label);
676 gtk_container_set_border_width(GTK_CONTAINER(frame), frame_border_width);
677 gtk_box_pack_end(GTK_BOX(box), frame, frame_expand, frame_expand, 0);
678 vbox = gtk_vbox_new(FALSE, vbox_pad);
679 gtk_container_set_border_width(GTK_CONTAINER(vbox), vbox_border_width);
680 gtk_container_add(GTK_CONTAINER(frame), vbox);
681 return vbox;
682 }
683
684 GtkWidget *
gkrellm_gtk_category_vbox(GtkWidget * box,gchar * category_header,gint header_pad,gint box_pad,gboolean pack_start)685 gkrellm_gtk_category_vbox(GtkWidget *box, gchar *category_header,
686 gint header_pad, gint box_pad, gboolean pack_start)
687 {
688 GtkWidget *vbox, *vbox1, *hbox, *label;
689 gchar *s;
690
691 vbox = gtk_vbox_new(TRUE, 0);
692 gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
693
694 if (pack_start)
695 gtk_box_pack_start(GTK_BOX(box), vbox, TRUE, TRUE, 0);
696 else
697 gtk_box_pack_end(GTK_BOX(box), vbox, TRUE, TRUE, 0);
698
699 if (category_header)
700 {
701 label = gtk_label_new(NULL);
702 s = g_strconcat("<span weight=\"bold\">", category_header,
703 "</span>",NULL);
704 gtk_label_set_markup(GTK_LABEL(label), s);
705 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
706 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, header_pad);
707 g_free(s);
708 }
709
710 hbox = gtk_hbox_new(FALSE, 0);
711 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
712
713 label = gtk_label_new(" ");
714 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
715 vbox1 = gtk_vbox_new(FALSE, box_pad);
716 gtk_box_pack_start(GTK_BOX(hbox), vbox1, TRUE, TRUE, 0);
717
718 /* Add some bottom pad */
719 label = gtk_label_new("");
720 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
721
722 return vbox1;
723 }
724
725 GtkWidget *
gkrellm_gtk_notebook_page(GtkWidget * tabs,char * name)726 gkrellm_gtk_notebook_page(GtkWidget *tabs, char *name)
727 {
728 GtkWidget *label;
729 GtkWidget *vbox;
730
731 vbox = gtk_vbox_new(FALSE, 0);
732 gtk_container_set_border_width(GTK_CONTAINER(vbox), 0);
733
734 label = gtk_label_new(name);
735 gtk_notebook_append_page(GTK_NOTEBOOK(tabs), vbox, label);
736
737 return vbox;
738 }
739
740 GtkWidget *
gkrellm_gtk_framed_notebook_page(GtkWidget * tabs,char * name)741 gkrellm_gtk_framed_notebook_page(GtkWidget *tabs, char *name)
742 {
743 GtkWidget *vbox;
744
745 vbox = gkrellm_gtk_notebook_page(tabs, name);
746 vbox = gkrellm_gtk_framed_vbox(vbox, NULL, 2, TRUE, 4, 4);
747 return vbox;
748 }
749
750 static void
create_about_tab(GtkWidget * vbox)751 create_about_tab(GtkWidget *vbox)
752 {
753 GtkWidget *label;
754 gchar *buf;
755
756 vbox = gkrellm_gtk_framed_vbox(vbox, NULL, 2, TRUE, 0, 0);
757 label = gtk_label_new("");
758 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
759
760 buf = g_strdup_printf(_("GKrellM %d.%d.%d%s\nGNU Krell Monitors\n\n"
761 "Copyright (c) %s by Bill Wilson\n"
762 "billw@gkrellm.net\n"
763 "http://gkrellm.net\n\n"
764 "Released under the GNU General Public License"),
765 GKRELLM_VERSION_MAJOR, GKRELLM_VERSION_MINOR,
766 GKRELLM_VERSION_REV, GKRELLM_EXTRAVERSION,
767 "1999-2019");
768 label = gtk_label_new(buf);
769 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
770 g_free(buf);
771 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
772
773 label = gtk_label_new("");
774 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
775
776 #if defined(__APPLE__)
777 buf = g_strdup_printf(_("Mac OS X code was contributed by:\n"
778 "Ben Hines <bhines@alumni.ucsd.edu>\n"
779 "and\n"
780 "Hajimu UMEMOTO <ume@mahoroba.org>"));
781 label = gtk_label_new(buf);
782 g_free(buf);
783 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
784 #endif
785 #if defined(__FreeBSD__)
786 buf = g_strdup_printf(
787 _("FreeBSD system dependent code was contributed by:\n"
788 "Hajimu UMEMOTO <ume@mahoroba.org>"));
789 label = gtk_label_new(buf);
790 g_free(buf);
791 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
792 #endif
793 #if defined(__DragonFly__)
794 buf = g_strdup_printf(
795 _("DragonFly system dependent code was contributed by:\n"
796 "Joerg Sonnenberger <joerg@bec.de>"));
797 label = gtk_label_new(buf);
798 g_free(buf);
799 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
800 #endif
801 #if defined(__NetBSD__)
802 buf = g_strdup_printf(
803 _("NetBSD system dependent code was contributed by:\n"
804 "Anthony Mallet <anthony.mallet@useless-ficus.net>"));
805 label = gtk_label_new(buf);
806 g_free(buf);
807 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
808 #endif
809 #if defined(__solaris__)
810 buf = g_strdup_printf(
811 _("Solaris system dependent code was contributed by:\n"
812 "Daisuke Yabuki <dxy@acm.org>"));
813 label = gtk_label_new(buf);
814 g_free(buf);
815 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
816 #endif
817 #if defined(WIN32)
818 buf = g_strdup_printf(
819 _("Windows system dependent code was contributed by:\n"
820 "Bill Nalen <bill@nalens.com>\n"
821 "Stefan Gehn <stefan+gkrellm@srcbox.net>\n"));
822 label = gtk_label_new(buf);
823 g_free(buf);
824 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
825 #endif // !WIN32
826 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
827 }
828
829
830 /* ------------------General Settings---------------------------------*/
831 static GtkWidget
832 *enable_hst_button,
833 *hostname_short_button,
834 *enable_sysname_button,
835 *save_position_button;
836
837 #if !defined(WIN32)
838 static GtkWidget
839 *sticky_state_button,
840 *dock_type_button,
841 *decorated_button,
842 *skip_taskbar_button,
843 *skip_pager_button,
844 *above_button,
845 *below_button;
846 #endif // !WIN32
847
848 GtkWidget *track_gtk_button,
849 *allow_multiple_button;
850 GtkWidget *on_top_button;
851
852
853
854 static void
cb_width_spin(GtkWidget * widget,GtkSpinButton * spin)855 cb_width_spin(GtkWidget *widget, GtkSpinButton *spin)
856 {
857 _GK.chart_width = gtk_spin_button_get_value_as_int(spin);
858 gkrellm_build();
859 }
860
861 static void
cb_HZ_spin(GtkWidget * widget,GtkSpinButton * spin)862 cb_HZ_spin(GtkWidget *widget, GtkSpinButton *spin)
863 {
864 gint n;
865
866 n = _GK.update_HZ;
867 _GK.update_HZ = gtk_spin_button_get_value_as_int(spin);
868 if (n != _GK.update_HZ)
869 gkrellm_start_timer(_GK.update_HZ);
870 }
871
872 static void
cb_hostname_sysname(GtkWidget * widget,gpointer data)873 cb_hostname_sysname(GtkWidget *widget, gpointer data)
874 {
875 _GK.enable_hostname = GTK_TOGGLE_BUTTON(enable_hst_button)->active;
876 if (hostname_short_button)
877 _GK.hostname_short = GTK_TOGGLE_BUTTON(hostname_short_button)->active;
878 _GK.enable_system_name = GTK_TOGGLE_BUTTON(enable_sysname_button)->active;
879 gkrellm_apply_hostname_config();
880 }
881
882 static void
cb_general(void)883 cb_general(void)
884 {
885 #if !defined(WIN32)
886 gint n;
887 gboolean new_state;
888 #endif
889
890 if (allow_multiple_button)
891 _GK.allow_multiple_instances =
892 GTK_TOGGLE_BUTTON(allow_multiple_button)->active;
893 if (on_top_button)
894 _GK.on_top = GTK_TOGGLE_BUTTON(on_top_button)->active;
895
896 _GK.save_position = GTK_TOGGLE_BUTTON(save_position_button)->active;
897 #if !defined(WIN32)
898 if (sticky_state_button)
899 {
900 n = GTK_TOGGLE_BUTTON(sticky_state_button)->active;
901 new_state = (n != _GK.sticky_state);
902 _GK.sticky_state = n;
903 if (new_state)
904 {
905 GtkWidget *top_window = gkrellm_get_top_window();
906
907 if (_GK.sticky_state)
908 gtk_window_stick(GTK_WINDOW(top_window));
909 else
910 gtk_window_unstick(GTK_WINDOW(top_window));
911 }
912 }
913
914 if (decorated_button) /* restart for change to take effect */
915 _GK.decorated = GTK_TOGGLE_BUTTON(decorated_button)->active;
916
917 if (skip_taskbar_button)
918 {
919 n = GTK_TOGGLE_BUTTON(skip_taskbar_button)->active;
920 new_state = (n != _GK.state_skip_taskbar);
921 _GK.state_skip_taskbar = n;
922 if (new_state)
923 gkrellm_winop_state_skip_taskbar(n);
924 }
925 if (skip_pager_button)
926 {
927 n = GTK_TOGGLE_BUTTON(skip_pager_button)->active;
928 new_state = (n != _GK.state_skip_pager);
929 _GK.state_skip_pager = n;
930 if (new_state)
931 gkrellm_winop_state_skip_pager(n);
932 }
933 if (above_button)
934 {
935 n = GTK_TOGGLE_BUTTON(above_button)->active;
936 new_state = (n != _GK.state_above);
937 _GK.state_above = n;
938 if (new_state)
939 {
940 if (n && _GK.state_below)
941 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(below_button),
942 FALSE);
943 gkrellm_winop_state_above(n);
944 }
945 }
946 if (below_button)
947 {
948 n = GTK_TOGGLE_BUTTON(below_button)->active;
949 new_state = (n != _GK.state_below);
950 _GK.state_below = n;
951 if (new_state)
952 {
953 if (n && _GK.state_above)
954 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(above_button),
955 FALSE);
956 gkrellm_winop_state_below(n);
957 }
958 }
959 #endif // !WIN32
960 }
961
962 #ifndef WIN32
963 static void
cb_dock_type(GtkWidget * widget,gpointer data)964 cb_dock_type(GtkWidget *widget, gpointer data)
965 {
966 gboolean sensitive;
967
968 _GK.dock_type = GTK_TOGGLE_BUTTON(dock_type_button)->active;
969 sensitive = !_GK.dock_type;
970 if (!sensitive)
971 {
972 gtk_toggle_button_set_active(
973 GTK_TOGGLE_BUTTON(decorated_button), FALSE);
974 gtk_toggle_button_set_active(
975 GTK_TOGGLE_BUTTON(skip_taskbar_button), FALSE);
976 gtk_toggle_button_set_active(
977 GTK_TOGGLE_BUTTON(skip_pager_button), FALSE);
978 }
979 gtk_widget_set_sensitive(decorated_button, sensitive);
980 gtk_widget_set_sensitive(skip_taskbar_button, sensitive);
981 gtk_widget_set_sensitive(skip_pager_button, sensitive);
982 }
983 #endif // WIN32
984
985 static gchar *general_info_text[] =
986 {
987 N_("<h>Krells\n"),
988 N_("Krells are the horizontally moving indicators below each chart and\n"
989 "on meter style monitors. Depending on the monitor, they show fast\n"
990 "response data rates, a percentage of some capacity, or something else.\n"),
991 "\n",
992 N_("<h>Charts\n"),
993 N_("The default for most charts is to automatically adjust the number of\n"
994 "grid lines drawn and the resolution per grid so drawn data will be\n"
995 "nicely visible. You may change this to fixed grids of 1-5 and/or\n"
996 "fixed grid resolutions in the chart config windows. However,\n"
997 "some combination of the auto scaling modes may give best results.\n"),
998 "\n",
999 N_("See the README or do a \"man gkrellm\" for more information.\n"),
1000 "\n",
1001 N_("<h>Chart Labels\n"),
1002 N_("Chart label format strings place text on charts using position codes:\n"),
1003 N_("\t\\t top left\n"),
1004 N_("\t\\b bottom left\n"),
1005 N_("\t\\n next line\n"),
1006 N_("\t\\N next line only if last string had visible characters\n"),
1007 N_("\t\\p previous line\n"),
1008 N_("\t\\c center the text\n"),
1009 N_("\t\\C begin drawing text at the center\n"),
1010 N_("\t\\r right justify\n"),
1011 N_("\t\\f use alternate font for the next string\n"),
1012 N_("\t\\w use the following string to define a field width\n"),
1013 N_("\t\\a draw left justified in the defined field width\n"),
1014 N_("\t\\e draw right justified in the defined field width\n"),
1015 N_("\t\\. no-op. Used to break a string into two strings.\n"),
1016 N_("\t\\D0 bottom of charts first data view (D2 for second data view ...)\n"),
1017 N_("\t\\D1 top of charts first data view (D3 for second data view ...)\n"),
1018 "\n",
1019 N_("\tText drawn on charts cannot use Pango markup and changing the color\n"),
1020 N_("\tused for a chart default or alternate font requires editing the theme.\n"),
1021 "\n",
1022
1023 N_("<h>Panel Labels\n"),
1024 N_("\tMost panel labels can use Pango markup to customize the font or\n"
1025 "\ttext color. If the Pango markup string requires quote characters some\n"
1026 "\tmonitors (eg Sensors) require using single quotes instead of double\n"
1027 "\tquotes. For example, to set a big colored CPU label, use markup:\n"),
1028 "\t <span foreground='cyan'><big>CPU</big></span>\n",
1029 "\n",
1030
1031 N_("<h>\nCommands\n"),
1032 N_("\tMany monitors can be configured to launch commands. Just enter the\n"
1033 "\tcommand where you see a \"command\" entry and also a comment if you\n"
1034 "\twant a tooltip to appear for the command. After a command is entered,\n"
1035 "\tfor a monitor, a button for launching it will become visible when you\n"
1036 "\tmove the mouse into the panel area of the monitor.\n\n"),
1037 N_("See the README or do a \"man gkrellm\" for more information.\n"),
1038 "\n",
1039
1040 N_("<h>\nMouse Button Actions:\n"),
1041 N_("<b>\tLeft "),
1042 N_("clicking on charts will toggle a display of some extra info.\n"),
1043 N_("<b>\tRight "),
1044 N_("clicking on charts brings up a chart configuration window.\n"),
1045 N_("<b>\tRight "),
1046 N_("clicking on many panels opens its monitor configuration window.\n")
1047 };
1048
1049 static void
create_general_tab(GtkWidget * tab_vbox)1050 create_general_tab(GtkWidget *tab_vbox)
1051 {
1052 GtkWidget *tabs;
1053 GtkWidget *vbox, *vbox1;
1054 #if !defined(WIN32)
1055 GtkWidget *vbox2;
1056 #endif
1057 GtkWidget *hbox;
1058 GtkWidget *label, *text;
1059 gint i;
1060
1061 tabs = gtk_notebook_new();
1062 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
1063 gtk_box_pack_start(GTK_BOX(tab_vbox), tabs, TRUE, TRUE, 0);
1064
1065 /* --Options tab */
1066 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Options"));
1067 vbox1 = gtk_vbox_new(FALSE, 0);
1068 gtk_box_pack_start(GTK_BOX(vbox), vbox1, FALSE, FALSE, 0);
1069 hbox = gtk_hbox_new (FALSE, 0);
1070 gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
1071
1072 gkrellm_gtk_check_button_connected(hbox, &enable_hst_button,
1073 _GK.enable_hostname, FALSE, FALSE, 0,
1074 cb_hostname_sysname, NULL,
1075 _("Hostname display"));
1076
1077 if (gkrellm_hostname_can_shorten())
1078 gkrellm_gtk_check_button_connected(hbox, &hostname_short_button,
1079 _GK.hostname_short, FALSE, FALSE, 10,
1080 cb_hostname_sysname, NULL,
1081 _("Short hostname"));
1082
1083 gkrellm_gtk_check_button_connected(vbox, &enable_sysname_button,
1084 _GK.enable_system_name, FALSE, FALSE, 0,
1085 cb_hostname_sysname, NULL,
1086 _("System name display"));
1087
1088 gkrellm_gtk_check_button_connected(vbox, &save_position_button,
1089 _GK.save_position, FALSE, FALSE, 6,
1090 cb_general, NULL,
1091 _("Remember screen location at exit and move to it at next startup"));
1092
1093 #if !defined(WIN32)
1094 gkrellm_gtk_check_button_connected(vbox, &allow_multiple_button,
1095 _GK.allow_multiple_instances, FALSE, FALSE, 0,
1096 cb_general, NULL,
1097 _("Allow multiple instances"));
1098 #endif // !WIN32
1099
1100 #if defined(WIN32)
1101 gkrellm_gtk_check_button_connected(vbox, &on_top_button,
1102 _GK.on_top, FALSE, FALSE, 0,
1103 cb_general, NULL,
1104 _("Make gkrellm a topmost window (restart gkrellm for this to take effect)."));
1105 #endif // WIN32
1106
1107 if (_GK.client_mode)
1108 {
1109 hbox = gtk_hbox_new(FALSE, 0);
1110 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 6);
1111 gkrellm_gtk_alert_button(hbox, NULL, FALSE, FALSE, 4, TRUE,
1112 gkrellm_gkrellmd_disconnect_cb, NULL);
1113 label = gtk_label_new(_("gkrellmd server disconnect"));
1114 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
1115 }
1116
1117 vbox = gkrellm_gtk_framed_vbox_end(vbox, NULL, 4, FALSE, 0, 2);
1118 gkrellm_gtk_spin_button(vbox, NULL, (gfloat) _GK.update_HZ,
1119 1.0, 20.0, 1.0, 1.0, 0, 55,
1120 cb_HZ_spin, NULL, FALSE,
1121 _("Krell and LED updates per second."));
1122
1123 gkrellm_gtk_spin_button(vbox, NULL, (gfloat) _GK.chart_width,
1124 (gfloat) CHART_WIDTH_MIN, (gfloat) CHART_WIDTH_MAX,
1125 5.0, 10.0, 0, 55,
1126 cb_width_spin, NULL, FALSE,
1127 _("GKrellM width"));
1128
1129 #if !defined(WIN32)
1130 /* --Window options tab */
1131 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Properties"));
1132 gkrellm_gtk_check_button_connected(vbox, &sticky_state_button,
1133 _GK.sticky_state, FALSE, FALSE, 0, cb_general, NULL,
1134 _("Set sticky state"));
1135 gkrellm_gtk_check_button_connected(vbox, &above_button,
1136 _GK.state_above, FALSE, FALSE, 0, cb_general, NULL,
1137 _("Set on top of other windows of the same type"));
1138 gkrellm_gtk_check_button_connected(vbox, &below_button,
1139 _GK.state_below, FALSE, FALSE, 0, cb_general, NULL,
1140 _("Set below other windows of the same type"));
1141
1142 vbox1 = gkrellm_gtk_framed_vbox(vbox, NULL, 4, FALSE, 2, 0);
1143 vbox2 = gkrellm_gtk_framed_vbox(vbox1, NULL, 0, FALSE, 0, 0);
1144 gkrellm_gtk_check_button_connected(vbox2, &dock_type_button,
1145 _GK.dock_type, FALSE, FALSE, 0,
1146 cb_dock_type, NULL,
1147 _("Set window type to be a dock or panel"));
1148
1149 vbox2 = gkrellm_gtk_framed_vbox(vbox1, NULL, 0, FALSE, 0, 0);
1150 gkrellm_gtk_check_button_connected(vbox2, &decorated_button,
1151 _GK.decorated, FALSE, FALSE, 0, cb_general, NULL,
1152 _("Use window manager decorations"));
1153
1154 gkrellm_gtk_check_button_connected(vbox2, &skip_taskbar_button,
1155 _GK.state_skip_taskbar, FALSE, FALSE, 0, cb_general, NULL,
1156 _("Do not include on a taskbar"));
1157
1158 gkrellm_gtk_check_button_connected(vbox2, &skip_pager_button,
1159 _GK.state_skip_pager, FALSE, FALSE, 0, cb_general, NULL,
1160 _("Do not include on a pager"));
1161
1162 if (_GK.dock_type)
1163 {
1164 gtk_widget_set_sensitive(decorated_button, FALSE);
1165 gtk_widget_set_sensitive(skip_taskbar_button, FALSE);
1166 gtk_widget_set_sensitive(skip_pager_button, FALSE);
1167 }
1168
1169 text = gtk_label_new(
1170 _("Some of these properties require a standards compliant window manager.\n"
1171 "You may have to restart gkrellm for them to take effect.\n"));
1172 gtk_box_pack_end(GTK_BOX(vbox), text, FALSE, TRUE, 4);
1173 #endif // !WIN32
1174
1175 /* --Info tab */
1176 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Info"));
1177 text = gkrellm_gtk_scrolled_text_view(vbox, NULL,
1178 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1179
1180 for (i = 0; i < sizeof(general_info_text)/sizeof(gchar *); ++i)
1181 gkrellm_gtk_text_view_append(text, _(general_info_text[i]));
1182 }
1183
1184
1185 /* ------------------Themes Tab----------------------------------*/
1186
1187 enum
1188 {
1189 THEME_COLUMN,
1190 PATH_COLUMN,
1191 N_THEME_COLUMNS
1192 };
1193
1194 typedef struct
1195 {
1196 gchar *path;
1197 gchar *name;
1198 }
1199 Theme;
1200
1201 static GtkTreeView *theme_treeview;
1202 static GtkTreeSelection *theme_selection;
1203
1204 static GList *themes_list;
1205 static GList *theme_position_in_list;
1206
1207 static GtkWidget *theme_alt_spin_button;
1208 static GtkWidget *theme_alt_label;
1209 static GtkWidget *theme_entry,
1210 *author_label;
1211
1212 static gboolean theme_modified;
1213
1214
1215 typedef struct
1216 {
1217 GtkFontSelectionDialog *fontseldlg;
1218 GtkWidget *entry;
1219 GtkWidget *browse_button;
1220 gchar *name;
1221 gchar *string;
1222 // PangoFontDescription *font_desc;
1223 }
1224 AltFontSelect;
1225
1226 static AltFontSelect
1227 large_font,
1228 normal_font,
1229 small_font;
1230
1231 gchar *
gkrellm_get_large_font_string(void)1232 gkrellm_get_large_font_string(void)
1233 {
1234 return large_font.string;
1235 }
1236
1237 gchar *
gkrellm_get_normal_font_string(void)1238 gkrellm_get_normal_font_string(void)
1239 {
1240 return normal_font.string;
1241 }
1242
1243 gchar *
gkrellm_get_small_font_string(void)1244 gkrellm_get_small_font_string(void)
1245 {
1246 return small_font.string;
1247 }
1248
1249 static gboolean
get_font_entries(void)1250 get_font_entries(void)
1251 {
1252 gchar *s;
1253 gboolean modified = FALSE;
1254
1255 s = (gchar *) gtk_entry_get_text(GTK_ENTRY(large_font.entry));
1256 modified |= gkrellm_dup_string(&large_font.string, s);
1257 s = (gchar *) gtk_entry_get_text(GTK_ENTRY(normal_font.entry));
1258 modified |= gkrellm_dup_string(&normal_font.string, s);
1259 s = (gchar *) gtk_entry_get_text(GTK_ENTRY(small_font.entry));
1260 modified |= gkrellm_dup_string(&small_font.string, s);
1261 return modified;
1262 }
1263
1264 static void
cb_font_dialog_ok(GtkWidget * w,AltFontSelect * afs)1265 cb_font_dialog_ok(GtkWidget *w, AltFontSelect *afs)
1266 {
1267 gchar *fontname;
1268
1269 fontname = gtk_font_selection_dialog_get_font_name(afs->fontseldlg);
1270 if (fontname)
1271 gtk_entry_set_text(GTK_ENTRY(afs->entry), fontname);
1272 gtk_widget_destroy(GTK_WIDGET(afs->fontseldlg));
1273 theme_modified = TRUE;
1274 get_font_entries();
1275 gkrellm_build();
1276 }
1277
1278 static void
cb_font_dialog(GtkWidget * widget,AltFontSelect * afs)1279 cb_font_dialog(GtkWidget *widget, AltFontSelect *afs)
1280 {
1281 GtkWidget *w;
1282 GtkFontSelectionDialog *fsd;
1283
1284 if (afs->fontseldlg)
1285 return;
1286 w = gtk_font_selection_dialog_new(_(afs->name));
1287 gtk_window_set_wmclass(GTK_WINDOW(w),
1288 "Gkrellm_dialog", "Gkrellm");
1289 fsd = GTK_FONT_SELECTION_DIALOG(w);
1290 afs->fontseldlg = fsd;
1291 gtk_font_selection_dialog_set_font_name(fsd, afs->string);
1292 g_signal_connect(G_OBJECT(fsd->ok_button), "clicked",
1293 G_CALLBACK(cb_font_dialog_ok), afs);
1294 g_signal_connect_swapped(G_OBJECT(fsd->cancel_button), "clicked",
1295 G_CALLBACK(gtk_widget_destroy), fsd);
1296 g_signal_connect(G_OBJECT(fsd), "destroy",
1297 G_CALLBACK(gtk_widget_destroyed), &afs->fontseldlg);
1298 gtk_widget_show(GTK_WIDGET(fsd));
1299 }
1300
1301 static gchar *
get_theme_author(gchar * path)1302 get_theme_author(gchar *path)
1303 {
1304 static gchar buf[128];
1305 FILE *f;
1306 gchar *s, *q, *rcfile, line[128];
1307
1308 buf[0] = '\0';
1309 if (!path || *path == '\0')
1310 return buf;
1311 rcfile = g_strdup_printf("%s/%s", path, GKRELLMRC);
1312 f = g_fopen(rcfile, "r");
1313 g_free(rcfile);
1314 if (!f)
1315 return buf;
1316 while (fgets(line, sizeof(line), f))
1317 {
1318 if ( (s = strtok(line, " :=\t\n")) == NULL
1319 || strcmp(s, "author") != 0
1320 )
1321 continue;
1322 s = strtok(NULL, "\n"); /* Rest of line is Author string */
1323 if (s)
1324 {
1325 while ( *s == ' ' || *s == '\t' || *s == '"' || *s == '='
1326 || *s == ':')
1327 ++s;
1328 q = strchr(s, (int) '"');
1329 if (q)
1330 *q = '\0';
1331 strcpy(buf, s);
1332 break;
1333 }
1334 }
1335 fclose(f);
1336 return buf;
1337 }
1338
1339 static Theme *
find_theme_in_list(gchar * name)1340 find_theme_in_list(gchar *name)
1341 {
1342 GList *list;
1343 Theme *theme;
1344
1345 if (!name || !*name)
1346 return NULL;
1347
1348 for (list = themes_list ; list; list = list->next)
1349 {
1350 theme = (Theme *) list->data;
1351 if (!strcmp(theme->name, name))
1352 return theme;
1353 }
1354 return NULL;
1355 }
1356
1357 static void
add_themes_to_list(gchar * theme_dir,gboolean in_gkrellm2)1358 add_themes_to_list(gchar *theme_dir, gboolean in_gkrellm2)
1359 {
1360 GDir *dir;
1361 Theme *theme;
1362 gchar *name;
1363 gchar *path;
1364
1365 if ((dir = g_dir_open(theme_dir, 0, NULL)) == NULL)
1366 return;
1367 while ((name = (gchar *) g_dir_read_name(dir)) != NULL)
1368 {
1369 if (find_theme_in_list(name))
1370 continue;
1371 if (in_gkrellm2)
1372 path = g_build_filename(theme_dir, name, "gkrellm2", NULL);
1373 else
1374 path = g_build_filename(theme_dir, name, NULL);
1375
1376 if (g_file_test(path, G_FILE_TEST_IS_DIR))
1377 {
1378 theme = g_new0(Theme, 1);
1379 theme->path = path;
1380 theme->name = g_strdup(name);
1381 themes_list = g_list_append(themes_list, theme);
1382 }
1383 else
1384 g_free(path);
1385 }
1386 g_dir_close(dir);
1387 }
1388
1389 static void
find_theme_position_in_list(void)1390 find_theme_position_in_list(void)
1391 {
1392 GList *list;
1393 Theme *theme;
1394 gchar *name;
1395
1396 name = *(_GK.theme_path) ? _GK.theme_path : "Default";
1397 for (list = themes_list; list; list = list->next)
1398 {
1399 theme = (Theme *) list->data;
1400 if (!strcmp(name, theme->path))
1401 break;
1402 }
1403 theme_position_in_list = list ? list : themes_list;
1404 }
1405
1406 gint
theme_compare(Theme * th1,Theme * th2)1407 theme_compare(Theme *th1, Theme *th2)
1408 {
1409 return strcmp(th1->name, th2->name);
1410 }
1411
1412 void
gkrellm_make_themes_list(void)1413 gkrellm_make_themes_list(void)
1414 {
1415 GList *list;
1416 Theme *theme;
1417 gchar *theme_dir;
1418
1419 for (list = themes_list; list; list = list->next)
1420 {
1421 theme = (Theme *) list->data;
1422 g_free(theme->path);
1423 g_free(theme->name);
1424 }
1425 gkrellm_free_glist_and_data(&themes_list);
1426
1427 theme = g_new0(Theme, 1);
1428 theme->path = g_strdup("Default");
1429 theme->name = g_strdup(theme->path);
1430 themes_list = g_list_append(themes_list, theme);
1431
1432 theme_dir = g_build_filename(gkrellm_homedir(), GKRELLM_THEMES_DIR, NULL);
1433 add_themes_to_list(theme_dir, FALSE);
1434 g_free(theme_dir);
1435
1436 theme_dir = g_build_filename(gkrellm_homedir(), ".themes", NULL);
1437 add_themes_to_list(theme_dir, TRUE);
1438 g_free(theme_dir);
1439
1440 theme_dir = gtk_rc_get_theme_dir();
1441 add_themes_to_list(theme_dir, TRUE);
1442
1443 #if defined(WIN32)
1444 gchar *install_path;
1445 install_path = g_win32_get_package_installation_directory_of_module(NULL);
1446 if (install_path != NULL)
1447 {
1448 theme_dir = g_build_filename(install_path, "share", "gkrellm2", "themes", NULL);
1449 add_themes_to_list(theme_dir, FALSE);
1450 g_free(theme_dir);
1451 g_free(install_path);
1452 }
1453 #endif
1454
1455 #if defined(LOCAL_THEMES_DIR)
1456 add_themes_to_list(LOCAL_THEMES_DIR, FALSE);
1457 #endif
1458 #if defined(SYSTEM_THEMES_DIR)
1459 add_themes_to_list(SYSTEM_THEMES_DIR, FALSE);
1460 #endif
1461
1462 themes_list = g_list_sort(themes_list, (GCompareFunc) theme_compare);
1463
1464 if (_GK.command_line_theme)
1465 {
1466 theme = g_new0(Theme, 1);
1467 theme->path = g_strdup(_GK.command_line_theme);
1468 theme->name = g_strdup(theme->path);
1469 themes_list = g_list_append(themes_list, theme);
1470 }
1471 find_theme_position_in_list();
1472 }
1473
1474 static GtkTreeModel *
theme_create_model(void)1475 theme_create_model(void)
1476 {
1477 GtkListStore *store;
1478 GtkTreeIter iter;
1479 GList *list;
1480 Theme *theme;
1481
1482 gkrellm_make_themes_list();
1483 store = gtk_list_store_new(N_THEME_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
1484 for (list = themes_list; list; list = list->next)
1485 {
1486 theme = (Theme *) list->data;
1487 gtk_list_store_append(store, &iter);
1488 gtk_list_store_set(store, &iter,
1489 THEME_COLUMN, theme->name,
1490 PATH_COLUMN, theme->path,
1491 -1);
1492 }
1493 return GTK_TREE_MODEL(store);
1494 }
1495
1496 static void
cb_theme_tree_selection_changed(GtkTreeSelection * selection,gpointer data)1497 cb_theme_tree_selection_changed(GtkTreeSelection *selection, gpointer data)
1498 {
1499 GtkTreeIter iter;
1500 GtkTreeModel *model;
1501 gchar *path;
1502
1503 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
1504 return;
1505 gtk_spin_button_set_value(GTK_SPIN_BUTTON(theme_alt_spin_button), 0.0);
1506 gtk_tree_model_get(model, &iter, PATH_COLUMN, &path, -1);
1507 gtk_entry_set_text(GTK_ENTRY(theme_entry), path);
1508 gtk_label_set_text(GTK_LABEL(author_label), get_theme_author(path));
1509 if (gkrellm_dup_string(&_GK.theme_path, path))
1510 {
1511 find_theme_position_in_list();
1512 theme_modified = TRUE;
1513 gkrellm_build();
1514 }
1515 }
1516
1517 static void
cb_theme_alternative_changed(GtkWidget * widget,GtkSpinButton * spin)1518 cb_theme_alternative_changed(GtkWidget *widget, GtkSpinButton *spin)
1519 {
1520 gint i;
1521
1522 i = gtk_spin_button_get_value_as_int(spin);
1523 if (i > _GK.theme_n_alternatives)
1524 {
1525 i = _GK.theme_n_alternatives;
1526 gtk_spin_button_set_value(spin, (gfloat) i);
1527 }
1528 if (i != _GK.theme_alternative)
1529 {
1530 _GK.theme_alternative = i;
1531 theme_modified = TRUE;
1532 gkrellm_build();
1533 }
1534 }
1535
1536 static void
cb_theme_scale_changed(GtkWidget * widget,GtkSpinButton * spin)1537 cb_theme_scale_changed(GtkWidget *widget, GtkSpinButton *spin)
1538 {
1539 gint i;
1540
1541 i = gtk_spin_button_get_value_as_int(spin);
1542 if (i != _GK.theme_scale)
1543 {
1544 _GK.theme_scale = i;
1545 theme_modified = TRUE;
1546 gkrellm_build();
1547 }
1548 }
1549
1550 void
gkrellm_set_theme_alternatives_label(void)1551 gkrellm_set_theme_alternatives_label(void)
1552 {
1553 GtkSpinButton *spin;
1554 gchar buf[64];
1555
1556 if (!config_window)
1557 return;
1558 spin = GTK_SPIN_BUTTON(theme_alt_spin_button);
1559 gtk_spin_button_set_value(spin, (gfloat) _GK.theme_alternative);
1560 snprintf(buf, sizeof(buf), _("%d total theme alternatives"),
1561 _GK.theme_n_alternatives);
1562 gtk_label_set_text(GTK_LABEL(theme_alt_label), buf);
1563 }
1564
1565 void
gkrellm_save_theme_config(void)1566 gkrellm_save_theme_config(void)
1567 {
1568 FILE *f;
1569 gchar *path;
1570
1571 /* Assume gkrellm -t is for testing and don't save theme config changes.
1572 | Similarly for _GK.demo.
1573 */
1574 if (!theme_modified || _GK.command_line_theme || _GK.demo || _GK.no_config)
1575 return;
1576
1577 path = gkrellm_make_config_file_name(gkrellm_homedir(),
1578 GKRELLM_THEME_CONFIG);
1579
1580 if ((f = g_fopen(path, "w")) != NULL)
1581 {
1582 fprintf(f, "%s\n", _GK.theme_path);
1583 fprintf(f, "%d\n", _GK.theme_alternative);
1584 fprintf(f, "%s\n", large_font.string);
1585 fprintf(f, "%s\n", normal_font.string);
1586 fprintf(f, "%s\n", small_font.string);
1587 fprintf(f, "%d\n", _GK.theme_scale);
1588 fclose(f);
1589 }
1590 g_free(path);
1591 theme_modified = FALSE;
1592 }
1593
1594 void
gkrellm_load_theme_config(void)1595 gkrellm_load_theme_config(void)
1596 {
1597 FILE *f;
1598 gchar *path, *s;
1599 gchar buf[1024];
1600 gint i;
1601
1602 /* Need to load the theme from ~/.gkrellm/theme_config only at startup
1603 | or if re-reading because of theme_event - these are only times
1604 | _GK.theme_path will be NULL. Note: _GK.theme_path will not be NULL
1605 | at startup if there is a command line theme, so no theme scaling if
1606 | using command line theme.
1607 */
1608 if (!_GK.theme_path)
1609 {
1610 path = gkrellm_make_config_file_name(gkrellm_homedir(),
1611 GKRELLM_THEME_CONFIG);
1612 f = g_fopen(path, "r");
1613 g_free(path);
1614 if (f && fgets(buf, sizeof(buf), f))
1615 {
1616 if ((s = strchr(buf, (gint) '\n')) != NULL)
1617 *s = '\0';
1618 gkrellm_debug(DEBUG_GUI, "gkrellm_load_theme_config: %s\n", buf);
1619 s = buf;
1620 if (s && *s != '#' && *s != '\0' && strcmp(s, "Default"))
1621 {
1622 if (*s == '/' || s[1] == ':')
1623 _GK.theme_path = g_strdup(s);
1624 else
1625 _GK.theme_path = g_strdup_printf("%s/%s/%s",
1626 gkrellm_homedir(), GKRELLM_THEMES_DIR, s);
1627 }
1628 for (i = 0; fgets(buf, sizeof(buf), f); ++i)
1629 {
1630 if ((s = strchr(buf, (gint) '\n')) != NULL)
1631 *s = '\0';
1632 gkrellm_debug(DEBUG_GUI, "gkrellm_load_theme_config: %s\n", buf);
1633 if (i == 0)
1634 sscanf(buf, "%d", &_GK.theme_alternative);
1635 if (i == 1 && !strstr(buf, "*-*")) /* XXX Trap out GdkFont */
1636 gkrellm_dup_string(&large_font.string, buf);
1637 if (i == 2 && !strstr(buf, "*-*"))
1638 gkrellm_dup_string(&normal_font.string, buf);
1639 if (i == 3 && !strstr(buf, "*-*"))
1640 gkrellm_dup_string(&small_font.string, buf);
1641 if (i == 4)
1642 sscanf(buf, "%d", &_GK.theme_scale);
1643 }
1644 }
1645 if (f)
1646 fclose(f);
1647 }
1648 if (!_GK.theme_path || !g_file_test(_GK.theme_path, G_FILE_TEST_IS_DIR))
1649 gkrellm_dup_string(&_GK.theme_path, "");
1650 if (!large_font.string)
1651 gkrellm_dup_string(&large_font.string, "Serif 11");
1652 if (!normal_font.string)
1653 gkrellm_dup_string(&normal_font.string, "Serif 9");
1654 if (!small_font.string)
1655 gkrellm_dup_string(&small_font.string, "Serif 8");
1656 }
1657
1658
1659 void
gkrellm_read_theme_event(GtkSettings * settings)1660 gkrellm_read_theme_event(GtkSettings *settings)
1661 {
1662 Theme *theme;
1663 gchar *s, *theme_name = NULL;
1664 gint alt = 0;
1665
1666 if (settings) /* called via "notify::gtk-theme-name" signal connect, */
1667 /* so get the current gtk theme name and switch to it */
1668 {
1669 g_object_get(_GK.gtk_settings, "gtk-theme-name", &theme_name, NULL);
1670 if (theme_name)
1671 gkrellm_debug(DEBUG_GUI, "notify::gtk-theme-name: %s\n", theme_name);
1672
1673 if ( gkrellm_dup_string(&_GK.gtk_theme_name, theme_name)
1674 && _GK.track_gtk_theme_name
1675 )
1676 {
1677 theme = find_theme_in_list(theme_name);
1678 if (!theme)
1679 {
1680 theme_name = g_strdup(_GK.default_track_theme);
1681 if ((s = strrchr(theme_name, ':')) != NULL)
1682 {
1683 *s++ = '\0';
1684 alt = atoi(s);
1685 }
1686 theme = find_theme_in_list(theme_name);
1687 g_free(theme_name);
1688 }
1689 if ( theme && theme->path
1690 && gkrellm_dup_string(&_GK.theme_path,
1691 strcmp(theme->path, "Default") ? theme->path : "")
1692 )
1693 {
1694 _GK.theme_alternative = alt;
1695 theme_modified = TRUE;
1696 gkrellm_save_theme_config();
1697 gkrellm_build();
1698 }
1699 }
1700 }
1701 else /* Called from cb_client_event() because we were sent the */
1702 /* _GKRELLM_READ_THEME client event, so reread theme config. */
1703 {
1704 g_free(_GK.theme_path);
1705 _GK.theme_path = NULL; /* Forces reread of GKRELLM_THEME_CONFIG */
1706 gkrellm_build();
1707 }
1708 }
1709
1710 static void
cb_load_theme(GtkAction * action,GtkWidget * widget)1711 cb_load_theme(GtkAction *action, GtkWidget *widget)
1712 {
1713 GtkTreeIter iter;
1714 GtkTreeModel *model;
1715 GtkTreePath *path;
1716 Theme *theme;
1717 gint row;
1718 const gchar *act = gtk_action_get_name(action);
1719
1720 ++_GK.theme_reload_count;
1721 if (_GK.no_config)
1722 return;
1723 if (!themes_list)
1724 gkrellm_make_themes_list();
1725 if (strcmp(act, "ThemeAltNextAction") == 0 || strcmp(act, "ThemeAltPrevAction") == 0)
1726 {
1727 _GK.theme_alternative += ((strcmp(act, "ThemeAltNextAction") == 0) ? 1 : -1);
1728 if (_GK.theme_alternative > _GK.theme_n_alternatives)
1729 {
1730 _GK.theme_alternative = 0;
1731 act = "ThemeNextAction";
1732 }
1733 if (_GK.theme_alternative < 0)
1734 {
1735 _GK.theme_alternative = 100;
1736 act = "ThemePrevAction";
1737 }
1738 theme_modified = TRUE;
1739 }
1740
1741 if (strcmp(act, "ThemeNextAction") == 0 || strcmp(act, "ThemePrevAction") == 0)
1742 {
1743 _GK.theme_alternative = 0;
1744 if (strcmp(act, "ThemeNextAction") == 0)
1745 {
1746 theme_position_in_list = theme_position_in_list->next;
1747 if (!theme_position_in_list)
1748 theme_position_in_list = themes_list;
1749 }
1750 else
1751 {
1752 theme_position_in_list = theme_position_in_list->prev;
1753 if (!theme_position_in_list)
1754 theme_position_in_list = g_list_last(themes_list);
1755 }
1756 if (config_window)
1757 {
1758 row = g_list_position(themes_list, theme_position_in_list);
1759 model = gtk_tree_view_get_model(theme_treeview);
1760 gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
1761 path = gtk_tree_model_get_path(model, &iter);
1762 gtk_tree_view_set_cursor(theme_treeview, path, NULL, FALSE);
1763 return; /* cb_theme_tree_selection_changed -> gkrellm_build()*/
1764 }
1765 theme = (Theme *) theme_position_in_list->data;
1766 gkrellm_dup_string(&_GK.theme_path,
1767 strcmp(theme->path, "Default") ? theme->path : "");
1768 theme_modified = TRUE;
1769 }
1770 if (strcmp(act, "ThemeScaleUp") == 0 && _GK.theme_scale < 380)
1771 {
1772 _GK.theme_scale += 20;
1773 theme_modified = TRUE;
1774 }
1775 else if (strcmp(act, "ThemeScaleDn") == 0 && _GK.theme_scale > 50)
1776 {
1777 _GK.theme_scale -= 20;
1778 theme_modified = TRUE;
1779 }
1780 gkrellm_build();
1781 }
1782
1783 static void
destroy_font_dialogs(void)1784 destroy_font_dialogs(void)
1785 {
1786 if (large_font.fontseldlg)
1787 gtk_widget_destroy(GTK_WIDGET(large_font.fontseldlg));
1788 if (normal_font.fontseldlg)
1789 gtk_widget_destroy(GTK_WIDGET(normal_font.fontseldlg));
1790 if (small_font.fontseldlg)
1791 gtk_widget_destroy(GTK_WIDGET(small_font.fontseldlg));
1792 }
1793
1794 static void
close_theme_config(gint from_close)1795 close_theme_config(gint from_close)
1796 {
1797 destroy_font_dialogs();
1798 }
1799
1800 static void
cb_font_entry_activate(GtkWidget * widget,gpointer * data)1801 cb_font_entry_activate(GtkWidget *widget, gpointer *data)
1802 {
1803 if (!get_font_entries())
1804 return;
1805 theme_modified = TRUE;
1806 gkrellm_build();
1807 }
1808
1809 static void
cb_font_entry_changed(GtkWidget * widget,gpointer * data)1810 cb_font_entry_changed(GtkWidget *widget, gpointer *data)
1811 {
1812 theme_modified = TRUE;
1813 }
1814
1815 gfloat
gkrellm_get_theme_scale(void)1816 gkrellm_get_theme_scale(void)
1817 {
1818 return (gfloat) (_GK.theme_scale) / 100.0;
1819 }
1820
1821 #ifndef WIN32
1822 static void
cb_track_gtk(GtkToggleButton * button,GtkWidget * box)1823 cb_track_gtk(GtkToggleButton *button, GtkWidget *box)
1824 {
1825 _GK.track_gtk_theme_name = button->active;
1826 gtk_widget_set_sensitive(box, _GK.track_gtk_theme_name);
1827 }
1828
1829 static void
cb_track_entry_changed(GtkWidget * widget,gpointer * data)1830 cb_track_entry_changed(GtkWidget *widget, gpointer *data)
1831 {
1832 gchar *s;
1833
1834 s = gkrellm_gtk_entry_get_text(&widget);
1835 gkrellm_dup_string(&_GK.default_track_theme, s);
1836 gkrellm_config_modified();
1837 }
1838 #endif // !WIN32
1839
1840 static void
create_theme_tab(GtkWidget * tabs_vbox)1841 create_theme_tab(GtkWidget *tabs_vbox)
1842 {
1843 GtkWidget *tabs;
1844 GtkWidget *vbox, *vbox1, *vbox2, *hbox;
1845 GtkWidget *label;
1846 #if !defined(WIN32)
1847 GtkWidget *entry;
1848 #endif // !WIN32
1849 GtkWidget *scrolled;
1850 GtkTreeModel *model;
1851 GtkCellRenderer *renderer;
1852 gchar *s;
1853
1854 tabs = gtk_notebook_new();
1855 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
1856 gtk_box_pack_start(GTK_BOX(tabs_vbox), tabs, TRUE, TRUE, 0);
1857
1858 /* --Theme tab */
1859 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Theme"));
1860
1861 hbox = gtk_hbox_new (FALSE, 0);
1862 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1863 label = gtk_label_new(_("Theme:"));
1864 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3);
1865 theme_entry = gtk_entry_new();
1866 gtk_entry_set_max_length(GTK_ENTRY(theme_entry), 128);
1867 if (_GK.theme_path)
1868 gtk_entry_set_text(GTK_ENTRY(theme_entry), _GK.theme_path);
1869 gtk_box_pack_start(GTK_BOX(hbox), theme_entry, TRUE, TRUE,0);
1870
1871 hbox = gtk_hbox_new (FALSE, 0);
1872 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1873 label = gtk_label_new(_("Author:"));
1874 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3);
1875 author_label = gtk_label_new(get_theme_author(_GK.theme_path));
1876 gtk_misc_set_alignment(GTK_MISC(author_label), 0, 0.5);
1877 gtk_box_pack_start(GTK_BOX(hbox), author_label, TRUE, TRUE, 5);
1878
1879 vbox1 = gkrellm_gtk_framed_vbox(vbox, NULL, 4, TRUE, 0, 2);
1880 scrolled = gtk_scrolled_window_new(NULL, NULL);
1881 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1882 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1883 gtk_box_pack_start(GTK_BOX(vbox1), scrolled, TRUE, TRUE, 0);
1884
1885 model = theme_create_model();
1886 theme_treeview = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
1887 g_object_unref(G_OBJECT(model));
1888 gtk_tree_view_set_rules_hint(theme_treeview, TRUE);
1889 renderer = gtk_cell_renderer_text_new();
1890 gtk_tree_view_insert_column_with_attributes(theme_treeview, -1,
1891 _("Theme"), renderer,
1892 "text", THEME_COLUMN, NULL);
1893 gtk_container_add(GTK_CONTAINER(scrolled), GTK_WIDGET(theme_treeview));
1894 theme_selection = gtk_tree_view_get_selection(theme_treeview);
1895 gtk_tree_selection_set_mode(theme_selection, GTK_SELECTION_SINGLE);
1896 g_signal_connect(G_OBJECT(theme_selection), "changed",
1897 G_CALLBACK(cb_theme_tree_selection_changed), NULL);
1898
1899 hbox = gtk_hbox_new (FALSE, 0);
1900 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
1901 gkrellm_gtk_spin_button(hbox, &theme_alt_spin_button,
1902 (gfloat)_GK.theme_alternative, 0.0, 100.0, 1.0, 5.0, 0, 60,
1903 cb_theme_alternative_changed, NULL, FALSE, NULL);
1904 theme_alt_label = gtk_label_new("");
1905 gtk_box_pack_start (GTK_BOX (hbox), theme_alt_label, TRUE, TRUE, 4);
1906 gtk_misc_set_alignment(GTK_MISC(theme_alt_label), 0, 0.5);
1907 gkrellm_set_theme_alternatives_label();
1908
1909
1910 /* -- Options tab */
1911 vbox = gkrellm_gtk_notebook_page(tabs, _("Options"));
1912 vbox = gkrellm_gtk_framed_vbox(vbox, NULL, 2, TRUE, 10, 4);
1913
1914 #if !defined(WIN32)
1915 vbox1 = gtk_vbox_new(FALSE, 0);
1916 gkrellm_gtk_check_button_connected(vbox, &track_gtk_button,
1917 _GK.track_gtk_theme_name, FALSE, FALSE, 0,
1918 cb_track_gtk, vbox1,
1919 _("Track Gtk theme changes for similarly named themes"));
1920 gtk_widget_set_sensitive(vbox1, _GK.track_gtk_theme_name);
1921 gtk_box_pack_start(GTK_BOX(vbox), vbox1, FALSE, FALSE, 0);
1922
1923 vbox1 = gkrellm_gtk_category_vbox(vbox1, NULL, 0, 0, TRUE);
1924 hbox = gtk_hbox_new(FALSE, 0);
1925 gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
1926 label = gtk_label_new(_("Default"));
1927 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1928 entry = gtk_entry_new();
1929 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
1930 gtk_entry_set_text(GTK_ENTRY(entry), _GK.default_track_theme);
1931 g_signal_connect(G_OBJECT(entry), "changed",
1932 G_CALLBACK(cb_track_entry_changed), NULL);
1933
1934 #endif // !WIN32
1935
1936 hbox = gtk_hbox_new (FALSE, 0);
1937 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
1938 gkrellm_gtk_spin_button(hbox, NULL,
1939 (gfloat)_GK.theme_scale, 40.0, 400.0, 10.0, 20.0, 0, 60,
1940 cb_theme_scale_changed, NULL, FALSE, NULL);
1941 label = gtk_label_new(_("Scale"));
1942 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 4);
1943 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1944
1945
1946 /* --Fonts tab */
1947 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Fonts"));
1948 vbox1 = gkrellm_gtk_framed_vbox(vbox, NULL, 2, FALSE, 0, 2);
1949
1950 vbox2 = gkrellm_gtk_framed_vbox(vbox1, _("Large font"), 4, FALSE, 0, 3);
1951 hbox = gtk_hbox_new(FALSE, 0);
1952 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, TRUE, 0);
1953
1954 large_font.entry = gtk_entry_new();
1955 gtk_box_pack_start(GTK_BOX(hbox), large_font.entry, TRUE, TRUE, 0);
1956 gtk_entry_set_text(GTK_ENTRY(large_font.entry), large_font.string);
1957 g_signal_connect(G_OBJECT(large_font.entry), "changed",
1958 G_CALLBACK(cb_font_entry_changed), NULL);
1959 g_signal_connect(G_OBJECT(large_font.entry), "activate",
1960 G_CALLBACK(cb_font_entry_activate), NULL);
1961 gkrellm_gtk_button_connected(hbox, &large_font.browse_button, FALSE, FALSE,
1962 0, cb_font_dialog, &large_font, _("Browse"));
1963
1964 vbox2 = gkrellm_gtk_framed_vbox(vbox1, _("Normal font"), 4, FALSE, 0, 3);
1965 hbox = gtk_hbox_new(FALSE, 0);
1966 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, TRUE, 0);
1967 normal_font.entry = gtk_entry_new();
1968 gtk_box_pack_start(GTK_BOX(hbox), normal_font.entry, TRUE, TRUE, 0);
1969 gtk_entry_set_text(GTK_ENTRY(normal_font.entry), normal_font.string);
1970 g_signal_connect(G_OBJECT(normal_font.entry), "changed",
1971 G_CALLBACK(cb_font_entry_changed), NULL);
1972 g_signal_connect(G_OBJECT(normal_font.entry), "activate",
1973 G_CALLBACK(cb_font_entry_activate), NULL);
1974 gkrellm_gtk_button_connected(hbox, &normal_font.browse_button,
1975 FALSE, FALSE, 0, cb_font_dialog, &normal_font,
1976 _("Browse"));
1977
1978 vbox2 = gkrellm_gtk_framed_vbox(vbox1, _("Small font"), 4, FALSE, 0, 3);
1979 hbox = gtk_hbox_new(FALSE, 0);
1980 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, TRUE, 0);
1981 small_font.entry = gtk_entry_new();
1982 gtk_box_pack_start(GTK_BOX(hbox), small_font.entry, TRUE, TRUE, 0);
1983 gtk_entry_set_text(GTK_ENTRY(small_font.entry), small_font.string);
1984 g_signal_connect(G_OBJECT(small_font.entry), "changed",
1985 G_CALLBACK(cb_font_entry_changed), NULL);
1986 g_signal_connect(G_OBJECT(small_font.entry), "activate",
1987 G_CALLBACK(cb_font_entry_activate), NULL);
1988 gkrellm_gtk_button_connected(hbox, &small_font.browse_button, FALSE, FALSE,
1989 0, cb_font_dialog, &small_font, _("Browse"));
1990
1991 /* --Info tab*/
1992 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Info"));
1993 s = g_strdup_printf(_("Untar your theme tar files in %s/%s"),
1994 gkrellm_homedir(), GKRELLM_THEMES_DIR);
1995 label = gtk_label_new(s);
1996 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
1997 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1998 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
1999 g_free(s);
2000
2001 label = gtk_label_new(
2002 _("Download themes from the GKrellM theme site at www.muhri.net"));
2003 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
2004 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
2005 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
2006
2007
2008 }
2009
2010
2011 /* ================================================================ */
2012 /* A simple tree store model for selecting monitor configs.
2013 */
2014 enum
2015 {
2016 NAME_COLUMN,
2017 MONITOR_COLUMN,
2018 PAGE_COLUMN,
2019 N_COLUMNS
2020 };
2021
2022 static GtkNotebook *config_notebook;
2023
2024 static gboolean expand_builtins,
2025 expand_plugins;
2026
2027 static GtkTreeView *treeview;
2028 static GtkTreeStore *model;
2029
2030 static GtkWidget *apply_button,
2031 *close_button;
2032
2033 static GkrellmMonitor *selected_monitor;
2034
2035 static void
close_config(gpointer data)2036 close_config(gpointer data)
2037 {
2038 GtkTreePath *path;
2039 gint from_close = GPOINTER_TO_INT(data);
2040
2041 path = gtk_tree_path_new_from_string("1");
2042 expand_builtins = gtk_tree_view_row_expanded(treeview, path);
2043 gtk_tree_path_free(path);
2044
2045 path = gtk_tree_path_new_from_string("2");
2046 expand_plugins = gtk_tree_view_row_expanded(treeview, path);
2047 gtk_tree_path_free(path);
2048
2049 g_object_unref(G_OBJECT(model));
2050 gtk_widget_destroy(config_window);
2051 config_window = NULL;
2052
2053 gkrellm_plugins_config_close();
2054 close_theme_config(from_close);
2055 if (_GK.config_modified)
2056 gkrellm_save_user_config();
2057 gkrellm_save_theme_config();
2058 }
2059
2060
2061 static void
apply_config(void)2062 apply_config(void)
2063 {
2064 GList *list;
2065 GkrellmMonitor *mon;
2066
2067 gkrellm_freeze_side_frame_packing();
2068 for (list = gkrellm_monitor_list; list; list = list->next)
2069 {
2070 mon = (GkrellmMonitor *) list->data;
2071 if ( mon->apply_config && mon->privat->enabled
2072 && (mon->privat->config_created || !mon->create_config)
2073 )
2074 {
2075 gkrellm_record_state(APPLY_CONFIG, mon);
2076 (*(mon->apply_config))();
2077 gkrellm_record_state(INTERNAL, NULL);
2078 }
2079 }
2080 gkrellm_thaw_side_frame_packing();
2081 gkrellm_config_modified();
2082 }
2083
2084 static void
OK_config(void)2085 OK_config(void)
2086 {
2087 apply_config();
2088 close_config(GINT_TO_POINTER(0));
2089 }
2090
2091
2092 static GtkWidget *
create_config_page(GkrellmMonitor * mon,GtkTreeStore * tree,GtkTreeIter * iter,GtkNotebook * notebook)2093 create_config_page(GkrellmMonitor *mon, GtkTreeStore *tree, GtkTreeIter *iter,
2094 GtkNotebook *notebook)
2095 {
2096 GtkWidget *vbox;
2097 gint page;
2098
2099 vbox = gtk_vbox_new(FALSE, 0);
2100 gtk_notebook_append_page(notebook, vbox, NULL);
2101 page = g_list_length(notebook->children) - 1;
2102
2103 if (mon)
2104 mon->privat->config_page = page;
2105
2106 gtk_tree_store_set(tree, iter,
2107 MONITOR_COLUMN, mon,
2108 PAGE_COLUMN, page,
2109 -1);
2110
2111 gkrellm_debug(DEBUG_GUI, "create_config_page %d: %s\n", page,
2112 mon ? mon->name : "--");
2113
2114 return vbox;
2115 }
2116
2117 static void
real_create_config(GkrellmMonitor * mon)2118 real_create_config(GkrellmMonitor *mon)
2119 {
2120 if (mon->privat->config_created || !mon->create_config)
2121 return;
2122
2123 gkrellm_record_state(CREATE_CONFIG, mon);
2124 (*(mon->create_config))(mon->privat->config_vbox);
2125 gkrellm_record_state(INTERNAL, NULL);
2126
2127 gtk_widget_show_all(mon->privat->config_vbox);
2128 mon->privat->config_created = TRUE;
2129 }
2130
2131 void
gkrellm_add_plugin_config_page(GkrellmMonitor * mon)2132 gkrellm_add_plugin_config_page(GkrellmMonitor *mon)
2133 {
2134 GtkTreeIter iter, plugin_iter;
2135 GtkTreePath *path;
2136
2137 if (config_window && mon->create_config)
2138 {
2139 path = gtk_tree_path_new_from_string("2");
2140 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &plugin_iter, path);
2141 gtk_tree_path_free(path);
2142
2143 gtk_tree_store_append(model, &iter, &plugin_iter);
2144 gtk_tree_store_set(model, &iter, NAME_COLUMN, mon->name, -1);
2145 mon->privat->config_vbox =
2146 create_config_page(mon, model, &iter, config_notebook);
2147 mon->privat->config_created = FALSE;
2148
2149 mon->privat->row_reference =
2150 gtk_tree_row_reference_new(GTK_TREE_MODEL(model),
2151 gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iter));
2152 }
2153 else
2154 mon->privat->config_page = -1;
2155 }
2156
2157 void
gkrellm_remove_plugin_config_page(GkrellmMonitor * mon)2158 gkrellm_remove_plugin_config_page(GkrellmMonitor *mon)
2159 {
2160 GtkTreePath *path;
2161 GtkTreeIter iter;
2162 GList *list;
2163 GkrellmMonitor *tmon;
2164
2165 if (mon->privat->config_page > 0)
2166 {
2167 path = gtk_tree_row_reference_get_path(mon->privat->row_reference);
2168 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
2169 gtk_tree_store_remove(model, &iter);
2170
2171 gtk_notebook_remove_page(config_notebook, mon->privat->config_page);
2172
2173 /* When a config_page is removed, any greater plugin config_page must
2174 | be decremented
2175 */
2176 for (list = gkrellm_monitor_list; list; list = list->next)
2177 {
2178 tmon = (GkrellmMonitor *) list->data;
2179 if (mon->privat->config_page >= tmon->privat->config_page)
2180 continue;
2181 tmon->privat->config_page -= 1;
2182 gkrellm_debug(DEBUG_GUI, "config_page %d: %s\n",
2183 tmon->privat->config_page, tmon->name);
2184 }
2185 }
2186 mon->privat->config_page = -1;
2187 }
2188
2189 /* If a config page uses instant apply, hide the APPLY/CLOSE buttons and
2190 | assume the config will be modified.
2191 */
2192 static void
set_apply_mode(gboolean instant)2193 set_apply_mode(gboolean instant)
2194 {
2195 if (instant)
2196 {
2197 gtk_widget_hide(apply_button);
2198 gtk_widget_hide(close_button);
2199 gkrellm_config_modified();
2200 }
2201 else
2202 {
2203 gtk_widget_show(apply_button);
2204 gtk_widget_show(close_button);
2205 }
2206 }
2207
2208 static void
cb_tree_selection_changed(GtkTreeSelection * selection,gpointer data)2209 cb_tree_selection_changed(GtkTreeSelection *selection, gpointer data)
2210 {
2211 GtkTreeIter iter;
2212 GtkTreeModel *model;
2213 gint page;
2214 gboolean instant;
2215
2216 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
2217 return;
2218 if (selected_monitor && selected_monitor->apply_config)
2219 {
2220 gkrellm_record_state(APPLY_CONFIG, selected_monitor);
2221 (*(selected_monitor->apply_config))();
2222 gkrellm_record_state(INTERNAL, NULL);
2223 }
2224 gtk_tree_model_get(model, &iter,
2225 MONITOR_COLUMN, &selected_monitor,
2226 PAGE_COLUMN, &page,
2227 -1);
2228 if (selected_monitor && selected_monitor->privat)
2229 {
2230 page = selected_monitor->privat->config_page;
2231 real_create_config(selected_monitor);
2232 if (selected_monitor == gkrellm_get_sensors_mon())
2233 { /* Special case dependencies in the configs */
2234 real_create_config(gkrellm_get_cpu_mon());
2235 real_create_config(gkrellm_get_proc_mon());
2236 }
2237 instant = ( selected_monitor->apply_config == NULL
2238 || selected_monitor->privat->instant_apply);
2239 }
2240 else
2241 instant = TRUE;
2242
2243 set_apply_mode(instant);
2244
2245 gtk_notebook_set_current_page(config_notebook, page);
2246 gkrellm_debug(DEBUG_GUI, "tree_selection_changed %d: %s\n",
2247 page, selected_monitor ? selected_monitor->name : "--");
2248 }
2249
2250 /* Monitors may want to present as instant apply monitors, but still need
2251 | their apply function called when changing notebook pages or on OK button.
2252 */
2253 void
gkrellm_config_instant_apply(GkrellmMonitor * mon)2254 gkrellm_config_instant_apply(GkrellmMonitor *mon)
2255 {
2256 mon->privat->instant_apply = TRUE;
2257 }
2258
2259 gboolean
gkrellm_config_window_shown(void)2260 gkrellm_config_window_shown(void)
2261 {
2262 return config_window ? TRUE : FALSE;
2263 }
2264
2265 void
create_config_window(void)2266 create_config_window(void)
2267 {
2268 GtkWidget *widget,
2269 *vbox,
2270 *main_vbox,
2271 *config_hbox,
2272 *hbox;
2273 GtkWidget *scrolled;
2274 GtkWidget *button;
2275 GtkTreeIter iter, citer;
2276 GtkTreePath *path;
2277 GtkCellRenderer *renderer;
2278 GtkTreeViewColumn *column;
2279 GtkTreeSelection *select;
2280 GList *list;
2281 GkrellmMonitor *mon;
2282 gchar *config_name, *window_title;
2283
2284 if (config_window)
2285 {
2286 gtk_window_present(GTK_WINDOW(config_window));
2287 return;
2288 }
2289 selected_monitor = NULL;
2290
2291 config_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2292 g_signal_connect(G_OBJECT(config_window), "delete_event",
2293 G_CALLBACK(close_config), GINT_TO_POINTER(1));
2294
2295 config_name = gkrellm_make_config_file_name(NULL, "GKrellM");
2296 window_title = g_strdup_printf("%s %s", config_name, _("Configuration"));
2297 gtk_window_set_title(GTK_WINDOW(config_window), window_title);
2298 g_free(config_name);
2299 g_free(window_title);
2300
2301 gtk_window_set_wmclass(GTK_WINDOW(config_window),
2302 "Gkrellm_conf", "Gkrellm");
2303 gtk_container_set_border_width(GTK_CONTAINER(config_window), 2);
2304
2305 config_hbox = gtk_hbox_new(FALSE, 4);
2306 gtk_container_add(GTK_CONTAINER(config_window), config_hbox);
2307
2308 scrolled = gtk_scrolled_window_new(NULL, NULL);
2309 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
2310 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2311 gtk_box_pack_start(GTK_BOX(config_hbox), scrolled, FALSE, FALSE, 0);
2312
2313 main_vbox = gtk_vbox_new(FALSE, 4);
2314 gtk_box_pack_start(GTK_BOX(config_hbox), main_vbox, TRUE, TRUE, 0);
2315
2316 widget = gtk_notebook_new();
2317 gtk_box_pack_start(GTK_BOX(main_vbox), widget, TRUE, TRUE, 0);
2318 config_notebook = GTK_NOTEBOOK(widget);
2319 gtk_notebook_set_show_tabs(config_notebook, FALSE);
2320
2321 model = gtk_tree_store_new(N_COLUMNS,
2322 G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT);
2323 gtk_tree_store_append(model, &iter, NULL);
2324 gtk_tree_store_set(model, &iter, NAME_COLUMN, _("General"), -1);
2325 vbox = create_config_page(NULL, model, &iter, config_notebook);
2326 create_general_tab(vbox);
2327
2328 gtk_tree_store_append(model, &iter, NULL);
2329 gtk_tree_store_set(model, &iter, NAME_COLUMN, _("Builtins"), -1);
2330 vbox = create_config_page(NULL, model, &iter, config_notebook);
2331
2332 for (list = gkrellm_monitor_list; list; list = list->next)
2333 {
2334 mon = (GkrellmMonitor *) list->data;
2335 if (MONITOR_ID(mon) == MON_PLUGIN || ! mon->create_config)
2336 continue;
2337
2338 gtk_tree_store_append(model, &citer, &iter);
2339 gtk_tree_store_set(model, &citer, NAME_COLUMN, mon->name, -1);
2340 mon->privat->config_vbox =
2341 create_config_page(mon, model, &citer, config_notebook);
2342 mon->privat->config_created = FALSE;
2343 mon->privat->row_reference =
2344 gtk_tree_row_reference_new(GTK_TREE_MODEL(model),
2345 gtk_tree_model_get_path(GTK_TREE_MODEL(model), &citer));
2346 }
2347
2348 gtk_tree_store_append(model, &iter, NULL);
2349 gtk_tree_store_set(model, &iter, NAME_COLUMN, _("Plugins"), -1);
2350 vbox = create_config_page(NULL, model, &iter, config_notebook);
2351 gkrellm_plugins_config_create(vbox);
2352
2353 gtk_tree_store_append(model, &iter, NULL);
2354 gtk_tree_store_set(model, &iter, NAME_COLUMN, _("Themes"), -1);
2355 vbox = create_config_page(NULL, model, &iter, config_notebook);
2356 create_theme_tab(vbox);
2357
2358 gtk_tree_store_append(model, &iter, NULL);
2359 gtk_tree_store_set(model, &iter, NAME_COLUMN, _("About"), -1);
2360 vbox = create_config_page(NULL, model, &iter, config_notebook);
2361 create_about_tab(vbox);
2362
2363 /* Add plugin notebook pages last since they may need special add/remove
2364 | actions as plugins are enabled/disabled.
2365 */
2366 for (list = gkrellm_monitor_list; list; list = list->next)
2367 {
2368 mon = (GkrellmMonitor *) list->data;
2369 if ( ! mon->create_config
2370 || ! mon->privat->enabled
2371 || MONITOR_ID(mon) != MON_PLUGIN
2372 )
2373 continue;
2374 gkrellm_add_plugin_config_page(mon);
2375 }
2376
2377 /* Create the tree view and don't unref the model because need to modify
2378 | it when enabling plugins
2379 */
2380 treeview =
2381 GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)));
2382
2383 renderer = gtk_cell_renderer_text_new();
2384 column = gtk_tree_view_column_new_with_attributes(_("Monitors"), renderer,
2385 "text", NAME_COLUMN, NULL);
2386 gtk_tree_view_append_column(treeview, column);
2387 gtk_container_add(GTK_CONTAINER(scrolled), GTK_WIDGET(treeview));
2388
2389 select = gtk_tree_view_get_selection(treeview);
2390 gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
2391 g_signal_connect(G_OBJECT(select), "changed",
2392 G_CALLBACK(cb_tree_selection_changed), NULL);
2393
2394 if (expand_builtins)
2395 {
2396 path = gtk_tree_path_new_from_string("1");
2397 gtk_tree_view_expand_row(treeview, path, TRUE);
2398 gtk_tree_path_free(path);
2399 }
2400 if (expand_plugins)
2401 {
2402 path = gtk_tree_path_new_from_string("2");
2403 gtk_tree_view_expand_row(treeview, path, TRUE);
2404 gtk_tree_path_free(path);
2405 }
2406
2407 hbox = gtk_hbutton_box_new();
2408 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
2409 gtk_box_set_spacing(GTK_BOX(hbox), 5);
2410 gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);
2411
2412 apply_button = gtk_button_new_from_stock(GTK_STOCK_APPLY);
2413 GTK_WIDGET_SET_FLAGS(apply_button, GTK_CAN_DEFAULT);
2414 g_signal_connect(G_OBJECT(apply_button), "clicked",
2415 G_CALLBACK(apply_config), NULL);
2416 gtk_box_pack_start(GTK_BOX(hbox), apply_button, TRUE, TRUE, 0);
2417
2418 close_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
2419 GTK_WIDGET_SET_FLAGS(close_button, GTK_CAN_DEFAULT);
2420 g_signal_connect(G_OBJECT(close_button), "clicked",
2421 G_CALLBACK(close_config), GINT_TO_POINTER(1));
2422 gtk_box_pack_start(GTK_BOX(hbox), close_button, TRUE, TRUE, 0);
2423
2424 button = gtk_button_new_from_stock(GTK_STOCK_OK);
2425 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
2426 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(OK_config), NULL);
2427 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
2428 gtk_widget_grab_default(button);
2429
2430 gtk_widget_show_all(config_window);
2431 }
2432
2433 void
gkrellm_open_config_window(GkrellmMonitor * mon)2434 gkrellm_open_config_window(GkrellmMonitor *mon)
2435 {
2436 GtkTreePath *path;
2437
2438 if (!mon || !mon->create_config || _GK.no_config)
2439 return;
2440 create_config_window();
2441 if (MONITOR_ID(mon) == MON_PLUGIN)
2442 path = gtk_tree_path_new_from_string("2");
2443 else
2444 path = gtk_tree_path_new_from_string("1");
2445
2446 gtk_tree_view_expand_row(treeview, path, TRUE);
2447 gtk_tree_path_free(path);
2448
2449 path = gtk_tree_row_reference_get_path(mon->privat->row_reference);
2450 gtk_tree_view_set_cursor(treeview, path, NULL, FALSE);
2451 }
2452
2453 static const char *ui_items_no_config = "\
2454 <ui>\
2455 <popup>\
2456 <separator/>\
2457 <menuitem name=\"Quit\" action=\"QuitAction\"/>\
2458 <separator/>\
2459 </popup>\
2460 </ui>\
2461 ";
2462
2463 static const char *ui_items = "\
2464 <ui>\
2465 <popup accelerators=\"true\">\
2466 <menuitem name=\"Configuration\" action=\"ConfigurationAction\"/>\
2467 <menu name=\"ThemeMenu\" action=\"ThemeMenuAction\">\
2468 <menuitem name=\"ThemeAltNext\" action=\"ThemeAltNextAction\"/>\
2469 <menuitem name=\"ThemeAltPrev\" action=\"ThemeAltPrevAction\"/>\
2470 </menu>\
2471 <separator/>\
2472 <menuitem name=\"Quit\" action=\"QuitAction\"/>\
2473 </popup>\
2474 </ui>\
2475 ";
2476
2477 /*
2478 static const char *ui_items_debug = "\
2479 <popup>\
2480 <menuitem name=\"ThemeNext\" action=\"ThemeNextAction\"/>\
2481 <menuitem name=\"ThemePrev\" action=\"ThemePrevAction\"/>\
2482 <menuitem name=\"MenuPopup\" action=\"MenuPopupAction\"/>\
2483 <menuitem name=\"ReloadTheme\" action=\"ReloadThemeAction\"/>\
2484 <menuitem name=\"ScaleThemeUp\" action=\"ScaleThemeUpAction\"/>\
2485 <menuitem name=\"ScaleThemeDn\" action=\"ScaleThemeDnAction\"/>\
2486 </popup>\
2487 ";
2488 */
2489
2490 static GtkActionEntry ui_entries[] =
2491 {
2492 { "QuitAction", NULL, N_("Quit"),
2493 NULL, NULL, G_CALLBACK(gtk_main_quit) },
2494 { "ConfigurationAction", NULL, N_("Configuration"),
2495 "F1", NULL, G_CALLBACK(create_config_window) },
2496 { "ThemeMenuAction", NULL, N_("Theme"),
2497 NULL, NULL, NULL },
2498 { "ThemeAltNextAction", NULL, N_("Next"),
2499 "<shift>Page_Up", NULL, G_CALLBACK(cb_load_theme) },
2500 { "ThemeAltPrevAction", NULL, N_("Prev"),
2501 "<shift>Page_Down", NULL, G_CALLBACK(cb_load_theme) },
2502 { "ThemeNextAction", NULL, N_("Theme next"),
2503 "<control>Page_Up", NULL, G_CALLBACK(cb_load_theme) },
2504 { "ThemePrevAction", NULL, N_("Theme prev"),
2505 "<control>Page_Down", NULL, G_CALLBACK(cb_load_theme) },
2506 { "MenuPopupAction", NULL, N_("Menu Popup"),
2507 "F2", NULL, G_CALLBACK(cb_load_theme) },
2508 { "ReloadThemeAction", NULL, N_("Reload Theme"),
2509 "F5", NULL, G_CALLBACK(cb_load_theme) },
2510 { "ScaleThemeUpAction", NULL, N_("Scale Theme Up"),
2511 "F6", NULL, G_CALLBACK(cb_load_theme) },
2512 { "ScaleThemeDnAction", NULL, N_("Scale Theme Dn"),
2513 "F7", NULL, G_CALLBACK(cb_load_theme) },
2514 };
2515 static guint n_ui_entries = G_N_ELEMENTS (ui_entries);
2516
2517 GtkUIManager *
gkrellm_create_ui_manager_popup(void)2518 gkrellm_create_ui_manager_popup(void)
2519 {
2520 GtkWidget *top_win;
2521 GtkUIManager *ui_manager;
2522 GtkActionGroup *action_group;
2523 GError *error;
2524
2525 top_win = gkrellm_get_top_window();
2526 action_group = gtk_action_group_new ("UiActions");
2527 gtk_action_group_add_actions (action_group, ui_entries, n_ui_entries, NULL);
2528 ui_manager = gtk_ui_manager_new ();
2529 gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
2530 error = NULL;
2531 if (_GK.no_config)
2532 gtk_ui_manager_add_ui_from_string (ui_manager, ui_items_no_config,
2533 strlen(ui_items_no_config), &error);
2534 else
2535 gtk_ui_manager_add_ui_from_string (ui_manager, ui_items,
2536 strlen(ui_items), &error);
2537 if (error)
2538 {
2539 g_message ("building menus failed: %s", error->message);
2540 g_error_free (error);
2541 return NULL;
2542 }
2543 gtk_window_add_accel_group(GTK_WINDOW(top_win),
2544 gtk_ui_manager_get_accel_group (ui_manager));
2545
2546 return ui_manager;
2547 }
2548
2549