1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
3
* clock.c: the GNOME clock applet
5
* Copyright (C) 1997-2003 Free Software Foundation, Inc.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License as
9
* published by the Free Software Foundation; either version 2 of the
10
* License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28
* Gediminas Paulauskas
33
* Evolution calendar integration TODO:
34
* + Fix treeview scrolling and sizing
35
* + Tooltips for tasks/appointments
36
* + Do everything backwards if the clock is on the bottom
37
* + Double clicking appointments/tasks should open them in evo
38
* + Consider using different colours for different sources
39
* + Consider doing a GtkMenu tearoff type thing
52
#include <panel-applet.h>
53
#include <panel-applet-gconf.h>
56
#include <gdk/gdkkeysyms.h>
57
#include <gconf/gconf-client.h>
58
#include <libgnomeui/gnome-help.h>
59
#include <libgnomeui/gnome-url.h>
62
#include "calendar-client.h"
64
#include "gtkchinesecalendar.h"
66
#define CLOCK_ICON "lunar-applet"
67
#define INTERNETSECOND (864)
68
#define INTERNETBEAT (86400)
70
#define N_GCONF_PREFS 7
72
#define NEVER_SENSITIVE "never_sensitive"
74
static const char* KEY_FORMAT = "format";
75
static const char* KEY_SHOW_SECONDS = "show_seconds";
76
static const char* KEY_SHOW_DATE = "show_date";
77
static const char* KEY_SHOW_LUNARDATE = "show_lunardate";
78
static const char* KEY_GMT_TIME = "gmt_time";
79
static const char* KEY_CONFIG_TOOL = "config_tool";
80
static const char* KEY_CUSTOM_FORMAT = "custom_format";
81
static const char* KEY_SHOW_WEEK = "show_week_numbers";
83
static const char *clock_config_tools [] = {
86
"/sbin/yast2 timezone",
90
/* Needs to match the indices in the combo */
92
CLOCK_FORMAT_INVALID = 0,
96
CLOCK_FORMAT_INTERNET,
100
static GConfEnumStringPair format_type_enum_map [] = {
101
{ CLOCK_FORMAT_12, "12-hour" },
102
{ CLOCK_FORMAT_24, "24-hour" },
103
{ CLOCK_FORMAT_UNIX, "unix" },
104
{ CLOCK_FORMAT_INTERNET, "internet" },
105
{ CLOCK_FORMAT_CUSTOM, "custom" },
109
typedef struct _ClockData ClockData;
118
GtkWidget *calendar_popup;
122
GtkWidget *task_list;
123
GtkWidget *appointment_list;
125
GtkListStore *appointments_model;
126
GtkListStore *tasks_model;
127
GtkTreeModelFilter *tasks_filter;
129
CalendarClient *client;
130
#endif /* HAVE_LIBECAL */
135
gboolean showseconds;
137
gboolean showlunardate;
147
PanelAppletOrient orient;
149
GtkAllocation old_allocation;
154
GtkWidget *showseconds_check;
155
GtkWidget *showdate_check;
156
GtkWidget *showlunardate_check;
157
GtkWidget *gmt_time_check;
158
GtkWidget *custom_hbox;
159
GtkWidget *custom_label;
160
GtkWidget *custom_entry;
161
gboolean custom_format_shown;
163
gboolean can_handle_format_12;
165
guint listeners [N_GCONF_PREFS];
168
static void update_clock (ClockData * cd);
169
static float get_itime (time_t current_time);
171
static void set_atk_name_description (GtkWidget *widget,
174
static void display_properties_dialog (BonoboUIComponent *uic,
176
const gchar *verbname);
177
static void display_help_dialog (BonoboUIComponent *uic,
179
const gchar *verbname);
180
static void display_about_dialog (BonoboUIComponent *uic,
182
const gchar *verbname);
183
static void position_calendar_popup (ClockData *cd,
186
static void update_orient (ClockData *cd);
189
unfix_size (ClockData *cd)
191
cd->fixed_width = -1;
192
cd->fixed_height = -1;
193
gtk_widget_queue_resize (cd->toggle);
197
calculate_minimum_width (GtkWidget *widget,
200
PangoContext *context;
206
context = gtk_widget_get_pango_context (widget);
208
layout = pango_layout_new (context);
209
pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
210
pango_layout_set_text (layout, text, -1);
211
pango_layout_get_pixel_size (layout, &width, &height);
212
g_object_unref (G_OBJECT (layout));
215
gtk_widget_style_get (widget,
216
"focus-line-width", &focus_width,
217
"focus-padding", &focus_pad,
220
width += 2 * (focus_width + focus_pad + widget->style->xthickness);
226
set_tooltip (GtkWidget *applet,
230
GtkTooltips *tooltips;
232
tooltips = g_object_get_data (G_OBJECT (applet), "tooltips");
234
tooltips = gtk_tooltips_new ();
235
g_object_ref (tooltips);
236
gtk_object_sink (GTK_OBJECT (tooltips));
237
g_object_set_data_full (
238
G_OBJECT (applet), "tooltips", tooltips,
239
(GDestroyNotify) g_object_unref);
242
gtk_tooltips_set_tip (tooltips, widget, tip, NULL);
246
clock_timeout_callback (gpointer data)
248
ClockData *cd = data;
253
if (!cd->showseconds &&
254
cd->format != CLOCK_FORMAT_UNIX &&
255
cd->format != CLOCK_FORMAT_CUSTOM) {
256
if (cd->format == CLOCK_FORMAT_INTERNET &&
257
(long)get_itime (new_time) !=
258
(long)get_itime (cd->current_time)) {
260
} else if ((cd->format == CLOCK_FORMAT_12 ||
261
cd->format == CLOCK_FORMAT_24) &&
262
new_time / 60 != cd->current_time / 60) {
273
get_itime (time_t current_time)
279
/* BMT (Biel Mean Time) is GMT+1 */
280
bmt = current_time + 3600;
282
itime = (tm->tm_hour*3600.0 + tm->tm_min*60.0 + tm->tm_sec)/86.4;
287
/* adapted from panel-toplevel.c */
289
calculate_minimum_height (GtkWidget *widget,
290
PanelAppletOrient orientation)
292
PangoContext *context;
293
PangoFontMetrics *metrics;
300
context = gtk_widget_get_pango_context (widget);
301
metrics = pango_context_get_metrics (context,
302
widget->style->font_desc,
303
pango_context_get_language (context));
305
ascent = pango_font_metrics_get_ascent (metrics);
306
descent = pango_font_metrics_get_descent (metrics);
308
pango_font_metrics_unref (metrics);
310
gtk_widget_style_get (widget,
311
"focus-line-width", &focus_width,
312
"focus-padding", &focus_pad,
315
if (orientation == PANEL_APPLET_ORIENT_UP
316
|| orientation == PANEL_APPLET_ORIENT_DOWN) {
317
thickness = widget->style->ythickness;
319
thickness = widget->style->xthickness;
322
return PANGO_PIXELS (ascent + descent) + 2 * (focus_width + focus_pad + thickness);
326
use_two_line_format (ClockData *cd)
328
if (cd->size >= 2 * calculate_minimum_height (cd->toggle, cd->orient))
335
update_timeformat (ClockData *cd)
337
/* Show date in another line if panel is vertical, or
338
* horizontal but large enough to hold two lines of text
340
const char *time_format;
341
const char *date_format;
344
if (cd->format == CLOCK_FORMAT_12)
345
time_format = cd->showseconds ? _("%l:%M:%S %p") : _("%l:%M %p");
347
time_format = cd->showseconds ? _("%H:%M:%S") : _("%H:%M");
350
clock_format = g_strdup (time_format);
353
/* translators: replace %e with %d if, when the day of the
354
* month as a decimal number is a single digit, it
355
* should begin with a 0 in your locale (e.g. "May
356
* 01" instead of "May 1").
358
date_format = _("%a %b %e");
360
if (use_two_line_format (cd))
361
/* translators: reverse the order of these arguments
362
* if the time should come before the
363
* date on a clock in your locale.
365
clock_format = g_strdup_printf (_("%1$s\n%2$s"),
366
date_format, time_format);
368
/* translators: reverse the order of these arguments
369
* if the time should come before the
370
* date on a clock in your locale.
372
clock_format = g_strdup_printf (_("%1$s, %2$s"),
373
date_format, time_format);
376
g_free (cd->timeformat);
377
cd->timeformat = g_locale_from_utf8 (clock_format, -1, NULL, NULL, NULL);
378
/* let's be paranoid */
380
cd->timeformat = g_strdup ("???");
382
g_free (clock_format);
385
/* sets accessible name and description for the widget */
387
set_atk_name_description (GtkWidget *widget,
392
obj = gtk_widget_get_accessible (widget);
394
/* return if gail is not loaded */
395
if (!GTK_IS_ACCESSIBLE (obj))
399
atk_object_set_description (obj, desc);
401
atk_object_set_name (obj, name);
405
update_clock (ClockData * cd)
408
char date[256], hour[256];
411
time (&cd->current_time);
414
tm = gmtime (&cd->current_time);
416
tm = localtime (&cd->current_time);
418
if (cd->format == CLOCK_FORMAT_UNIX) {
419
if (use_two_line_format (cd)) {
420
g_snprintf (hour, sizeof(hour), "%lu\n%05lu",
421
(unsigned long)(cd->current_time / 100000L),
422
(unsigned long)(cd->current_time % 100000L));
424
g_snprintf (hour, sizeof(hour), "%lu", (unsigned long)cd->current_time);
426
} else if (cd->format == CLOCK_FORMAT_INTERNET) {
427
float itime = get_itime (cd->current_time);
429
g_snprintf (hour, sizeof (hour), "@%3.2f", itime);
431
g_snprintf (hour, sizeof (hour), "@%3.0f", itime);
432
} else if (cd->format == CLOCK_FORMAT_CUSTOM) {
433
char *timeformat = g_locale_from_utf8 (cd->custom_format, -1,
436
strcpy (hour, "???");
437
else if (strftime (hour, sizeof (hour), timeformat, tm) <= 0)
438
strcpy (hour, "???");
441
if (strftime (hour, sizeof (hour), cd->timeformat, tm) <= 0)
442
strcpy (hour, "???");
445
utf8 = g_locale_to_utf8 (hour, -1, NULL, NULL, NULL);
446
gtk_label_set_text (GTK_LABEL (cd->clockw), utf8);
450
gtk_widget_queue_resize (cd->toggle);
453
/* Show date in tooltip */
454
loc = g_locale_from_utf8 (_("%A %B %d"), -1, NULL, NULL, NULL);
456
strcpy (date, "???");
457
else if (strftime (date, sizeof (date), loc, tm) <= 0)
458
strcpy (date, "???");
461
utf8 = g_locale_to_utf8 (date, -1, NULL, NULL, NULL);
462
set_tooltip (cd->applet, cd->toggle, utf8);
466
set_tooltip (cd->applet, cd->toggle, _("Click to view your appointments and tasks"));
468
set_tooltip (cd->applet, cd->toggle, _("Click to view month calendar"));
474
refresh_clock (ClockData *cd)
481
refresh_clock_timeout(ClockData *cd)
487
update_timeformat (cd);
490
g_source_remove (cd->timeout);
494
if (cd->format == CLOCK_FORMAT_INTERNET)
495
timeouttime = INTERNETSECOND;
499
cd->timeout = g_timeout_add (timeouttime,
500
clock_timeout_callback,
505
destroy_clock(GtkWidget * widget, ClockData *cd)
510
client = gconf_client_get_default ();
512
for (i = 0; i < N_GCONF_PREFS; i++)
513
gconf_client_notify_remove (
514
client, cd->listeners [i]);
516
g_object_unref (G_OBJECT (client));
519
g_source_remove (cd->timeout);
524
g_object_unref (cd->client);
527
if (cd->appointments_model)
528
g_object_unref (cd->appointments_model);
529
cd->appointments_model = NULL;
532
g_object_unref (cd->tasks_model);
533
cd->tasks_model = NULL;
535
if (cd->tasks_filter)
536
g_object_unref (cd->tasks_filter);
537
cd->tasks_filter = NULL;
538
#endif /* HAVE_LIBECAL */
541
gtk_widget_destroy (cd->about);
545
gtk_widget_destroy (cd->props);
548
if (cd->calendar_popup)
549
gtk_widget_destroy (cd->calendar_popup);
550
cd->calendar_popup = NULL;
552
g_free (cd->timeformat);
553
g_free (cd->config_tool);
554
g_free (cd->custom_format);
559
close_on_escape (GtkWidget *widget,
563
if (event->keyval == GDK_Escape) {
564
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->toggle), FALSE);
572
delete_event (GtkWidget *widget,
576
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->toggle), FALSE);
580
static inline ClockFormat
581
clock_locale_format (void)
585
am = nl_langinfo (AM_STR);
586
return (am[0] == '\0') ? CLOCK_FORMAT_24 : CLOCK_FORMAT_12;
592
update_frame_visibility (GtkWidget *frame,
596
gboolean model_empty;
601
model_empty = !gtk_tree_model_get_iter_first (model, &iter);
604
gtk_widget_hide (frame);
606
gtk_widget_show (frame);
610
APPOINTMENT_COLUMN_UID,
611
APPOINTMENT_COLUMN_SUMMARY,
612
APPOINTMENT_COLUMN_DESCRIPTION,
613
APPOINTMENT_COLUMN_START_TIME,
614
APPOINTMENT_COLUMN_START_TEXT,
615
APPOINTMENT_COLUMN_END_TIME,
616
APPOINTMENT_COLUMN_ALL_DAY,
617
APPOINTMENT_COLUMN_COLOR,
618
N_APPOINTMENT_COLUMNS
624
TASK_COLUMN_DESCRIPTION,
625
TASK_COLUMN_START_TIME,
626
TASK_COLUMN_DUE_TIME,
627
TASK_COLUMN_PERCENT_COMPLETE,
628
TASK_COLUMN_PERCENT_COMPLETE_TEXT,
629
TASK_COLUMN_COMPLETED,
630
TASK_COLUMN_COMPLETED_TIME,
631
TASK_COLUMN_OVERDUE_ATTR,
634
TASK_COLUMN_PRIORITY,
639
format_time (ClockFormat format,
648
char result [256] = { 0, };
660
if (year == (tm->tm_year + 1900) &&
661
month == tm->tm_mon &&
662
day == tm->tm_mday) {
663
if (format != CLOCK_FORMAT_12 && format != CLOCK_FORMAT_24)
664
format = clock_locale_format ();
666
if (format == CLOCK_FORMAT_12)
667
time_format = g_locale_from_utf8 (_("%l:%M %p"), -1, NULL, NULL, NULL);
669
time_format = g_locale_from_utf8 (_("%H:%M"), -1, NULL, NULL, NULL);
672
/* Translators: If the event did not start on the current day
673
we will display the start date in the most abbreviated way possible. */
674
time_format = g_locale_from_utf8 (_("%b %d"), -1, NULL, NULL, NULL);
677
strftime (result, sizeof (result), time_format, tm);
678
g_free (time_format);
680
return g_locale_to_utf8 (result, -1, NULL, NULL, NULL);
684
handle_tasks_changed (ClockData *cd)
688
gtk_list_store_clear (cd->tasks_model);
690
events = calendar_client_get_events (cd->client, CALENDAR_EVENT_TASK);
691
for (l = events; l; l = l->next) {
692
CalendarTask *task = l->data;
694
char *percent_complete_text;
696
g_assert (CALENDAR_EVENT (task)->type == CALENDAR_EVENT_TASK);
698
/* FIXME: should this format be locale specific ? */
699
percent_complete_text = g_strdup_printf ("%d%%", task->percent_complete);
701
gtk_list_store_append (cd->tasks_model, &iter);
702
gtk_list_store_set (cd->tasks_model, &iter,
703
TASK_COLUMN_UID, task->uid,
704
TASK_COLUMN_SUMMARY, task->summary,
705
TASK_COLUMN_DESCRIPTION, task->description,
706
TASK_COLUMN_START_TIME, task->start_time,
707
TASK_COLUMN_DUE_TIME, task->due_time,
708
TASK_COLUMN_PERCENT_COMPLETE, task->percent_complete,
709
TASK_COLUMN_PERCENT_COMPLETE_TEXT, percent_complete_text,
710
TASK_COLUMN_COMPLETED, task->percent_complete == 100,
711
TASK_COLUMN_COMPLETED_TIME, task->completed_time,
712
TASK_COLUMN_COLOR, task->color_string,
713
TASK_COLUMN_URL, task->url,
714
TASK_COLUMN_PRIORITY, task->priority,
717
g_free (percent_complete_text);
718
calendar_event_free (CALENDAR_EVENT (task));
720
g_slist_free (events);
722
update_frame_visibility (cd->task_list, GTK_TREE_MODEL (cd->tasks_filter));
726
handle_task_completed_toggled (ClockData *cd,
727
const char *path_str,
728
GtkCellRendererToggle *cell)
730
GtkTreePath *child_path, *path;
733
gboolean task_completed;
734
guint percent_complete;
736
path = gtk_tree_path_new_from_string (path_str);
737
child_path = gtk_tree_model_filter_convert_path_to_child_path (cd->tasks_filter, path);
738
gtk_tree_model_get_iter (GTK_TREE_MODEL (cd->tasks_model), &iter, child_path);
739
gtk_tree_model_get (GTK_TREE_MODEL (cd->tasks_model), &iter,
740
TASK_COLUMN_UID, &uid,
741
TASK_COLUMN_COMPLETED, &task_completed,
742
TASK_COLUMN_PERCENT_COMPLETE, &percent_complete,
745
task_completed = !task_completed;
746
percent_complete = task_completed ? 100 : 0;
748
calendar_client_set_task_completed (cd->client,
754
gtk_tree_path_free (path);
755
gtk_tree_path_free (child_path);
759
handle_task_percent_complete_edited (ClockData *cd,
760
const char *path_str,
762
GtkCellRendererText *cell)
764
GtkTreePath *child_path, *path;
767
int percent_complete;
768
char *error = NULL, *text_copy;
770
path = gtk_tree_path_new_from_string (path_str);
771
child_path = gtk_tree_model_filter_convert_path_to_child_path (cd->tasks_filter, path);
772
gtk_tree_model_get_iter (GTK_TREE_MODEL (cd->tasks_model), &iter, child_path);
773
gtk_tree_model_get (GTK_TREE_MODEL (cd->tasks_model), &iter,
774
TASK_COLUMN_UID, &uid,
777
text_copy = g_strdup (text);
778
text_copy = g_strdelimit (text_copy, "%", ' ');
779
text_copy = g_strstrip (text_copy);
780
percent_complete = (int) g_strtod (text_copy, &error);
781
if (!error || !error [0]) {
782
gboolean task_completed;
784
percent_complete = CLAMP (percent_complete, 0, 100);
785
task_completed = (percent_complete == 100);
787
calendar_client_set_task_completed (cd->client,
795
gtk_tree_path_free (path);
796
gtk_tree_path_free (child_path);
800
filter_out_tasks (GtkTreeModel *model,
805
GTime completed_time;
809
gtk_tree_model_get (model, iter,
810
TASK_COLUMN_START_TIME, &start_time,
811
TASK_COLUMN_COMPLETED_TIME, &completed_time,
814
one_day_ago = cd->current_time - (24 * 60 * 60);
816
visible = !start_time || start_time <= cd->current_time;
818
visible = !completed_time || completed_time >= one_day_ago;
824
modify_task_text_attributes (GtkTreeModel *model,
831
PangoAttrList *attr_list;
832
PangoAttribute *attr;
833
GtkTreeIter child_iter;
835
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
839
if (column != TASK_COLUMN_OVERDUE_ATTR) {
840
memset (value, 0, sizeof (GValue));
841
gtk_tree_model_get_value (GTK_TREE_MODEL (cd->tasks_model),
842
&child_iter, column, value);
847
gtk_tree_model_get (GTK_TREE_MODEL (cd->tasks_model), &child_iter,
848
TASK_COLUMN_DUE_TIME, &due_time,
850
if (due_time && due_time > cd->current_time)
853
attr_list = pango_attr_list_new ();
855
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
856
attr->start_index = 0;
857
attr->end_index = G_MAXINT;
858
pango_attr_list_insert (attr_list, attr);
860
g_value_take_boxed (value, attr_list);
864
create_hig_frame (const char *title)
867
GtkWidget *alignment;
871
vbox = gtk_vbox_new (FALSE, 6);
873
bold_title = g_strdup_printf ("<b>%s</b>", title);
875
alignment = gtk_alignment_new (0, 0.5, 0, 0);
876
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
877
gtk_widget_show (alignment);
879
label = gtk_label_new (bold_title);
880
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
881
gtk_container_add (GTK_CONTAINER (alignment), label);
882
gtk_widget_show (label);
890
task_activated_cb (GtkTreeView *view,
892
GtkTreeViewColumn *column,
896
GtkTreePath *child_path;
899
child_path = gtk_tree_model_filter_convert_path_to_child_path (cd->tasks_filter, path);
901
gtk_tree_model_get_iter (GTK_TREE_MODEL (cd->tasks_model), &iter, child_path);
902
gtk_tree_model_get (GTK_TREE_MODEL (cd->tasks_model), &iter,
903
TASK_COLUMN_URL, &uri, -1);
906
gnome_url_show_on_screen (uri,
907
gtk_widget_get_screen (cd->applet),
912
gtk_tree_path_free (child_path);
918
set_renderer_pixbuf_color_by_column (GtkCellRenderer *renderer,
924
GdkPixbuf *pixbuf = NULL;
927
gtk_tree_model_get (model, iter, column_number, &color_string, -1);
930
sscanf (color_string, "%06x", &color);
931
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 16, 16);
932
gdk_pixbuf_fill (pixbuf, color << 8);
934
g_object_set (renderer, "visible", pixbuf != NULL, "pixbuf", pixbuf, NULL);
937
g_object_unref (pixbuf);
939
g_free (color_string);
944
task_pixbuf_cell_data_func (GtkTreeViewColumn *column,
945
GtkCellRenderer *renderer,
950
set_renderer_pixbuf_color_by_column (renderer,
957
appointment_pixbuf_cell_data_func (GtkTreeViewColumn *column,
958
GtkCellRenderer *renderer,
963
set_renderer_pixbuf_color_by_column (renderer,
966
APPOINTMENT_COLUMN_COLOR);
970
compare_tasks (GtkTreeModel *model,
978
gtk_tree_model_get (model, a, TASK_COLUMN_PRIORITY, &priority_a, -1);
979
gtk_tree_model_get (model, b, TASK_COLUMN_PRIORITY, &priority_b, -1);
981
/* We change undefined priorities so they appear after 'Low'. */
987
/* We'll just use the ordering of the priority values. */
988
if (priority_a < priority_b)
990
else if (priority_a > priority_b)
993
GTime due_time_a, due_time_b;
995
gtk_tree_model_get (model, a,
996
TASK_COLUMN_DUE_TIME, &due_time_a, -1);
997
gtk_tree_model_get (model, b,
998
TASK_COLUMN_DUE_TIME, &due_time_b, -1);
1000
if (due_time_a < due_time_b)
1002
else if (due_time_a > due_time_b)
1010
create_task_list (ClockData *cd,
1011
GtkWidget **tree_view,
1012
GtkWidget **scrolled_window)
1016
GtkWidget *scrolled;
1017
GtkCellRenderer *cell;
1018
GtkTreeViewColumn *column;
1020
vbox = create_hig_frame (_("Tasks"));
1022
*scrolled_window = scrolled = gtk_scrolled_window_new (NULL, NULL);
1023
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
1025
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
1027
GTK_POLICY_AUTOMATIC);
1028
gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
1029
gtk_widget_show (scrolled);
1031
if (!cd->tasks_model) {
1032
GType column_types [N_TASK_COLUMNS] = {
1033
G_TYPE_STRING, /* uid */
1034
G_TYPE_STRING, /* summary */
1035
G_TYPE_STRING, /* description */
1036
G_TYPE_LONG, /* start time */
1037
G_TYPE_LONG, /* due time */
1038
G_TYPE_UINT, /* percent complete */
1039
G_TYPE_STRING, /* percent complete text */
1040
G_TYPE_BOOLEAN, /* completed */
1041
G_TYPE_LONG, /* completed time */
1042
PANGO_TYPE_ATTR_LIST, /* summary text attributes */
1043
G_TYPE_STRING, /* color */
1044
G_TYPE_STRING, /* url */
1045
G_TYPE_INT /* priority */
1048
cd->tasks_model = gtk_list_store_newv (N_TASK_COLUMNS, column_types);
1050
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (cd->tasks_model),
1051
TASK_COLUMN_PRIORITY,
1055
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (cd->tasks_model),
1056
TASK_COLUMN_PRIORITY,
1057
GTK_SORT_ASCENDING);
1059
cd->tasks_filter = GTK_TREE_MODEL_FILTER (
1060
gtk_tree_model_filter_new (GTK_TREE_MODEL (cd->tasks_model),
1062
gtk_tree_model_filter_set_visible_func (
1064
(GtkTreeModelFilterVisibleFunc) filter_out_tasks,
1067
gtk_tree_model_filter_set_modify_func (
1071
(GtkTreeModelFilterModifyFunc) modify_task_text_attributes,
1076
*tree_view = view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (cd->tasks_filter));
1077
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
1079
g_signal_connect (view, "row-activated",
1080
G_CALLBACK (task_activated_cb), cd);
1083
column = gtk_tree_view_column_new ();
1084
cell = gtk_cell_renderer_pixbuf_new ();
1085
gtk_tree_view_column_pack_start (column, cell, TRUE);
1086
gtk_tree_view_column_set_cell_data_func (column, cell,
1087
(GtkTreeCellDataFunc) task_pixbuf_cell_data_func,
1089
gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
1091
/* Completed toggle */
1092
column = gtk_tree_view_column_new ();
1093
cell = gtk_cell_renderer_toggle_new ();
1095
"activatable", TRUE,
1097
g_signal_connect_swapped (cell, "toggled",
1098
G_CALLBACK (handle_task_completed_toggled), cd);
1099
gtk_tree_view_column_pack_start (column, cell, TRUE);
1100
gtk_tree_view_column_add_attribute (column, cell,
1101
"active", TASK_COLUMN_COMPLETED);
1102
gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
1104
/* Percent complete */
1105
column = gtk_tree_view_column_new ();
1106
cell = gtk_cell_renderer_text_new ();
1110
g_signal_connect_swapped (cell, "edited",
1111
G_CALLBACK (handle_task_percent_complete_edited), cd);
1112
gtk_tree_view_column_pack_start (column, cell, TRUE);
1113
gtk_tree_view_column_add_attribute (column, cell,
1114
"text", TASK_COLUMN_PERCENT_COMPLETE_TEXT);
1115
gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
1118
column = gtk_tree_view_column_new ();
1119
cell = gtk_cell_renderer_text_new ();
1120
g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
1121
gtk_tree_view_column_pack_start (column, cell, TRUE);
1122
gtk_tree_view_column_set_attributes (column, cell,
1123
"text", TASK_COLUMN_SUMMARY,
1124
"strikethrough", TASK_COLUMN_COMPLETED,
1125
"attributes", TASK_COLUMN_OVERDUE_ATTR,
1127
gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
1129
gtk_container_add (GTK_CONTAINER (scrolled), view);
1131
gtk_widget_show (view);
1137
mark_day_on_calendar (CalendarClient *client,
1141
gtk_chinese_calendar_mark_day (GTK_CHINESE_CALENDAR (cd->calendar), day);
1145
handle_appointments_changed (ClockData *cd)
1148
guint year, month, day;
1151
gtk_chinese_calendar_clear_marks (GTK_CHINESE_CALENDAR (cd->calendar));
1153
calendar_client_foreach_appointment_day (cd->client,
1154
(CalendarDayIter) mark_day_on_calendar,
1158
gtk_list_store_clear (cd->appointments_model);
1160
events = calendar_client_get_events (cd->client, CALENDAR_EVENT_APPOINTMENT);
1161
calendar_client_get_date (cd->client, &year, &month, &day);
1162
for (l = events; l; l = l->next) {
1163
CalendarAppointment *appointment = l->data;
1167
g_assert (CALENDAR_EVENT (appointment)->type == CALENDAR_EVENT_APPOINTMENT);
1169
if (appointment->is_all_day)
1170
start_text = g_strdup (_("All Day"));
1172
start_text = format_time (cd->format,
1173
appointment->start_time,
1178
gtk_list_store_append (cd->appointments_model, &iter);
1179
gtk_list_store_set (cd->appointments_model, &iter,
1180
APPOINTMENT_COLUMN_UID, appointment->uid,
1181
APPOINTMENT_COLUMN_SUMMARY, appointment->summary,
1182
APPOINTMENT_COLUMN_DESCRIPTION, appointment->description,
1183
APPOINTMENT_COLUMN_START_TIME, appointment->start_time,
1184
APPOINTMENT_COLUMN_START_TEXT, start_text,
1185
APPOINTMENT_COLUMN_END_TIME, appointment->end_time,
1186
APPOINTMENT_COLUMN_ALL_DAY, appointment->is_all_day,
1187
APPOINTMENT_COLUMN_COLOR , appointment->color_string,
1190
g_free (start_text);
1191
calendar_event_free (CALENDAR_EVENT (appointment));
1193
g_slist_free (events);
1195
update_frame_visibility (cd->appointment_list, GTK_TREE_MODEL (cd->appointments_model));
1199
create_appointment_list (ClockData *cd,
1200
GtkWidget **tree_view,
1201
GtkWidget **scrolled_window)
1205
GtkWidget *scrolled;
1206
GtkCellRenderer *cell;
1207
GtkTreeViewColumn *column;
1209
vbox = create_hig_frame ( _("Appointments"));
1211
*scrolled_window = scrolled = gtk_scrolled_window_new (NULL, NULL);
1212
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
1214
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
1216
GTK_POLICY_AUTOMATIC);
1217
gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
1218
gtk_widget_show (scrolled);
1220
if (!cd->appointments_model) {
1221
cd->appointments_model =
1222
gtk_list_store_new (N_APPOINTMENT_COLUMNS,
1223
G_TYPE_STRING, /* uid */
1224
G_TYPE_STRING, /* summary */
1225
G_TYPE_STRING, /* description */
1226
G_TYPE_LONG, /* start time */
1227
G_TYPE_STRING, /* start time text */
1228
G_TYPE_LONG, /* end time */
1229
G_TYPE_BOOLEAN, /* all day */
1230
G_TYPE_STRING); /* color */
1232
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (cd->appointments_model),
1233
APPOINTMENT_COLUMN_START_TIME,
1234
GTK_SORT_ASCENDING);
1238
*tree_view = view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (cd->appointments_model));
1239
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
1242
column = gtk_tree_view_column_new ();
1243
cell = gtk_cell_renderer_pixbuf_new ();
1244
gtk_tree_view_column_pack_start (column, cell, TRUE);
1245
gtk_tree_view_column_set_cell_data_func (column, cell,
1246
(GtkTreeCellDataFunc) appointment_pixbuf_cell_data_func,
1248
gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
1251
column = gtk_tree_view_column_new ();
1252
cell = gtk_cell_renderer_text_new ();
1253
gtk_tree_view_column_pack_start (column, cell, TRUE);
1254
gtk_tree_view_column_add_attribute (column, cell,
1255
"text", APPOINTMENT_COLUMN_START_TEXT);
1256
gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
1259
column = gtk_tree_view_column_new ();
1260
cell = gtk_cell_renderer_text_new ();
1261
g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
1262
gtk_tree_view_column_pack_start (column, cell, TRUE);
1263
gtk_tree_view_column_add_attribute (column, cell,
1264
"text", APPOINTMENT_COLUMN_SUMMARY);
1265
gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
1267
gtk_container_add (GTK_CONTAINER (scrolled), view);
1269
gtk_widget_show (view);
1275
calendar_day_activated (ClockData *cd,
1276
GtkCalendar *calendar)
1284
gtk_chinese_calendar_get_date (GTK_CHINESE_CALENDAR (cd->calendar),
1285
&year, &month, &day);
1287
command_line = g_strdup_printf ("evolution "
1288
"calendar:///?startdate=%.4d%.2d%.2d",
1289
year, month + 1, day);
1293
if (!gdk_spawn_command_line_on_screen (gtk_widget_get_screen (cd->calendar),
1294
command_line, &error)) {
1295
g_printerr ("Cannot launch calendar: %s\n", error->message);
1296
g_error_free (error);
1299
g_free (command_line);
1303
calendar_day_selected (ClockData *cd)
1307
gtk_chinese_calendar_get_date (GTK_CHINESE_CALENDAR (cd->calendar), NULL, NULL, &day);
1309
calendar_client_select_day (cd->client, day);
1311
handle_appointments_changed (cd);
1312
handle_tasks_changed (cd);
1316
calendar_month_selected (ClockData *cd)
1320
gtk_chinese_calendar_get_date (GTK_CHINESE_CALENDAR (cd->calendar), &year, &month, NULL);
1322
calendar_client_select_month (cd->client, month, year);
1324
handle_appointments_changed (cd);
1325
handle_tasks_changed (cd);
1330
GtkWidget *calendar;
1335
constrain_list_size (GtkWidget *widget,
1336
GtkRequisition *requisition,
1337
ConstraintData *constraint)
1342
/* constrain width to the calendar width */
1343
gtk_widget_size_request (constraint->calendar, &req);
1344
requisition->width = MIN (requisition->width, req.width);
1346
/* constrain height to be the tree height up to a max */
1347
max_height = (gdk_screen_get_height (gtk_widget_get_screen (widget)) - req.height) / 3;
1348
gtk_widget_size_request (constraint->tree, &req);
1350
requisition->height = MIN (req.height, max_height);
1351
requisition->height += 2 * widget->style->ythickness;
1355
setup_list_size_constraint (GtkWidget *widget,
1356
GtkWidget *calendar,
1359
ConstraintData *constraint;
1361
constraint = g_new0 (ConstraintData, 1);
1362
constraint->calendar = calendar;
1363
constraint->tree = tree;
1365
g_signal_connect_data (widget, "size-request",
1366
G_CALLBACK (constrain_list_size), constraint,
1367
(GClosureNotify) g_free, 0);
1370
#endif /* HAVE_LIBECAL */
1373
add_appointments_and_tasks (ClockData *cd,
1377
GtkWidget *tree_view;
1378
GtkWidget *scrolled_window;
1379
guint year, month, day;
1381
cd->task_list = create_task_list (cd, &tree_view, &scrolled_window);
1382
g_object_add_weak_pointer (G_OBJECT (cd->task_list),
1383
(gpointer *) &cd->task_list);
1384
setup_list_size_constraint (scrolled_window, cd->calendar, tree_view);
1385
update_frame_visibility (cd->task_list, GTK_TREE_MODEL (cd->tasks_model));
1387
cd->appointment_list = create_appointment_list (cd, &tree_view, &scrolled_window);
1388
g_object_add_weak_pointer (G_OBJECT (cd->appointment_list),
1389
(gpointer *) &cd->appointment_list);
1390
setup_list_size_constraint (scrolled_window, cd->calendar, tree_view);
1391
update_frame_visibility (cd->appointment_list, GTK_TREE_MODEL (cd->appointments_model));
1393
switch (cd->orient) {
1394
case PANEL_APPLET_ORIENT_UP:
1395
gtk_box_pack_start (GTK_BOX (vbox), cd->appointment_list, TRUE, TRUE, 0);
1396
gtk_box_pack_start (GTK_BOX (vbox), cd->task_list, TRUE, TRUE, 0);
1399
gtk_box_pack_start (GTK_BOX (vbox), cd->task_list, TRUE, TRUE, 0);
1400
gtk_box_pack_start (GTK_BOX (vbox), cd->appointment_list, TRUE, TRUE, 0);
1405
cd->client = calendar_client_new ();
1407
g_signal_connect_swapped (cd->client, "tasks-changed",
1408
G_CALLBACK (handle_tasks_changed), cd);
1409
g_signal_connect_swapped (cd->client, "appointments-changed",
1410
G_CALLBACK (handle_appointments_changed), cd);
1413
gtk_chinese_calendar_get_date (GTK_CHINESE_CALENDAR (cd->calendar), &year, &month, &day);
1415
calendar_client_select_day (cd->client, day);
1416
calendar_client_select_month (cd->client, month, year);
1418
handle_tasks_changed (cd);
1419
handle_appointments_changed (cd);
1421
g_signal_connect_swapped (cd->calendar, "day-selected-double-click",
1422
G_CALLBACK (calendar_day_activated), cd);
1423
g_signal_connect_swapped (cd->calendar, "day-selected",
1424
G_CALLBACK (calendar_day_selected), cd);
1425
g_signal_connect_swapped (cd->calendar, "month-changed",
1426
G_CALLBACK (calendar_month_selected), cd);
1427
#endif /* HAVE_LIBECAL */
1431
create_calendar (ClockData *cd,
1437
GtkCalendarDisplayOptions options;
1440
window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
1441
gtk_window_set_icon_name (window, CLOCK_ICON);
1442
gtk_window_set_screen (window, screen);
1444
frame = gtk_frame_new (NULL);
1445
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
1446
gtk_container_add (GTK_CONTAINER (window), frame);
1447
gtk_widget_show (frame);
1449
vbox = gtk_vbox_new (FALSE, 6);
1450
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
1451
gtk_container_add (GTK_CONTAINER (frame), vbox);
1452
gtk_widget_show (vbox);
1454
gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DOCK);
1455
gtk_window_set_decorated (window, FALSE);
1456
gtk_window_set_resizable (window, FALSE);
1457
gtk_window_stick (window);
1458
gtk_window_set_title (window, _("Calendar"));
1460
g_signal_connect (window, "delete_event",
1461
G_CALLBACK (delete_event), cd);
1463
g_signal_connect (window, "key_press_event",
1464
G_CALLBACK (close_on_escape), cd);
1466
cd->calendar = gtk_chinese_calendar_new ();
1467
g_object_add_weak_pointer (G_OBJECT (cd->calendar),
1468
(gpointer *) &cd->calendar);
1470
options = gtk_chinese_calendar_get_display_options (GTK_CHINESE_CALENDAR (cd->calendar));
1472
options |= GTK_CHINESE_CALENDAR_SHOW_WEEK_NUMBERS;
1473
if (cd->showlunardate)
1474
options |= GTK_CHINESE_CALENDAR_SHOW_LUNAR_DATE;
1476
options &= ~GTK_CHINESE_CALENDAR_SHOW_LUNAR_DATE;
1477
gtk_chinese_calendar_set_display_options (GTK_CHINESE_CALENDAR (cd->calendar), options);
1480
tm = gmtime (&cd->current_time);
1482
tm = localtime (&cd->current_time);
1483
gtk_chinese_calendar_select_month (GTK_CHINESE_CALENDAR (cd->calendar),
1485
tm->tm_year + 1900);
1486
gtk_chinese_calendar_select_day (GTK_CHINESE_CALENDAR (cd->calendar), tm->tm_mday);
1488
switch (cd->orient) {
1489
case PANEL_APPLET_ORIENT_UP:
1490
add_appointments_and_tasks (cd, vbox);
1491
gtk_box_pack_start (GTK_BOX (vbox), cd->calendar, TRUE, FALSE, 0);
1494
gtk_box_pack_start (GTK_BOX (vbox), cd->calendar, TRUE, FALSE, 0);
1495
add_appointments_and_tasks (cd, vbox);
1498
gtk_widget_show (cd->calendar);
1500
return GTK_WIDGET (window);
1504
position_calendar_popup (ClockData *cd,
1510
GdkRectangle monitor;
1511
GdkGravity gravity = GDK_GRAVITY_NORTH_WEST;
1512
int button_w, button_h;
1516
gboolean found_monitor = FALSE;
1518
/* Get root origin of the toggle button, and position above that. */
1519
gdk_window_get_origin (button->window, &x, &y);
1521
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
1522
gtk_widget_size_request (window, &req);
1526
button_w = button->allocation.width;
1527
button_h = button->allocation.height;
1529
screen = gtk_window_get_screen (GTK_WINDOW (window));
1531
n = gdk_screen_get_n_monitors (screen);
1532
for (i = 0; i < n; i++) {
1533
gdk_screen_get_monitor_geometry (screen, i, &monitor);
1534
if (x >= monitor.x && x <= monitor.x + monitor.width &&
1535
y >= monitor.y && y <= monitor.y + monitor.height) {
1536
found_monitor = TRUE;
1541
if ( ! found_monitor) {
1542
/* eek, we should be on one of those xinerama
1546
monitor.width = gdk_screen_get_width (screen);
1547
monitor.height = gdk_screen_get_height (screen);
1550
/* Based on panel orientation, position the popup.
1551
* Ignore window gravity since the window is undecorated.
1552
* The orientations are all named backward from what
1555
switch (cd->orient) {
1556
case PANEL_APPLET_ORIENT_RIGHT:
1558
if ((y + h) > monitor.y + monitor.height)
1559
y -= (y + h) - (monitor.y + monitor.height);
1561
if ((y + h) > (monitor.height / 2))
1562
gravity = GDK_GRAVITY_SOUTH_WEST;
1564
gravity = GDK_GRAVITY_NORTH_WEST;
1567
case PANEL_APPLET_ORIENT_LEFT:
1569
if ((y + h) > monitor.y + monitor.height)
1570
y -= (y + h) - (monitor.y + monitor.height);
1572
if ((y + h) > (monitor.height / 2))
1573
gravity = GDK_GRAVITY_SOUTH_EAST;
1575
gravity = GDK_GRAVITY_NORTH_EAST;
1578
case PANEL_APPLET_ORIENT_DOWN:
1580
if ((x + w) > monitor.x + monitor.width)
1581
x -= (x + w) - (monitor.x + monitor.width);
1583
gravity = GDK_GRAVITY_NORTH_WEST;
1586
case PANEL_APPLET_ORIENT_UP:
1588
if ((x + w) > monitor.x + monitor.width)
1589
x -= (x + w) - (monitor.x + monitor.width);
1591
gravity = GDK_GRAVITY_SOUTH_WEST;
1596
gtk_window_move (GTK_WINDOW (window), x, y);
1597
gtk_window_set_gravity (GTK_WINDOW (window), gravity);
1601
present_calendar_popup (ClockData *cd,
1605
position_calendar_popup (cd, window, button);
1606
gtk_window_present (GTK_WINDOW (window));
1610
refresh_calendar (ClockData *cd)
1612
if (cd->calendar_popup)
1613
gtk_widget_destroy (cd->calendar_popup);
1614
cd->calendar_popup = NULL;
1615
if (!cd->calendar_popup) {
1616
cd->calendar_popup = create_calendar (cd, gtk_widget_get_screen (cd->applet));
1617
g_object_add_weak_pointer (G_OBJECT (cd->calendar_popup),
1618
(gpointer *) &cd->calendar_popup);
1621
if (cd->calendar_popup && GTK_WIDGET_REALIZED (cd->toggle)) {
1623
if (cd->tasks_filter && cd->task_list)
1624
gtk_tree_model_filter_refilter (cd->tasks_filter);
1627
present_calendar_popup (cd, cd->calendar_popup, cd->toggle);
1628
gtk_window_present (GTK_WINDOW (cd->calendar_popup));
1633
update_popup (ClockData *cd)
1635
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cd->toggle))) {
1636
if (cd->calendar_popup)
1637
gtk_widget_destroy (cd->calendar_popup);
1638
cd->calendar_popup = NULL;
1642
if (!cd->calendar_popup) {
1643
cd->calendar_popup = create_calendar (cd, gtk_widget_get_screen (cd->applet));
1644
g_object_add_weak_pointer (G_OBJECT (cd->calendar_popup),
1645
(gpointer *) &cd->calendar_popup);
1648
if (cd->calendar_popup && GTK_WIDGET_REALIZED (cd->toggle)) {
1650
if (cd->tasks_filter && cd->task_list)
1651
gtk_tree_model_filter_refilter (cd->tasks_filter);
1654
present_calendar_popup (cd, cd->calendar_popup, cd->toggle);
1655
gtk_window_present (GTK_WINDOW (cd->calendar_popup));
1660
toggle_calendar (GtkWidget *button,
1667
do_not_eat_button_press (GtkWidget *widget,
1668
GdkEventButton *event)
1670
if (event->button != 1)
1671
g_signal_stop_emission_by_name (widget, "button_press_event");
1676
/* Don't request smaller size then the last one we did, this avoids
1677
jumping when proportional fonts are used. We must take care to
1678
call "unfix_size" whenever options are changed or such where
1679
we'd want to forget the fixed size */
1681
clock_size_request (GtkWidget *clock, GtkRequisition *req, gpointer data)
1683
ClockData *cd = data;
1685
if (req->width > cd->fixed_width)
1686
cd->fixed_width = req->width;
1687
if (req->height > cd->fixed_height)
1688
cd->fixed_height = req->height;
1689
req->width = cd->fixed_width;
1690
req->height = cd->fixed_height;
1694
force_no_focus_padding (GtkWidget *widget)
1696
gboolean first_time = TRUE;
1699
gtk_rc_parse_string ("\n"
1700
" style \"clock-applet-button-style\"\n"
1702
" GtkWidget::focus-line-width=0\n"
1703
" GtkWidget::focus-padding=0\n"
1706
" widget \"*.clock-applet-button\" style \"clock-applet-button-style\"\n"
1711
gtk_widget_set_name (widget, "clock-applet-button");
1715
create_clock_widget (ClockData *cd)
1719
GtkWidget *alignment;
1721
clock = gtk_label_new ("hmm?");
1722
g_signal_connect (clock, "size_request",
1723
G_CALLBACK (clock_size_request),
1725
g_signal_connect_swapped (clock, "style_set",
1726
G_CALLBACK (unfix_size),
1728
gtk_label_set_justify (GTK_LABEL (clock), GTK_JUSTIFY_CENTER);
1729
gtk_widget_show (clock);
1731
toggle = gtk_toggle_button_new ();
1732
gtk_container_set_resize_mode (GTK_CONTAINER (toggle), GTK_RESIZE_IMMEDIATE);
1733
gtk_button_set_relief (GTK_BUTTON (toggle), GTK_RELIEF_NONE);
1735
force_no_focus_padding (toggle);
1737
alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
1738
gtk_container_add (GTK_CONTAINER (alignment), clock);
1739
gtk_container_set_resize_mode (GTK_CONTAINER (alignment), GTK_RESIZE_IMMEDIATE);
1740
gtk_widget_show (alignment);
1741
gtk_container_add (GTK_CONTAINER (toggle), alignment);
1743
g_signal_connect (toggle, "button_press_event",
1744
G_CALLBACK (do_not_eat_button_press), NULL);
1746
g_signal_connect (toggle, "toggled",
1747
G_CALLBACK (toggle_calendar), cd);
1749
gtk_widget_show (toggle);
1751
cd->toggle = toggle;
1757
cd->orient = panel_applet_get_orient (PANEL_APPLET (cd->applet));
1759
cd->size = panel_applet_get_size (PANEL_APPLET (cd->applet));
1761
g_signal_connect (G_OBJECT(clock), "destroy",
1762
G_CALLBACK (destroy_clock),
1765
set_atk_name_description (GTK_WIDGET (cd->applet), NULL,
1766
_("Computer Clock"));
1768
/* Refresh the clock so that it paints its first state */
1769
refresh_clock_timeout(cd);
1773
update_orient (ClockData *cd)
1780
text = gtk_label_get_text (GTK_LABEL (cd->clockw));
1781
min_width = calculate_minimum_width (cd->toggle, text);
1783
if (cd->orient == PANEL_APPLET_ORIENT_LEFT &&
1784
min_width > cd->toggle->allocation.width)
1786
else if (cd->orient == PANEL_APPLET_ORIENT_RIGHT &&
1787
min_width > cd->toggle->allocation.width)
1792
angle = gtk_label_get_angle (GTK_LABEL (cd->clockw));
1793
if (angle != new_angle) {
1795
gtk_label_set_angle (GTK_LABEL (cd->clockw), new_angle);
1799
/* this is when the panel orientation changes */
1801
applet_change_orient (PanelApplet *applet,
1802
PanelAppletOrient orient,
1805
if (orient == cd->orient)
1808
cd->orient = orient;
1815
/* this is when the panel size changes */
1817
toggle_change_pixel_size (GtkWidget *widget,
1818
GtkAllocation *allocation,
1823
if (cd->old_allocation.width == allocation->width &&
1824
cd->old_allocation.height == allocation->height)
1827
cd->old_allocation.width = allocation->width;
1828
cd->old_allocation.height = allocation->height;
1830
if (cd->orient == PANEL_APPLET_ORIENT_LEFT ||
1831
cd->orient == PANEL_APPLET_ORIENT_RIGHT)
1832
new_size = allocation->width;
1834
new_size = allocation->height;
1836
cd->size = new_size;
1839
update_timeformat (cd);
1844
copy_time (BonoboUIComponent *uic,
1846
const gchar *verbname)
1851
if (cd->format == CLOCK_FORMAT_UNIX) {
1852
g_snprintf (string, sizeof(string), "%lu",
1853
(unsigned long)cd->current_time);
1854
} else if (cd->format == CLOCK_FORMAT_INTERNET) {
1855
float itime = get_itime (cd->current_time);
1856
if (cd->showseconds)
1857
g_snprintf (string, sizeof (string), "@%3.2f", itime);
1859
g_snprintf (string, sizeof (string), "@%3.0f", itime);
1864
if (cd->format == CLOCK_FORMAT_CUSTOM) {
1865
format = g_locale_from_utf8 (cd->custom_format, -1,
1867
} else if (cd->format == CLOCK_FORMAT_12) {
1868
if (cd->showseconds)
1869
format = g_locale_from_utf8 (_("%I:%M:%S %p"), -1, NULL, NULL, NULL);
1871
format = g_locale_from_utf8 (_("%I:%M %p"), -1, NULL, NULL, NULL);
1873
if (cd->showseconds)
1874
format = g_locale_from_utf8 (_("%H:%M:%S"), -1, NULL, NULL, NULL);
1876
format = g_locale_from_utf8 (_("%H:%M"), -1, NULL, NULL, NULL);
1880
tm = gmtime (&cd->current_time);
1882
tm = localtime (&cd->current_time);
1885
strcpy (string, "???");
1886
else if (strftime (string, sizeof (string), format, tm) <= 0)
1887
strcpy (string, "???");
1891
utf8 = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
1892
gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
1894
gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1900
copy_date (BonoboUIComponent *uic,
1902
const gchar *verbname)
1909
tm = gmtime (&cd->current_time);
1911
tm = localtime (&cd->current_time);
1913
loc = g_locale_from_utf8 (_("%A, %B %d %Y"), -1, NULL, NULL, NULL);
1915
strcpy (string, "???");
1916
else if (strftime (string, sizeof (string), loc, tm) <= 0)
1917
strcpy (string, "???");
1920
utf8 = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
1921
gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
1923
gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1929
try_config_tool (GdkScreen *screen,
1937
if (!tool || tool[0] == '\0')
1940
if (!g_shell_parse_argv (tool, NULL, &argv, NULL))
1943
if (!(path = g_find_program_in_path (argv [0]))) {
1951
if (gdk_spawn_on_screen (screen,
1955
G_SPAWN_SEARCH_PATH,
1966
dialog = gtk_message_dialog_new (NULL,
1967
GTK_DIALOG_DESTROY_WITH_PARENT,
1970
_("Failed to launch time configuration tool: %s"),
1974
g_signal_connect (dialog, "response",
1975
G_CALLBACK (gtk_widget_destroy), NULL);
1977
gtk_window_set_icon_name (GTK_WINDOW (dialog), CLOCK_ICON);
1978
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
1979
gtk_window_set_screen (GTK_WINDOW (dialog), screen);
1981
gtk_widget_show_all (dialog);
1987
config_date (BonoboUIComponent *uic,
1989
const char *verbname)
1995
screen = gtk_widget_get_screen (cd->applet);
1997
if (try_config_tool (screen, cd->config_tool))
2000
for (i = 0; i < G_N_ELEMENTS (clock_config_tools); i++)
2001
if (try_config_tool (screen, clock_config_tools [i]))
2004
dialog = gtk_message_dialog_new (NULL,
2005
GTK_DIALOG_DESTROY_WITH_PARENT,
2008
_("Failed to locate a program for configuring "
2009
"the date and time. Perhaps none is installed?"));
2011
g_signal_connect (dialog, "response",
2012
G_CALLBACK (gtk_widget_destroy), NULL);
2014
gtk_window_set_icon_name (GTK_WINDOW (dialog), CLOCK_ICON);
2015
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
2016
gtk_window_set_screen (GTK_WINDOW (dialog), screen);
2018
gtk_widget_show_all (dialog);
2021
/* current timestamp */
2022
static const BonoboUIVerb clock_menu_verbs [] = {
2023
BONOBO_UI_UNSAFE_VERB ("ClockPreferences", display_properties_dialog),
2024
BONOBO_UI_UNSAFE_VERB ("ClockHelp", display_help_dialog),
2025
BONOBO_UI_UNSAFE_VERB ("ClockAbout", display_about_dialog),
2026
BONOBO_UI_UNSAFE_VERB ("ClockCopyTime", copy_time),
2027
BONOBO_UI_UNSAFE_VERB ("ClockCopyDate", copy_date),
2028
BONOBO_UI_UNSAFE_VERB ("ClockConfig", config_date),
2033
format_changed (GConfClient *client,
2041
if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
2044
value = gconf_value_get_string (entry->value);
2045
if (!gconf_string_to_enum (format_type_enum_map, value, &new_format))
2048
if (!clock->can_handle_format_12 && new_format == CLOCK_FORMAT_12)
2049
new_format = CLOCK_FORMAT_24;
2051
if (new_format == clock->format)
2054
clock->format = new_format;
2055
update_timeformat (clock);
2056
refresh_clock_timeout (clock);
2060
show_seconds_changed (GConfClient *client,
2067
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
2070
value = gconf_value_get_bool (entry->value);
2072
clock->showseconds = (value != 0);
2073
refresh_clock_timeout (clock);
2077
show_date_changed (GConfClient *client,
2084
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
2087
value = gconf_value_get_bool (entry->value);
2089
clock->showdate = (value != 0);
2090
update_timeformat (clock);
2091
refresh_clock (clock);
2095
show_lunardate_changed (GConfClient *client,
2102
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
2105
value = gconf_value_get_bool (entry->value);
2107
clock->showlunardate = (value != 0);
2108
refresh_calendar(clock);
2109
//update_popup (clock);
2113
gmt_time_changed (GConfClient *client,
2120
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
2123
value = gconf_value_get_bool (entry->value);
2125
clock->gmt_time = (value != 0);
2126
refresh_clock_timeout (clock);
2130
check_config_tool_command (const char *config_tool)
2135
if (!config_tool || config_tool[0] == '\0')
2139
if (!g_shell_parse_argv (config_tool, NULL, &argv, NULL))
2142
if (!(path = g_find_program_in_path (argv [0]))) {
2154
config_tool_changed (GConfClient *client,
2161
if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
2164
value = gconf_value_get_string (entry->value);
2166
if (check_config_tool_command (value)) {
2167
g_free (clock->config_tool);
2168
clock->config_tool = g_strdup (value);
2173
custom_format_changed (GConfClient *client,
2180
if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
2183
value = gconf_value_get_string (entry->value);
2185
g_free (clock->custom_format);
2186
clock->custom_format = g_strdup (value);
2188
if (clock->format == CLOCK_FORMAT_CUSTOM)
2189
refresh_clock (clock);
2193
show_week_changed (GConfClient *client,
2198
GtkCalendarDisplayOptions options;
2201
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
2204
value = gconf_value_get_bool (entry->value);
2206
if (clock->showweek == (value != 0))
2209
clock->showweek = (value != 0);
2211
if (clock->calendar_popup != NULL) {
2212
options = gtk_chinese_calendar_get_display_options (GTK_CHINESE_CALENDAR (clock->calendar));
2214
if (clock->showweek)
2215
options |= GTK_CHINESE_CALENDAR_SHOW_WEEK_NUMBERS;
2217
options &= ~(GTK_CHINESE_CALENDAR_SHOW_WEEK_NUMBERS);
2219
gtk_chinese_calendar_set_display_options (GTK_CHINESE_CALENDAR (clock->calendar),
2222
position_calendar_popup (clock, clock->calendar_popup,
2228
setup_gconf (ClockData *clock)
2230
GConfClient *client;
2233
client = gconf_client_get_default ();
2235
key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
2237
clock->listeners [0] =
2238
gconf_client_notify_add (
2240
(GConfClientNotifyFunc) format_changed,
2244
key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
2246
clock->listeners [1] =
2247
gconf_client_notify_add (
2249
(GConfClientNotifyFunc)show_seconds_changed,
2253
key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
2255
clock->listeners [2] =
2256
gconf_client_notify_add (
2258
(GConfClientNotifyFunc) show_date_changed,
2262
key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
2263
KEY_SHOW_LUNARDATE);
2264
clock->listeners [3] =
2265
gconf_client_notify_add (
2267
(GConfClientNotifyFunc) show_lunardate_changed,
2271
key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
2273
clock->listeners [4] =
2274
gconf_client_notify_add (
2276
(GConfClientNotifyFunc) gmt_time_changed,
2280
key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
2282
clock->listeners [5] =
2283
gconf_client_notify_add (
2285
(GConfClientNotifyFunc) config_tool_changed,
2289
key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
2291
clock->listeners [6] =
2292
gconf_client_notify_add (
2294
(GConfClientNotifyFunc) custom_format_changed,
2298
key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
2300
clock->listeners [7] =
2301
gconf_client_notify_add (
2303
(GConfClientNotifyFunc) show_week_changed,
2307
g_object_unref (G_OBJECT (client));
2311
clock_migrate_to_26 (ClockData *clock)
2314
gboolean internettime;
2317
internettime = panel_applet_gconf_get_bool (PANEL_APPLET (clock->applet),
2320
unixtime = panel_applet_gconf_get_bool (PANEL_APPLET (clock->applet),
2323
hourformat = panel_applet_gconf_get_int (PANEL_APPLET (clock->applet),
2328
clock->format = CLOCK_FORMAT_UNIX;
2329
else if (internettime)
2330
clock->format = CLOCK_FORMAT_INTERNET;
2331
else if (hourformat == 12)
2332
clock->format = CLOCK_FORMAT_12;
2333
else if (hourformat == 24)
2334
clock->format = CLOCK_FORMAT_24;
2336
panel_applet_gconf_set_string (PANEL_APPLET (clock->applet),
2338
gconf_enum_to_string (format_type_enum_map,
2344
fill_clock_applet (PanelApplet *applet)
2347
BonoboUIComponent *popup_component;
2352
panel_applet_add_preferences (applet, "/schemas/apps/clock_applet/prefs", NULL);
2353
panel_applet_set_flags (applet, PANEL_APPLET_EXPAND_MINOR);
2355
cd = g_new0 (ClockData, 1);
2356
cd->fixed_width = -1;
2357
cd->fixed_height = -1;
2359
cd->applet = GTK_WIDGET (applet);
2363
cd->format = CLOCK_FORMAT_INVALID;
2365
format_str = panel_applet_gconf_get_string (applet, KEY_FORMAT, NULL);
2367
gconf_string_to_enum (format_type_enum_map, format_str, &format))
2368
cd->format = format;
2370
clock_migrate_to_26 (cd);
2372
g_free (format_str);
2374
if (cd->format == CLOCK_FORMAT_INVALID)
2375
cd->format = clock_locale_format ();
2377
cd->custom_format = panel_applet_gconf_get_string (applet, KEY_CUSTOM_FORMAT, NULL);
2378
cd->showseconds = panel_applet_gconf_get_bool (applet, KEY_SHOW_SECONDS, NULL);
2381
cd->showdate = panel_applet_gconf_get_bool (applet, KEY_SHOW_DATE, &error);
2383
g_error_free (error);
2384
/* if on a small screen don't show date by default */
2385
if (gdk_screen_width () <= 800)
2386
cd->showdate = FALSE;
2388
cd->showdate = TRUE;
2392
cd->showlunardate = panel_applet_gconf_get_bool (applet, KEY_SHOW_LUNARDATE, &error);
2394
g_error_free (error);
2395
/* if on a small screen don't show date by default */
2396
if (gdk_screen_width () <= 800)
2397
cd->showlunardate = FALSE;
2399
cd->showlunardate = TRUE;
2402
cd->gmt_time = panel_applet_gconf_get_bool (applet, KEY_GMT_TIME, NULL);
2403
cd->showweek = panel_applet_gconf_get_bool (applet, KEY_SHOW_WEEK, NULL);
2404
cd->config_tool = panel_applet_gconf_get_string (applet, KEY_CONFIG_TOOL, NULL);
2406
cd->timeformat = NULL;
2408
cd->can_handle_format_12 = (clock_locale_format () == CLOCK_FORMAT_12);
2409
if (!cd->can_handle_format_12 && cd->format == CLOCK_FORMAT_12)
2410
cd->format = CLOCK_FORMAT_24;
2412
create_clock_widget (cd);
2414
gtk_container_set_border_width (GTK_CONTAINER (cd->applet), 0);
2415
gtk_container_set_border_width (GTK_CONTAINER (cd->toggle), 0);
2416
gtk_container_add (GTK_CONTAINER (cd->applet), cd->toggle);
2418
#ifndef CLOCK_INPROCESS
2419
gtk_window_set_default_icon_name (CLOCK_ICON);
2421
gtk_widget_show (cd->applet);
2423
/* FIXME: Update this comment. */
2424
/* we have to bind change_orient before we do applet_widget_add
2425
since we need to get an initial change_orient signal to set our
2426
initial oriantation, and we get that during the _add call */
2427
g_signal_connect (G_OBJECT (cd->applet),
2429
G_CALLBACK (applet_change_orient),
2432
g_signal_connect (G_OBJECT (cd->toggle),
2434
G_CALLBACK (toggle_change_pixel_size),
2437
panel_applet_set_background_widget (PANEL_APPLET (cd->applet),
2438
GTK_WIDGET (cd->applet));
2440
panel_applet_setup_menu_from_file (PANEL_APPLET (cd->applet),
2442
"GNOME_LunarApplet.xml",
2447
popup_component = panel_applet_get_popup_component (PANEL_APPLET (cd->applet));
2449
if (panel_applet_get_locked_down (PANEL_APPLET (cd->applet))) {
2450
bonobo_ui_component_set_prop (popup_component,
2451
"/commands/ClockPreferences",
2454
bonobo_ui_component_set_prop (popup_component,
2455
"/commands/ClockConfig",
2460
if (!check_config_tool_command (cd->config_tool)) {
2461
g_free (cd->config_tool);
2462
cd->config_tool = NULL;
2465
if (!cd->config_tool) {
2468
for (i = 0; i < G_N_ELEMENTS (clock_config_tools); i++)
2469
if (check_config_tool_command (clock_config_tools [i])) {
2470
cd->config_tool = g_strdup (clock_config_tools [i]);
2475
bonobo_ui_component_set_prop (popup_component,
2476
"/commands/ClockConfig",
2477
"hidden", cd->config_tool ? "0" : "1",
2484
setup_writability_sensitivity (ClockData *clock, GtkWidget *w, GtkWidget *label, const char *key)
2487
GConfClient *client;
2489
client = gconf_client_get_default ();
2491
fullkey = panel_applet_gconf_get_full_key
2492
(PANEL_APPLET (clock->applet), key);
2494
if ( ! gconf_client_key_is_writable (client, fullkey, NULL)) {
2495
g_object_set_data (G_OBJECT (w), NEVER_SENSITIVE,
2496
GINT_TO_POINTER (1));
2497
gtk_widget_set_sensitive (w, FALSE);
2498
if (label != NULL) {
2499
g_object_set_data (G_OBJECT (label), NEVER_SENSITIVE,
2500
GINT_TO_POINTER (1));
2501
gtk_widget_set_sensitive (label, FALSE);
2507
g_object_unref (G_OBJECT (client));
2511
update_properties_for_format (ClockData *cd,
2516
/* show the custom format things the first time we actually
2517
* have a custom format set in GConf, but after that don't
2518
* unshow it if the format changes
2520
if (!cd->custom_format_shown &&
2521
(cd->format == CLOCK_FORMAT_CUSTOM ||
2522
(cd->custom_format && cd->custom_format [0]))) {
2523
gtk_widget_show (cd->custom_hbox);
2524
gtk_widget_show (cd->custom_label);
2525
gtk_widget_show (cd->custom_entry);
2527
gtk_combo_box_append_text (combo, _("Custom format"));
2529
cd->custom_format_shown = TRUE;
2532
/* Some combinations of options do not make sense */
2534
case CLOCK_FORMAT_12:
2535
case CLOCK_FORMAT_24:
2536
gtk_widget_set_sensitive (cd->showseconds_check, TRUE);
2537
gtk_widget_set_sensitive (cd->showdate_check, TRUE);
2538
gtk_widget_set_sensitive (cd->gmt_time_check, TRUE);
2539
gtk_widget_set_sensitive (cd->custom_entry, FALSE);
2540
gtk_widget_set_sensitive (cd->custom_label, FALSE);
2542
case CLOCK_FORMAT_UNIX:
2543
gtk_widget_set_sensitive (cd->showseconds_check, FALSE);
2544
gtk_widget_set_sensitive (cd->showdate_check, FALSE);
2545
gtk_widget_set_sensitive (cd->gmt_time_check, FALSE);
2546
gtk_widget_set_sensitive (cd->custom_entry, FALSE);
2547
gtk_widget_set_sensitive (cd->custom_label, FALSE);
2549
case CLOCK_FORMAT_INTERNET:
2550
gtk_widget_set_sensitive (cd->showseconds_check, TRUE);
2551
gtk_widget_set_sensitive (cd->showdate_check, FALSE);
2552
gtk_widget_set_sensitive (cd->gmt_time_check, FALSE);
2553
gtk_widget_set_sensitive (cd->custom_entry, FALSE);
2554
gtk_widget_set_sensitive (cd->custom_label, FALSE);
2556
case CLOCK_FORMAT_CUSTOM:
2557
gtk_widget_set_sensitive (cd->showseconds_check, FALSE);
2558
gtk_widget_set_sensitive (cd->showdate_check, FALSE);
2559
gtk_widget_set_sensitive (cd->gmt_time_check, TRUE);
2560
gtk_widget_set_sensitive (cd->custom_entry, TRUE);
2561
gtk_widget_set_sensitive (cd->custom_label, TRUE);
2564
g_assert_not_reached ();
2570
set_format_cb (GtkComboBox *combo,
2575
/* valid values begin from 1 */
2576
if (cd->can_handle_format_12)
2577
format = gtk_combo_box_get_active (combo) + 1;
2579
format = gtk_combo_box_get_active (combo) + 2;
2581
update_properties_for_format (cd, combo, format);
2583
if (cd->format != format)
2584
panel_applet_gconf_set_string (PANEL_APPLET (cd->applet),
2586
gconf_enum_to_string (format_type_enum_map, format),
2591
set_show_seconds_cb (GtkWidget *w,
2594
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2596
GTK_TOGGLE_BUTTON (w)->active,
2601
set_show_date_cb (GtkWidget *w,
2604
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2606
GTK_TOGGLE_BUTTON (w)->active,
2611
set_show_lunardate_cb (GtkWidget *w,
2614
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2616
GTK_TOGGLE_BUTTON (w)->active,
2620
set_gmt_time_cb (GtkWidget *w,
2623
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2625
GTK_TOGGLE_BUTTON (w)->active,
2630
set_custom_format_cb (GtkEntry *entry,
2633
const char *custom_format;
2635
custom_format = gtk_entry_get_text (entry);
2636
panel_applet_gconf_set_string (PANEL_APPLET (cd->applet),
2637
KEY_CUSTOM_FORMAT, custom_format, NULL);
2641
properties_response_cb (GtkWidget *widget,
2646
if (id == GTK_RESPONSE_HELP) {
2647
GError *error = NULL;
2649
gnome_help_display_desktop_on_screen (
2650
NULL, "clock", "clock", "clock-settings",
2651
gtk_widget_get_screen (cd->applet),
2656
dialog = gtk_message_dialog_new (GTK_WINDOW (widget),
2657
GTK_DIALOG_DESTROY_WITH_PARENT,
2660
_("There was an error displaying help: %s"),
2663
g_signal_connect (G_OBJECT (dialog), "response",
2664
G_CALLBACK (gtk_widget_destroy),
2667
gtk_window_set_icon_name (GTK_WINDOW (dialog),
2669
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
2670
gtk_window_set_screen (GTK_WINDOW (dialog),
2671
gtk_widget_get_screen (cd->applet));
2672
gtk_widget_show (dialog);
2673
g_error_free (error);
2676
gtk_widget_destroy (widget);
2681
display_properties_dialog (BonoboUIComponent *uic,
2683
const gchar *verbname)
2691
gtk_window_set_screen (GTK_WINDOW (cd->props),
2692
gtk_widget_get_screen (cd->applet));
2693
gtk_window_present (GTK_WINDOW (cd->props));
2697
cd->props = gtk_dialog_new_with_buttons (_("Lunar Preferences"), NULL, 0,
2704
gtk_window_set_icon_name (GTK_WINDOW (cd->props), CLOCK_ICON);
2705
gtk_dialog_set_has_separator (GTK_DIALOG (cd->props), FALSE);
2706
gtk_dialog_set_default_response (GTK_DIALOG (cd->props), GTK_RESPONSE_CLOSE);
2707
gtk_window_set_resizable (GTK_WINDOW (cd->props), FALSE);
2708
gtk_window_set_screen (GTK_WINDOW (cd->props),
2709
gtk_widget_get_screen (cd->applet));
2710
gtk_container_set_border_width (GTK_CONTAINER (cd->props), 5);
2711
gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (cd->props)->vbox), 2);
2713
vbox = gtk_vbox_new (FALSE, 6);
2714
gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
2715
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (cd->props)->vbox), vbox, FALSE, FALSE, 0);
2716
gtk_widget_show (vbox);
2718
hbox = gtk_hbox_new (FALSE, 12);
2719
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2720
gtk_widget_show (hbox);
2722
label = gtk_label_new_with_mnemonic (_("Clock _type:"));
2723
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
2724
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2725
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2726
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2727
gtk_widget_show (label);
2729
combo = gtk_combo_box_new_text ();
2730
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
2732
if (cd->can_handle_format_12)
2733
gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("12 hour"));
2734
gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("24 hour"));
2735
gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("UNIX time"));
2736
gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Internet time"));
2738
gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
2739
gtk_widget_show (combo);
2741
cd->custom_hbox = gtk_hbox_new (FALSE, 12);
2742
gtk_box_pack_start (GTK_BOX (vbox), cd->custom_hbox, TRUE, TRUE, 0);
2744
cd->custom_label = gtk_label_new_with_mnemonic (_("Custom _format:"));
2745
gtk_label_set_use_markup (GTK_LABEL (cd->custom_label), TRUE);
2746
gtk_label_set_justify (GTK_LABEL (cd->custom_label),
2748
gtk_misc_set_alignment (GTK_MISC (cd->custom_label), 0, 0.5);
2749
gtk_box_pack_start (GTK_BOX (cd->custom_hbox),
2753
cd->custom_entry = gtk_entry_new ();
2754
gtk_box_pack_start (GTK_BOX (cd->custom_hbox),
2757
gtk_entry_set_text (GTK_ENTRY (cd->custom_entry),
2759
g_signal_connect (cd->custom_entry, "changed",
2760
G_CALLBACK (set_custom_format_cb),
2763
cd->showseconds_check = gtk_check_button_new_with_mnemonic (_("Show _seconds"));
2764
gtk_box_pack_start (GTK_BOX (vbox), cd->showseconds_check, FALSE, FALSE, 0);
2765
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->showseconds_check),
2767
g_signal_connect (cd->showseconds_check, "toggled",
2768
G_CALLBACK (set_show_seconds_cb),
2770
gtk_widget_show (cd->showseconds_check);
2772
cd->showdate_check = gtk_check_button_new_with_mnemonic (_("Show _date"));
2773
gtk_box_pack_start (GTK_BOX (vbox), cd->showdate_check, FALSE, FALSE, 0);
2774
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->showdate_check),
2776
g_signal_connect (cd->showdate_check, "toggled",
2777
G_CALLBACK (set_show_date_cb),
2779
gtk_widget_show (cd->showdate_check);
2782
cd->showlunardate_check = gtk_check_button_new_with_mnemonic (_("Show _lunar date"));
2783
gtk_box_pack_start (GTK_BOX (vbox), cd->showlunardate_check, FALSE, FALSE, 0);
2784
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->showlunardate_check),
2786
g_signal_connect (cd->showlunardate_check, "toggled",
2787
G_CALLBACK (set_show_lunardate_cb),
2789
gtk_widget_show (cd->showlunardate_check);
2791
cd->gmt_time_check = gtk_check_button_new_with_mnemonic (_("Use _UTC"));
2792
gtk_box_pack_start (GTK_BOX (vbox), cd->gmt_time_check, FALSE, FALSE, 0);
2793
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->gmt_time_check),
2795
g_signal_connect (cd->gmt_time_check, "toggled",
2796
G_CALLBACK (set_gmt_time_cb),
2798
gtk_widget_show (cd->gmt_time_check);
2800
g_signal_connect (cd->props, "destroy",
2801
G_CALLBACK (gtk_widget_destroyed),
2803
g_signal_connect (cd->props, "response",
2804
G_CALLBACK (properties_response_cb),
2807
update_properties_for_format (cd, GTK_COMBO_BOX (combo), cd->format);
2809
/* valid values begin from 1 */
2810
if (cd->can_handle_format_12)
2811
gtk_combo_box_set_active (GTK_COMBO_BOX (combo),
2814
gtk_combo_box_set_active (GTK_COMBO_BOX (combo),
2817
g_signal_connect (combo, "changed",
2818
G_CALLBACK (set_format_cb), cd);
2820
/* Now set up the sensitivity based on gconf key writability */
2821
setup_writability_sensitivity (cd, combo, label, KEY_FORMAT);
2822
setup_writability_sensitivity (cd, cd->custom_entry, cd->custom_label,
2824
setup_writability_sensitivity (cd, cd->showseconds_check, NULL, KEY_SHOW_SECONDS);
2825
setup_writability_sensitivity (cd, cd->showdate_check, NULL, KEY_SHOW_DATE);
2826
setup_writability_sensitivity (cd, cd->showlunardate_check, NULL, KEY_SHOW_LUNARDATE);
2827
setup_writability_sensitivity (cd, cd->gmt_time_check, NULL, KEY_GMT_TIME);
2829
gtk_widget_show (cd->props);
2833
display_help_dialog (BonoboUIComponent *uic,
2835
const gchar *verbname)
2837
GError *error = NULL;
2839
gnome_help_display_desktop_on_screen (NULL, "clock", "clock", NULL,
2840
gtk_widget_get_screen (cd->applet),
2844
dialog = gtk_message_dialog_new (NULL,
2848
_("There was an error displaying help: %s"),
2851
g_signal_connect (G_OBJECT (dialog), "response",
2852
G_CALLBACK (gtk_widget_destroy),
2855
gtk_window_set_icon_name (GTK_WINDOW (dialog), CLOCK_ICON);
2856
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
2857
gtk_window_set_screen (GTK_WINDOW (dialog),
2858
gtk_widget_get_screen (cd->applet));
2859
gtk_widget_show (dialog);
2860
g_error_free (error);
2865
display_about_dialog (BonoboUIComponent *uic,
2867
const gchar *verbname)
2869
static const gchar *authors[] =
2871
"yetist <yetist@gmail.com>",
2872
"George Lebl <jirka@5z.com>",
2873
"Gediminas Paulauskas <menesis@delfi.lt>",
2876
static const char *documenters[] =
2878
"Dan Mueth <d-mueth@uchicago.edu>",
2883
gtk_window_set_screen (GTK_WINDOW (cd->about),
2884
gtk_widget_get_screen (cd->applet));
2885
gtk_window_present (GTK_WINDOW (cd->about));
2889
cd->about = gtk_about_dialog_new ();
2890
g_object_set (cd->about,
2893
"copyright", "Copyright \xc2\xa9 1998-2004 Free Software Foundation, Inc.",
2894
"comments", _("The Lunar displays the current time and lunar date"),
2896
"documenters", documenters,
2897
"translator-credits", _("translator-credits"),
2898
"logo-icon-name", CLOCK_ICON,
2901
gtk_window_set_icon_name (GTK_WINDOW (cd->about), CLOCK_ICON);
2902
gtk_window_set_wmclass (GTK_WINDOW (cd->about), "clock", "Clock");
2903
gtk_window_set_screen (GTK_WINDOW (cd->about),
2904
gtk_widget_get_screen (cd->applet));
2906
g_signal_connect (G_OBJECT(cd->about), "destroy",
2907
(GCallback)gtk_widget_destroyed, &cd->about);
2909
g_signal_connect (cd->about, "response",
2910
G_CALLBACK (gtk_widget_destroy),
2913
gtk_widget_show (cd->about);
2917
clock_factory (PanelApplet *applet,
2921
gboolean retval = FALSE;
2923
if (!strcmp (iid, "OAFIID:GNOME_LunarApplet"))
2924
retval = fill_clock_applet (applet);
2929
#ifdef CLOCK_INPROCESS
2930
PANEL_APPLET_BONOBO_SHLIB_FACTORY ("OAFIID:GNOME_LunarApplet_Factory",
2936
PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_LunarApplet_Factory",