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 #if defined(WIN32)
38
39 #define DEFAULT_CLOCK_FORMAT "%#I:%M <span foreground=\"$A\"><small>%S</small></span>"
40 #define ALT1_CLOCK_FORMAT "%#I:%M <span foreground=\"$A\"><small>%p</small></span>"
41 #define ALT2_CLOCK_FORMAT "%#H:%M <span foreground=\"$A\"><small>%S</small></span>"
42 #define DEFAULT_CAL_FORMAT "%a <span foreground=\"$A\"><big><big>%#d</big></big></span> %b"
43 #define ALT1_CAL_FORMAT "<big>%a %b <span foreground=\"$A\">%#d</span></big>"
44 #define ALT2_CAL_FORMAT "%a <span foreground=\"cyan2\"><span font_desc=\"16.5\"><i>%#d</i></span></span> %b"
45
46 #else
47
48 #define DEFAULT_CLOCK_FORMAT \
49 _("%l:%M <span foreground=\"$A\"><small>%S</small></span>")
50 #define ALT1_CLOCK_FORMAT "%l:%M <span foreground=\"$A\"><small>%p</small></span>"
51 #define ALT2_CLOCK_FORMAT "%k:%M <span foreground=\"$A\"><small>%S</small></span>"
52
53 #define DEFAULT_CAL_FORMAT \
54 _("%a <span foreground=\"$A\"><big><big>%e</big></big></span> %b")
55 #define ALT1_CAL_FORMAT "<big>%a %b <span foreground=\"$A\">%e</span></big>"
56 #define ALT2_CAL_FORMAT "%a <span foreground=\"cyan2\"><span font_desc=\"16.5\"><i>%e</i></span></span> %b"
57
58 #endif
59
60
61 static GkrellmMonitor
62 *mon_clock,
63 *mon_cal;
64
65 static GkrellmPanel
66 *pclock,
67 *pcal;
68
69 static GtkWidget
70 *cal_vbox,
71 *clock_vbox;
72
73 static GkrellmDecal
74 *d_cal,
75 *d_clock;
76
77
78 static GkrellmLauncher
79 clock_launch,
80 cal_launch;
81
82 static gboolean cal_enable,
83 clock_enable,
84 loop_chime_enable;
85
86
87 static gchar *cal_format,
88 *clock_format;
89
90 static gchar *cal_alt_color_string,
91 *clock_alt_color_string;
92
93 static gint clock_style_id,
94 cal_style_id;
95
96
97 static gchar *hour_chime_command,
98 *quarter_chime_command;
99 static gboolean chime_block;
100
101 typedef struct
102 {
103 gchar *command;
104 gint count;
105 }
106 ChimeData;
107
108
109 struct tm gkrellm_current_tm;
110
111
112
113 struct tm *
gkrellm_get_current_time(void)114 gkrellm_get_current_time(void)
115 {
116 return &gkrellm_current_tm;
117 }
118
119
120 static gpointer
chime_func(gpointer data)121 chime_func(gpointer data)
122 {
123 ChimeData *chime = (ChimeData *)data;
124 gint counter;
125
126 if (strlen(chime->command))
127 {
128 if (chime->count > 12)
129 chime->count -= 12;
130
131 for (counter = 0; counter < chime -> count; counter ++)
132 g_spawn_command_line_sync(chime->command,
133 NULL, NULL, NULL, NULL /* GError */);
134 }
135 g_free(chime->command);
136 g_free(chime);
137 return NULL;
138 }
139
140 static void
get_color_name(GdkColor * color,gchar ** color_string)141 get_color_name(GdkColor *color, gchar **color_string)
142 {
143 gchar *cstring;
144
145 cstring = g_strdup_printf("#%2.2x%2.2x%2.2x",
146 (color->red >> 8) & 0xff,
147 (color->green >> 8) & 0xff,
148 (color->blue >> 8) & 0xff );
149 gkrellm_dup_string(color_string, cstring);
150 g_free(cstring);
151 }
152
153 static void
format_alt_color(gchar * src_string,gchar * buf,gint size,gchar * alt_color)154 format_alt_color(gchar *src_string, gchar *buf, gint size, gchar *alt_color)
155 {
156 gint len;
157 gchar *s;
158
159 if (!buf || size < 1)
160 return;
161 --size;
162 *buf = '\0';
163 if (!src_string)
164 return;
165
166 for (s = src_string; *s != '\0' && size > 0; ++s)
167 {
168 len = 1;
169 if (*s == '$' && *(s + 1) != '\0')
170 {
171 switch(*(s + 1))
172 {
173 case 'A':
174 len = snprintf(buf, size, "%s", alt_color);
175 break;
176 default:
177 *buf = *s;
178 if (size > 1)
179 {
180 *(buf + 1) = *(s + 1);
181 ++len;
182 }
183 break;
184 }
185 ++s;
186 }
187 else
188 *buf = *s;
189 size -= len;
190 buf += len;
191 }
192 *buf = '\0';
193 }
194
195 static gchar *
strftime_format(gchar * format,gchar * alt_color)196 strftime_format(gchar *format, gchar *alt_color)
197 {
198 struct tm *t;
199 gchar *locale_format = NULL;
200 gchar buf1[512], buf2[512];
201
202 if (_GK.client_mode)
203 t = gkrellm_client_server_time();
204 else
205 t = &gkrellm_current_tm;
206
207 locale_format = g_locale_from_utf8(format, -1, NULL, NULL, NULL);
208 if (!locale_format)
209 locale_format = g_strdup(format);
210 strftime(buf1, sizeof(buf1), locale_format, t);
211 g_free (locale_format);
212 format_alt_color(buf1, buf2, sizeof(buf2), alt_color);
213
214 // g_debug("%s\n", buf2);
215
216 return g_locale_to_utf8 (buf2, -1, NULL, NULL, NULL);
217 }
218
219 static gint
expose_event(GtkWidget * widget,GdkEventExpose * ev)220 expose_event(GtkWidget *widget, GdkEventExpose *ev)
221 {
222 GdkPixmap *pixmap = NULL;
223
224 if (widget == pcal->drawing_area)
225 pixmap = pcal->pixmap;
226 else if (widget == pclock->drawing_area)
227 pixmap = pclock->pixmap;
228 if (pixmap)
229 gdk_draw_drawable(widget->window, gkrellm_draw_GC(1), pixmap,
230 ev->area.x, ev->area.y, ev->area.x, ev->area.y,
231 ev->area.width, ev->area.height);
232 return FALSE;
233 }
234
235 static gint
cb_panel_press(GtkWidget * widget,GdkEventButton * ev)236 cb_panel_press(GtkWidget *widget, GdkEventButton *ev)
237 {
238 if (ev->button == 3)
239 gkrellm_open_config_window(mon_clock);
240 return FALSE;
241 }
242
243 static void
cal_visibility(void)244 cal_visibility(void)
245 {
246 if (cal_enable)
247 {
248 gkrellm_panel_show(pcal);
249 gkrellm_spacers_show(mon_cal);
250 }
251 else
252 {
253 gkrellm_panel_hide(pcal);
254 gkrellm_spacers_hide(mon_cal);
255 }
256 }
257
258 static void
create_calendar_panel(GtkWidget * vbox,gint first_create)259 create_calendar_panel(GtkWidget *vbox, gint first_create)
260 {
261 GkrellmStyle *style;
262 GkrellmTextstyle *ts;
263 gchar *cal_string;
264
265 if (first_create)
266 pcal = gkrellm_panel_new0();
267 style = gkrellm_meter_style(cal_style_id);
268
269 ts = gkrellm_meter_alt_textstyle(cal_style_id);
270 get_color_name(&ts->color, &cal_alt_color_string);
271
272 cal_string = strftime_format(cal_format, cal_alt_color_string);
273 d_cal = gkrellm_create_decal_text_markup(pcal, cal_string,
274 gkrellm_meter_textstyle(cal_style_id), style, -1, -1, -1);
275 g_free(cal_string);
276
277 gkrellm_panel_configure(pcal, NULL, style);
278 gkrellm_panel_create(vbox, mon_cal, pcal);
279
280 if (first_create)
281 {
282 /* Help the motion out hack. If starting a move in host panel and mouse
283 | jerks into the pclock/pcal drawing areas, we stop moving unless:
284 */
285 extern void gkrellm_motion(GtkWidget *, GdkEventMotion *, gpointer);
286
287 g_signal_connect(G_OBJECT(pcal->drawing_area), "motion_notify_event",
288 G_CALLBACK(gkrellm_motion), NULL);
289
290 g_signal_connect(G_OBJECT (pcal->drawing_area), "expose_event",
291 G_CALLBACK(expose_event), NULL);
292 g_signal_connect(G_OBJECT(pcal->drawing_area), "button_press_event",
293 G_CALLBACK(cb_panel_press), NULL);
294 }
295 gkrellm_setup_launcher(pcal, &cal_launch, METER_PANEL_TYPE, 0);
296
297 cal_visibility();
298 }
299
300 static void
draw_cal(void)301 draw_cal(void)
302 {
303 gchar *utf8, *cal_string;
304 gint w, h;
305
306 if (!cal_enable)
307 return;
308
309 cal_string = strftime_format(cal_format, cal_alt_color_string);
310 if (!g_utf8_validate(cal_string, -1, NULL))
311 {
312 if ((utf8 = g_locale_to_utf8(cal_string, -1, NULL, NULL, NULL))
313 != NULL)
314 {
315 g_free(cal_string);
316 cal_string = utf8;
317 }
318 }
319
320 /* Get string extents in case a string change => need to resize the
321 | panel. A string change can also change the decal y_ink (possibly
322 | without changing decal size).
323 */
324 gkrellm_text_markup_extents(d_cal->text_style.font,
325 cal_string, strlen(cal_string), &w, &h, NULL, &d_cal->y_ink);
326
327 w += d_cal->text_style.effect;
328 if (h + d_cal->text_style.effect != d_cal->h)
329 {
330 gkrellm_panel_destroy(pcal);
331 create_calendar_panel(cal_vbox, TRUE);
332 }
333
334 gkrellm_draw_decal_markup(pcal, d_cal, cal_string);
335 gkrellm_decal_text_set_offset(d_cal, (d_cal->w - w) / 2, 0);
336
337 gkrellm_draw_panel_layers(pcal);
338 g_free(cal_string);
339 }
340
341 static void
create_calendar(GtkWidget * vbox,gint first_create)342 create_calendar(GtkWidget *vbox, gint first_create)
343 {
344 cal_vbox = vbox;
345 create_calendar_panel(vbox, first_create);
346 draw_cal();
347 }
348
349 static void
clock_visibility(void)350 clock_visibility(void)
351 {
352 if (clock_enable)
353 {
354 gkrellm_panel_show(pclock);
355 gkrellm_spacers_show(mon_clock);
356 }
357 else
358 {
359 gkrellm_panel_hide(pclock);
360 gkrellm_spacers_hide(mon_clock);
361 }
362 }
363
364 static void
create_clock_panel(GtkWidget * vbox,gint first_create)365 create_clock_panel(GtkWidget *vbox, gint first_create)
366 {
367 GkrellmStyle *style;
368 GkrellmTextstyle *ts;
369 gchar *clock_string;
370
371 if (first_create)
372 pclock = gkrellm_panel_new0();
373 style = gkrellm_meter_style(clock_style_id);
374
375 ts = gkrellm_meter_alt_textstyle(clock_style_id);
376 get_color_name(&ts->color, &clock_alt_color_string);
377
378 clock_string = strftime_format(clock_format, clock_alt_color_string);
379 d_clock = gkrellm_create_decal_text_markup(pclock, clock_string,
380 gkrellm_meter_textstyle(clock_style_id), style, -1, -1, -1);
381 g_free(clock_string);
382
383 gkrellm_panel_configure(pclock, NULL, style);
384 gkrellm_panel_create(vbox, mon_clock, pclock);
385
386 if (first_create)
387 {
388 g_signal_connect(G_OBJECT (pclock->drawing_area), "expose_event",
389 G_CALLBACK(expose_event), NULL);
390 g_signal_connect(G_OBJECT(pclock->drawing_area), "button_press_event",
391 G_CALLBACK(cb_panel_press), NULL);
392 }
393 gkrellm_setup_launcher(pclock, &clock_launch, METER_PANEL_TYPE, 0);
394
395 clock_visibility();
396 }
397
398 static void
draw_clock(gboolean check_size)399 draw_clock(gboolean check_size)
400 {
401 gchar *utf8, *clock_string;
402 gint w,h;
403
404 if (!clock_enable)
405 return;
406
407 clock_string = strftime_format(clock_format, clock_alt_color_string);
408 if (!g_utf8_validate(clock_string, -1, NULL))
409 {
410 if ((utf8 = g_locale_to_utf8(clock_string, -1, NULL, NULL, NULL))
411 != NULL)
412 {
413 g_free(clock_string);
414 clock_string = utf8;
415 }
416 }
417
418 if (check_size)
419 {
420 /* Get string extents in case a string change => need to resize the
421 | panel. A string change can also change the decal y_ink (possibly
422 | without changing decal size).
423 */
424 gkrellm_text_markup_extents(d_clock->text_style.font,
425 clock_string, strlen(clock_string),
426 &w, &h, NULL, &d_clock->y_ink);
427 w += d_clock->text_style.effect;
428 if (h + d_clock->text_style.effect != d_clock->h)
429 {
430 gkrellm_panel_destroy(pclock);
431 create_clock_panel(clock_vbox, TRUE);
432 }
433 gkrellm_decal_text_set_offset(d_clock, (d_clock->w - w) / 2, 0);
434 }
435 gkrellm_draw_decal_markup(pclock, d_clock, clock_string);
436 gkrellm_draw_panel_layers(pclock);
437 g_free(clock_string);
438 }
439
440
441 static void
create_clock(GtkWidget * vbox,gint first_create)442 create_clock(GtkWidget *vbox, gint first_create)
443 {
444 clock_vbox = vbox;
445 create_clock_panel(vbox, first_create);
446 draw_clock(TRUE);
447 }
448
449 static void
update_clock(void)450 update_clock(void)
451 {
452 GThread *gth;
453 struct tm *ptm;
454 static gint min_prev, hour_prev = -1, sec_prev = -1;
455 ChimeData *chime;
456 gboolean hour_tick;
457
458 if (_GK.client_mode)
459 {
460 ptm = gkrellm_client_server_time();
461 if (sec_prev == ptm->tm_sec)
462 return;
463 sec_prev = ptm->tm_sec;
464 }
465 else
466 {
467 if (!GK.second_tick)
468 return;
469 ptm = &gkrellm_current_tm;
470 }
471
472 hour_tick = (ptm->tm_hour != hour_prev);
473 if ( ptm->tm_min != min_prev
474 || hour_tick
475 )
476 {
477 draw_cal();
478 if (ptm->tm_hour != hour_prev && hour_prev != -1)
479 {
480 if (!chime_block && hour_chime_command && *hour_chime_command)
481 {
482 chime = g_new0(ChimeData, 1);
483 chime -> command = g_strdup(hour_chime_command);
484 chime -> count = loop_chime_enable ? ptm->tm_hour : 1;
485 gth = g_thread_new("chime", chime_func, chime);
486 g_thread_unref(gth);
487 }
488 }
489 else
490 {
491 if ( !chime_block && (ptm->tm_min % 15) == 0
492 && quarter_chime_command && *quarter_chime_command
493 )
494 {
495 chime = g_new0(ChimeData, 1);
496 chime -> command = g_strdup(quarter_chime_command);
497 chime -> count = 1;
498 gth = g_thread_new("chime", chime_func, chime);
499 g_thread_unref(gth);
500 }
501 }
502 }
503 draw_clock(hour_tick);
504 min_prev = ptm->tm_min;
505 hour_prev = ptm->tm_hour;
506 }
507
508
509 #define CLOCK_CONFIG_KEYWORD "clock_cal"
510
511 static void
save_clock_cal_config(FILE * f)512 save_clock_cal_config(FILE *f)
513 {
514 fprintf(f, "%s clock_launch %s\n", CLOCK_CONFIG_KEYWORD,
515 clock_launch.command);
516 fprintf(f, "%s clock_tooltip %s\n", CLOCK_CONFIG_KEYWORD,
517 clock_launch.tooltip_comment);
518 fprintf(f, "%s cal_launch %s\n", CLOCK_CONFIG_KEYWORD,
519 cal_launch.command);
520 fprintf(f, "%s cal_tooltip %s\n", CLOCK_CONFIG_KEYWORD,
521 cal_launch.tooltip_comment);
522 fprintf(f, "%s hour_chime_command %s\n", CLOCK_CONFIG_KEYWORD,
523 hour_chime_command);
524 fprintf(f, "%s quarter_chime_command %s\n", CLOCK_CONFIG_KEYWORD,
525 quarter_chime_command);
526 fprintf(f, "%s loop_chime_enable %d\n", CLOCK_CONFIG_KEYWORD,
527 loop_chime_enable);
528 fprintf(f, "%s clock_options %d\n", CLOCK_CONFIG_KEYWORD,
529 clock_enable);
530 fprintf(f, "%s cal_options %d\n", CLOCK_CONFIG_KEYWORD,
531 cal_enable);
532 fprintf(f, "%s cal_format %s\n", CLOCK_CONFIG_KEYWORD,
533 cal_format);
534 fprintf(f, "%s clock_format %s\n", CLOCK_CONFIG_KEYWORD,
535 clock_format);
536 }
537
538 static void
load_clock_cal_config(gchar * arg)539 load_clock_cal_config(gchar *arg)
540 {
541 gchar config[32], item[CFG_BUFSIZE];
542 gint n;
543
544 n = sscanf(arg, "%31s %[^\n]", config, item);
545 if (n == 2)
546 {
547 if (!strcmp(config, "clock_launch"))
548 clock_launch.command = g_strdup(item);
549 else if (!strcmp(config, "clock_tooltip"))
550 clock_launch.tooltip_comment = g_strdup(item);
551 else if (!strcmp(config, "cal_launch"))
552 cal_launch.command = g_strdup(item);
553 else if (!strcmp(config, "cal_tooltip"))
554 cal_launch.tooltip_comment = g_strdup(item);
555 else if (!strcmp(config, "hour_chime_command"))
556 gkrellm_dup_string(&hour_chime_command, item);
557 else if (!strcmp(config, "quarter_chime_command"))
558 gkrellm_dup_string(&quarter_chime_command, item);
559 else if (!strcmp(config, "loop_chime_enable"))
560 sscanf(item, "%d", &loop_chime_enable);
561 else if (!strcmp(config, "clock_options"))
562 sscanf(item, "%d", &clock_enable);
563 else if (!strcmp(config, "cal_options"))
564 sscanf(item, "%d", &cal_enable);
565 else if (!strcmp(config, "cal_format"))
566 gkrellm_dup_string(&cal_format, item);
567 else if (!strcmp(config, "clock_format"))
568 gkrellm_dup_string(&clock_format, item);
569 }
570 }
571
572 /* --------------------------------------------------------------------- */
573 static GtkWidget *cal_launch_entry,
574 *cal_tooltip_entry,
575 *clock_launch_entry,
576 *clock_tooltip_entry,
577 *hour_chime_entry,
578 *quarter_chime_entry,
579 *clock_enable_button,
580 *cal_enable_button,
581 *loop_chime_button;
582
583 static GtkWidget *cal_format_combo_box,
584 *clock_format_combo_box;
585
586
587 static void
cb_clock_cal(GtkWidget * widget,gpointer data)588 cb_clock_cal(GtkWidget *widget, gpointer data)
589 {
590 loop_chime_enable = GTK_TOGGLE_BUTTON(loop_chime_button)->active;
591
592 clock_enable = GTK_TOGGLE_BUTTON(clock_enable_button)->active;
593 clock_visibility();
594
595 cal_enable = GTK_TOGGLE_BUTTON(cal_enable_button)->active;
596 cal_visibility();
597
598 draw_cal();
599 draw_clock(TRUE);
600 }
601
602 static void
cb_launch_entry(GtkWidget * widget,gpointer data)603 cb_launch_entry(GtkWidget *widget, gpointer data)
604 {
605 gint which = GPOINTER_TO_INT(data);
606
607 if (which)
608 gkrellm_apply_launcher(&cal_launch_entry, &cal_tooltip_entry,
609 pcal, &cal_launch, gkrellm_launch_button_cb);
610 else
611 gkrellm_apply_launcher(&clock_launch_entry, &clock_tooltip_entry,
612 pclock, &clock_launch, gkrellm_launch_button_cb);
613 }
614
615 static void
cb_chime_entry(GtkWidget * widget,gpointer data)616 cb_chime_entry(GtkWidget *widget, gpointer data)
617 {
618 gint which = (GPOINTER_TO_INT(data)) & 0x1;
619 gint activate = (GPOINTER_TO_INT(data)) & 0x10;
620
621 /* If editing the chime commands, block them until config is destroyed
622 | or we get a "activate".
623 */
624 chime_block = activate ? FALSE : TRUE;
625 if (which)
626 gkrellm_dup_string(&hour_chime_command,
627 gkrellm_gtk_entry_get_text(&hour_chime_entry));
628 else
629 gkrellm_dup_string(&quarter_chime_command,
630 gkrellm_gtk_entry_get_text(&quarter_chime_entry));
631 }
632
633 static void
cal_format_cb(GtkWidget * widget,gpointer data)634 cal_format_cb(GtkWidget *widget, gpointer data)
635 {
636 gchar *s, *check;
637 GtkWidget *entry;
638
639 entry = gtk_bin_get_child(GTK_BIN(cal_format_combo_box));
640 s = gkrellm_gtk_entry_get_text(&entry);
641
642 check = strftime_format(s, cal_alt_color_string);
643
644 /* In case Pango markup tags, don't accept line unless valid markup.
645 | Ie, markup like <span ...> xxx </span> or <b> xxx </b>
646 */
647 if ( strchr(check, '<') != NULL
648 && !pango_parse_markup(check, -1, 0, NULL, NULL, NULL, NULL)
649 )
650 {
651 g_free(check);
652 return;
653 }
654
655 g_free(check);
656 if (gkrellm_dup_string(&cal_format, s))
657 draw_cal();
658 }
659
660 static void
clock_format_cb(GtkWidget * widget,gpointer data)661 clock_format_cb(GtkWidget *widget, gpointer data)
662 {
663 gchar *s, *check;
664 GtkWidget *entry;
665
666 entry = gtk_bin_get_child(GTK_BIN(clock_format_combo_box));
667 s = gkrellm_gtk_entry_get_text(&entry);
668
669 check = strftime_format(s, clock_alt_color_string);
670
671 if ( strchr(check, '<') != NULL
672 && !pango_parse_markup(check, -1, 0, NULL, NULL, NULL, NULL)
673 )
674 {
675 g_free(check);
676 return;
677 }
678
679 g_free(check);
680 if (gkrellm_dup_string(&clock_format, s))
681 draw_clock(TRUE);
682 }
683
684 static void
config_destroyed(void)685 config_destroyed(void)
686 {
687 chime_block = FALSE;
688 }
689
690
691 static gchar *clock_info_text[] =
692 {
693 N_("<h>Clock/Calendar Format Strings\n"),
694 N_("The display format strings should contain strftime conversion\n"
695 "characters and Pango text attribute markup strings.\n"),
696 "\n",
697 N_("For the clock, the provided default strings will display a 12 hour\n"
698 "clock with seconds, a 12 hour clock with AM/PM indicator, or a 24 hour\n"
699 "clock with seconds.\n"),
700 "\n",
701 N_("The special $A substitution variable expands to the current theme\n"
702 "alternate color and is for use with the Pango \"foreground\" attribute.\n")
703 };
704
705
706 static void
create_clock_tab(GtkWidget * tab_vbox)707 create_clock_tab(GtkWidget *tab_vbox)
708 {
709 GtkWidget *tabs;
710 GtkWidget *table, *vbox, *vbox1, *hbox, *label, *text;
711 gint i;
712
713 tabs = gtk_notebook_new();
714 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
715 gtk_box_pack_start(GTK_BOX(tab_vbox), tabs, TRUE, TRUE, 0);
716 g_signal_connect(G_OBJECT(tabs),"destroy",
717 G_CALLBACK(config_destroyed), NULL);
718
719 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Options"));
720
721 vbox1 = gkrellm_gtk_category_vbox(vbox, _("Calendar"), 4, 0, TRUE);
722 gkrellm_gtk_check_button_connected(vbox1, &cal_enable_button,
723 cal_enable, FALSE, FALSE, 2,
724 cb_clock_cal, NULL,
725 _("Enable"));
726 hbox = gtk_hbox_new(FALSE, 0);
727 gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 6);
728 label = gtk_label_new(_("Display format string:"));
729 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
730 cal_format_combo_box = gtk_combo_box_entry_new_text();
731 gtk_box_pack_start(GTK_BOX(vbox1), cal_format_combo_box, FALSE, FALSE, 0);
732 gtk_combo_box_append_text(GTK_COMBO_BOX(cal_format_combo_box), cal_format);
733 gtk_combo_box_append_text(GTK_COMBO_BOX(cal_format_combo_box), DEFAULT_CAL_FORMAT);
734 gtk_combo_box_append_text(GTK_COMBO_BOX(cal_format_combo_box), ALT1_CAL_FORMAT);
735 gtk_combo_box_append_text(GTK_COMBO_BOX(cal_format_combo_box), ALT2_CAL_FORMAT);
736 gtk_combo_box_set_active(GTK_COMBO_BOX(cal_format_combo_box), 0);
737 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(cal_format_combo_box)), "changed",
738 G_CALLBACK(cal_format_cb), NULL);
739
740 vbox1 = gkrellm_gtk_category_vbox(vbox, _("Clock"), 4, 0, TRUE);
741 gkrellm_gtk_check_button_connected(vbox1, &clock_enable_button,
742 clock_enable, FALSE, FALSE, 6,
743 cb_clock_cal, NULL,
744 _("Enable"));
745 hbox = gtk_hbox_new(FALSE, 0);
746 gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 6);
747 label = gtk_label_new(_("Display format string:"));
748 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
749 clock_format_combo_box = gtk_combo_box_entry_new_text();
750 gtk_box_pack_start(GTK_BOX(vbox1), clock_format_combo_box, FALSE, FALSE, 0);
751 gtk_combo_box_append_text(GTK_COMBO_BOX(clock_format_combo_box), clock_format);
752 gtk_combo_box_append_text(GTK_COMBO_BOX(clock_format_combo_box), DEFAULT_CLOCK_FORMAT);
753 gtk_combo_box_append_text(GTK_COMBO_BOX(clock_format_combo_box), ALT1_CLOCK_FORMAT);
754 gtk_combo_box_append_text(GTK_COMBO_BOX(clock_format_combo_box), ALT2_CLOCK_FORMAT);
755 gtk_combo_box_set_active(GTK_COMBO_BOX(clock_format_combo_box), 0);
756 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(clock_format_combo_box)), "changed",
757 G_CALLBACK(clock_format_cb), NULL);
758
759 /* -- Setup tab */
760 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Setup"));
761
762 vbox1 = gkrellm_gtk_category_vbox(vbox, _("Clock Chime Commands"),
763 4, 0, TRUE);
764 table = gkrellm_gtk_launcher_table_new(vbox1, 2);
765
766 gkrellm_gtk_config_launcher(table, 0, &hour_chime_entry, NULL,
767 _("Hour"), NULL);
768 gtk_entry_set_text(GTK_ENTRY(hour_chime_entry), hour_chime_command);
769 g_signal_connect(G_OBJECT(hour_chime_entry), "changed",
770 G_CALLBACK(cb_chime_entry), GINT_TO_POINTER(1));
771 g_signal_connect(G_OBJECT(hour_chime_entry), "activate",
772 G_CALLBACK(cb_chime_entry), GINT_TO_POINTER(0x11));
773
774 gkrellm_gtk_config_launcher(table, 1, &quarter_chime_entry, NULL,
775 _("Quarter hour"), NULL);
776 gtk_entry_set_text(GTK_ENTRY(quarter_chime_entry), quarter_chime_command);
777 g_signal_connect(G_OBJECT(quarter_chime_entry), "changed",
778 G_CALLBACK(cb_chime_entry), GINT_TO_POINTER(0));
779 g_signal_connect(G_OBJECT(quarter_chime_entry), "activate",
780 G_CALLBACK(cb_chime_entry), GINT_TO_POINTER(0x10));
781
782 gkrellm_gtk_check_button_connected(vbox1, &loop_chime_button,
783 loop_chime_enable, FALSE, FALSE, 6,
784 cb_clock_cal, NULL,
785 _("Loop hour chime command"));
786
787 vbox = gkrellm_gtk_category_vbox(vbox, _("Launch Commands"),
788 4, 0, TRUE);
789 table = gkrellm_gtk_launcher_table_new(vbox, 2);
790
791 gkrellm_gtk_config_launcher(table, 0, &cal_launch_entry,
792 &cal_tooltip_entry, _("Calendar"), &cal_launch);
793
794 /* --Info tab */
795 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Info"));
796 text = gkrellm_gtk_scrolled_text_view(vbox, NULL,
797 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
798 for (i = 0; i < sizeof(clock_info_text)/sizeof(gchar *); ++i)
799 gkrellm_gtk_text_view_append(text, _(clock_info_text[i]));
800 g_signal_connect(G_OBJECT(cal_launch_entry), "changed",
801 G_CALLBACK(cb_launch_entry), GINT_TO_POINTER(1));
802 g_signal_connect(G_OBJECT(cal_tooltip_entry), "changed",
803 G_CALLBACK(cb_launch_entry), GINT_TO_POINTER(1));
804
805 gkrellm_gtk_config_launcher(table, 1, &clock_launch_entry,
806 &clock_tooltip_entry, _("Clock"), &clock_launch);
807 g_signal_connect(G_OBJECT(clock_launch_entry), "changed",
808 G_CALLBACK(cb_launch_entry), GINT_TO_POINTER(0));
809 g_signal_connect(G_OBJECT(clock_tooltip_entry), "changed",
810 G_CALLBACK(cb_launch_entry), GINT_TO_POINTER(0));
811 }
812
813
814 static GkrellmMonitor monitor_clock =
815 {
816 N_("Clock"), /* Name, for config tab. */
817 MON_CLOCK, /* Id, 0 if a plugin */
818 create_clock, /* The create function */
819 update_clock, /* The update function */
820 create_clock_tab, /* The config tab create function */
821 NULL, /* Instant apply */
822
823 save_clock_cal_config, /* Save user conifg */
824 load_clock_cal_config, /* Load user config */
825 CLOCK_CONFIG_KEYWORD, /* config keyword */
826
827 NULL, /* Undef 2 */
828 NULL, /* Undef 1 */
829 NULL, /* Undef 0 */
830
831 0, /* insert_before_id - place plugin before this mon */
832
833 NULL, /* Handle if a plugin, filled in by GKrellM */
834 NULL /* path if a plugin, filled in by GKrellM */
835 };
836
837 GkrellmMonitor *
gkrellm_init_clock_monitor(void)838 gkrellm_init_clock_monitor(void)
839 {
840 clock_enable = TRUE;
841 monitor_clock.name = _(monitor_clock.name);
842 loop_chime_enable = FALSE;
843 hour_chime_command = g_strdup("");
844 quarter_chime_command = g_strdup("");
845
846 gkrellm_dup_string(&clock_format, DEFAULT_CLOCK_FORMAT);
847
848 clock_style_id = gkrellm_add_meter_style(&monitor_clock, CLOCK_STYLE_NAME);
849 mon_clock = &monitor_clock;
850 return &monitor_clock;
851 }
852
853 static GkrellmMonitor monitor_cal =
854 {
855 N_("Calendar"), /* Name, for config tab. */
856 MON_CAL, /* Id, 0 if a plugin */
857 create_calendar, /* The create function */
858 NULL, /* The update function */
859 NULL, /* The config tab create function */
860 NULL, /* Apply the config function */
861
862 NULL, /* Save user conifg */
863 NULL, /* Load user config */
864 NULL, /* config keyword */
865
866 NULL, /* Undef 2 */
867 NULL, /* Undef 1 */
868 NULL, /* Undef 0 */
869
870 0, /* insert_before_id - place plugin before this mon */
871
872 NULL, /* Handle if a plugin, filled in by GKrellM */
873 NULL /* path if a plugin, filled in by GKrellM */
874 };
875
876 GkrellmMonitor *
gkrellm_init_cal_monitor(void)877 gkrellm_init_cal_monitor(void)
878 {
879 cal_enable = TRUE;
880 monitor_cal.name = _(monitor_cal.name);
881
882 gkrellm_dup_string(&cal_format, DEFAULT_CAL_FORMAT);
883
884 cal_style_id = gkrellm_add_meter_style(&monitor_cal, CAL_STYLE_NAME);
885 mon_cal = &monitor_cal;
886 return &monitor_cal;
887 }
888
889