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
44
#include <panel-applet.h>
45
#include <panel-applet-gconf.h>
47
#include <glib/gi18n.h>
48
#include <gio/gdesktopappinfo.h>
51
#include <gdk/gdkkeysyms.h>
53
#include <gconf/gconf-client.h>
55
#include <libgweather/gweather-prefs.h>
56
#include <libgweather/gweather-xml.h>
57
#include <libgweather/location-entry.h>
58
#include <libgweather/timezone-menu.h>
61
#include <libedataserverui/e-passwords.h>
66
#include "calendar-window.h"
67
#include "clock-location.h"
68
#include "clock-location-tile.h"
69
#include "clock-map.h"
70
#include "clock-utils.h"
71
#include "system-timezone.h"
73
#define INTERNETSECOND (864)
74
#define INTERNETBEAT (86400)
76
#define NEVER_SENSITIVE "never_sensitive"
78
#define N_GCONF_PREFS 11 /* Keep this in sync with the number of keys below! */
79
#define KEY_FORMAT "format"
80
#define KEY_SHOW_SECONDS "show_seconds"
81
#define KEY_SHOW_DATE "show_date"
82
#define KEY_SHOW_WEATHER "show_weather"
83
#define KEY_SHOW_TEMPERATURE "show_temperature"
84
#define KEY_CUSTOM_FORMAT "custom_format"
85
#define KEY_SHOW_WEEK "show_week_numbers"
86
#define KEY_CITIES "cities"
87
#define KEY_TEMPERATURE_UNIT "temperature_unit"
88
#define KEY_SPEED_UNIT "speed_unit"
90
static GConfEnumStringPair format_type_enum_map [] = {
91
{ CLOCK_FORMAT_12, "12-hour" },
92
{ CLOCK_FORMAT_24, "24-hour" },
93
{ CLOCK_FORMAT_UNIX, "unix" },
94
{ CLOCK_FORMAT_INTERNET, "internet" },
95
{ CLOCK_FORMAT_CUSTOM, "custom" },
106
typedef struct _ClockData ClockData;
112
GtkWidget *panel_button; /* main toggle button for the whole clock */
114
GtkWidget *main_obox; /* orientable box inside panel_button */
115
GtkWidget *weather_obox; /* orientable box for the weather widgets */
117
GtkWidget *clockw; /* main label for the date/time display */
119
GtkWidget *panel_weather_icon;
120
GtkWidget *panel_temperature_label;
123
GtkWidget *calendar_popup;
125
GtkWidget *clock_vbox;
126
GtkSizeGroup *clock_group;
130
/* Preferences dialog */
131
GtkWidget *prefs_window;
132
GtkTreeView *prefs_locations;
134
GtkWidget *prefs_location_add_button;
135
GtkWidget *prefs_location_edit_button;
136
GtkWidget *prefs_location_remove_button;
138
GWeatherLocationEntry *location_entry;
139
GWeatherTimezoneMenu *zone_combo;
141
GtkWidget *time_settings_button;
142
GAppInfo *datetime_appinfo;
144
GtkListStore *cities_store;
145
GtkWidget *cities_section;
146
GtkWidget *map_section;
147
GtkWidget *map_widget;
152
gboolean showseconds;
155
gboolean show_weather;
156
gboolean show_temperature;
158
gboolean use_temperature_default;
159
gboolean use_speed_default;
160
TempUnit temperature_unit;
161
SpeedUnit speed_unit;
165
GList *location_tiles;
171
PanelAppletOrient orient;
173
GtkAllocation old_allocation;
175
SystemTimezone *systz;
180
GtkWidget *showseconds_check;
181
GtkWidget *showdate_check;
182
GtkWidget *custom_hbox;
183
GtkWidget *custom_label;
184
GtkWidget *custom_entry;
185
gboolean custom_format_shown;
187
gboolean can_handle_format_12;
189
guint listeners [N_GCONF_PREFS];
192
/* Used to count the number of clock instances. It's there to know when we
193
* should free resources that are shared. */
194
static int clock_numbers = 0;
196
static void update_clock (ClockData * cd);
197
static void update_tooltip (ClockData * cd);
198
static void update_panel_weather (ClockData *cd);
199
static int clock_timeout_callback (gpointer data);
200
static float get_itime (time_t current_time);
202
static void set_atk_name_description (GtkWidget *widget,
205
static void verb_display_properties_dialog (GtkAction *action,
208
static void display_properties_dialog (ClockData *cd,
209
gboolean start_in_locations_page);
210
static void position_calendar_popup (ClockData *cd);
211
static void update_orient (ClockData *cd);
212
static void applet_change_orient (PanelApplet *applet,
213
PanelAppletOrient orient,
216
static void edit_hide (GtkWidget *unused, ClockData *cd);
217
static gboolean edit_delete (GtkWidget *unused, GdkEvent *event, ClockData *cd);
218
static void save_cities_store (ClockData *cd);
220
/* ClockBox, an instantiable GtkBox */
222
typedef GtkBox ClockBox;
223
typedef GtkBoxClass ClockBoxClass;
225
static GType clock_box_get_type (void);
227
G_DEFINE_TYPE (ClockBox, clock_box, GTK_TYPE_BOX)
230
clock_box_init (ClockBox *box)
235
clock_box_class_init (ClockBoxClass *klass)
241
static inline GtkWidget *
242
_clock_get_widget (ClockData *cd,
245
return GTK_WIDGET (gtk_builder_get_object (cd->builder, name));
249
unfix_size (ClockData *cd)
251
cd->fixed_width = -1;
252
cd->fixed_height = -1;
253
gtk_widget_queue_resize (cd->panel_button);
257
calculate_minimum_width (GtkWidget *widget,
260
PangoContext *pango_context;
265
GtkStyleContext *style_context;
269
pango_context = gtk_widget_get_pango_context (widget);
271
layout = pango_layout_new (pango_context);
272
pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
273
pango_layout_set_text (layout, text, -1);
274
pango_layout_get_pixel_size (layout, &width, &height);
275
g_object_unref (G_OBJECT (layout));
278
state = gtk_widget_get_state_flags (widget);
279
style_context = gtk_widget_get_style_context (widget);
280
gtk_style_context_get_padding (style_context, state, &padding);
281
gtk_style_context_get_style (style_context,
282
"focus-line-width", &focus_width,
283
"focus-padding", &focus_pad,
286
width += 2 * (focus_width + focus_pad) + padding.left + padding.right;
292
clock_set_timeout (ClockData *cd,
297
if (cd->format == CLOCK_FORMAT_INTERNET) {
300
itime_ms = ((unsigned int) (get_itime (now) * 1000));
302
if (!cd->showseconds)
303
timeouttime = (999 - itime_ms % 1000) * 86.4 + 1;
306
gettimeofday (&tv, NULL);
307
itime_ms += (tv.tv_usec * 86.4) / 1000;
308
timeouttime = ((999 - itime_ms % 1000) * 86.4) / 100 + 1;
314
gettimeofday (&tv, NULL);
315
/* We can't expect the timer resolution to be < 10ms, so add
316
* 15ms to make sure we're fine; see
317
* https://bugzilla.gnome.org/show_bug.cgi?id=585668 */
318
timeouttime = (G_USEC_PER_SEC - tv.tv_usec)/1000+15;
320
/* timeout of one minute if we don't care about the seconds */
321
if (cd->format != CLOCK_FORMAT_UNIX &&
323
/* we use localtime() to handle leap seconds, see
324
* https://bugzilla.gnome.org/show_bug.cgi?id=604317 */
325
tm = localtime (&now);
327
timeouttime += 1000 * (59 - tm->tm_sec);
331
cd->timeout = g_timeout_add (timeouttime,
332
clock_timeout_callback,
337
clock_timeout_callback (gpointer data)
339
ClockData *cd = data;
344
if (!cd->showseconds &&
345
cd->format != CLOCK_FORMAT_UNIX &&
346
cd->format != CLOCK_FORMAT_CUSTOM) {
347
if (cd->format == CLOCK_FORMAT_INTERNET &&
348
(unsigned int)get_itime (new_time) !=
349
(unsigned int)get_itime (cd->current_time)) {
351
} else if ((cd->format == CLOCK_FORMAT_12 ||
352
cd->format == CLOCK_FORMAT_24) &&
353
new_time / 60 != cd->current_time / 60) {
360
clock_set_timeout (cd, new_time);
366
get_itime (time_t current_time)
372
/* BMT (Biel Mean Time) is GMT+1 */
373
bmt = current_time + 3600;
375
itime = (tm->tm_hour*3600.0 + tm->tm_min*60.0 + tm->tm_sec)/86.4;
380
/* adapted from panel-toplevel.c */
382
calculate_minimum_height (GtkWidget *widget,
383
PanelAppletOrient orientation)
386
GtkStyleContext *style_context;
387
const PangoFontDescription *font_desc;
388
PangoContext *pango_context;
389
PangoFontMetrics *metrics;
397
state = gtk_widget_get_state_flags (widget);
398
style_context = gtk_widget_get_style_context (widget);
399
font_desc = gtk_style_context_get_font (style_context, state);
401
pango_context = gtk_widget_get_pango_context (widget);
402
metrics = pango_context_get_metrics (pango_context,
404
pango_context_get_language (pango_context));
406
ascent = pango_font_metrics_get_ascent (metrics);
407
descent = pango_font_metrics_get_descent (metrics);
409
pango_font_metrics_unref (metrics);
411
gtk_style_context_get_padding (style_context, state, &padding);
412
gtk_style_context_get_style (style_context,
413
"focus-line-width", &focus_width,
414
"focus-padding", &focus_pad,
417
if (orientation == PANEL_APPLET_ORIENT_UP
418
|| orientation == PANEL_APPLET_ORIENT_DOWN) {
419
thickness = padding.top + padding.bottom;
421
thickness = padding.left + padding.right;
424
return PANGO_PIXELS (ascent + descent) + 2 * (focus_width + focus_pad) + thickness;
428
use_two_line_format (ClockData *cd)
430
if (cd->size >= 2 * calculate_minimum_height (cd->panel_button, cd->orient))
437
get_updated_timeformat (ClockData *cd)
439
/* Show date in another line if panel is vertical, or
440
* horizontal but large enough to hold two lines of text
443
const char *time_format;
444
const char *date_format;
447
if (cd->format == CLOCK_FORMAT_12)
448
/* Translators: This is a strftime format string.
449
* It is used to display the time in 12-hours format (eg, like
450
* in the US: 8:10 am). The %p expands to am/pm. */
451
time_format = cd->showseconds ? _("%l:%M:%S %p") : _("%l:%M %p");
453
/* Translators: This is a strftime format string.
454
* It is used to display the time in 24-hours format (eg, like
455
* in France: 20:10). */
456
time_format = cd->showseconds ? _("%H:%M:%S") : _("%H:%M");
459
clock_format = g_strdup (time_format);
462
/* Translators: This is a strftime format string.
463
* It is used to display the date. Replace %e with %d if, when
464
* the day of the month as a decimal number is a single digit,
465
* it should begin with a 0 in your locale (e.g. "May 01"
466
* instead of "May 1"). */
467
date_format = _("%a %b %e");
469
if (use_two_line_format (cd))
470
/* translators: reverse the order of these arguments
471
* if the time should come before the
472
* date on a clock in your locale.
474
clock_format = g_strdup_printf (_("%1$s\n%2$s"),
478
/* translators: reverse the order of these arguments
479
* if the time should come before the
480
* date on a clock in your locale.
482
clock_format = g_strdup_printf (_("%1$s, %2$s"),
487
result = g_locale_from_utf8 (clock_format, -1, NULL, NULL, NULL);
488
g_free (clock_format);
490
/* let's be paranoid */
492
result = g_strdup ("???");
498
update_timeformat (ClockData *cd)
500
g_free (cd->timeformat);
501
cd->timeformat = get_updated_timeformat (cd);
504
/* sets accessible name and description for the widget */
506
set_atk_name_description (GtkWidget *widget,
511
obj = gtk_widget_get_accessible (widget);
513
/* return if gail is not loaded */
514
if (!GTK_IS_ACCESSIBLE (obj))
518
atk_object_set_description (obj, desc);
520
atk_object_set_name (obj, name);
524
update_location_tiles (ClockData *cd)
528
for (l = cd->location_tiles; l; l = l->next) {
529
ClockLocationTile *tile;
531
tile = CLOCK_LOCATION_TILE (l->data);
532
clock_location_tile_refresh (tile, FALSE);
537
format_time (ClockData *cd)
545
tm = localtime (&cd->current_time);
547
if (cd->format == CLOCK_FORMAT_UNIX) {
548
if (use_two_line_format (cd)) {
549
utf8 = g_strdup_printf ("%lu\n%05lu",
550
(unsigned long)(cd->current_time / 100000L),
551
(unsigned long)(cd->current_time % 100000L));
553
utf8 = g_strdup_printf ("%lu",
554
(unsigned long)cd->current_time);
556
} else if (cd->format == CLOCK_FORMAT_INTERNET) {
557
float itime = get_itime (cd->current_time);
559
utf8 = g_strdup_printf ("@%3.2f", itime);
561
utf8 = g_strdup_printf ("@%3d", (unsigned int) itime);
562
} else if (cd->format == CLOCK_FORMAT_CUSTOM) {
563
char *timeformat = g_locale_from_utf8 (cd->custom_format, -1,
566
strcpy (hour, "???");
567
else if (strftime (hour, sizeof (hour), timeformat, tm) <= 0)
568
strcpy (hour, "???");
571
utf8 = g_locale_to_utf8 (hour, -1, NULL, NULL, NULL);
573
if (strftime (hour, sizeof (hour), cd->timeformat, tm) <= 0)
574
strcpy (hour, "???");
576
utf8 = g_locale_to_utf8 (hour, -1, NULL, NULL, NULL);
580
utf8 = g_strdup (hour);
586
format_time_24 (ClockData *cd)
591
tm = localtime (&cd->current_time);
592
strftime (buf, sizeof (buf) - 1, "%k:%M:%S", tm);
593
return g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
597
update_clock (ClockData * cd)
604
time (&cd->current_time);
605
utf8 = format_time (cd);
608
if (pango_parse_markup (utf8, -1, 0, NULL, NULL, NULL, NULL))
612
gtk_label_set_markup (GTK_LABEL (cd->clockw), utf8);
614
gtk_label_set_text (GTK_LABEL (cd->clockw), utf8);
619
gtk_widget_queue_resize (cd->panel_button);
622
update_location_tiles (cd);
624
if (cd->map_widget && cd->calendar_popup && gtk_widget_get_visible (cd->calendar_popup))
625
clock_map_update_time (CLOCK_MAP (cd->map_widget));
629
update_tooltip (ClockData * cd)
640
tm = localtime (&cd->current_time);
644
/* Show date in tooltip. */
645
/* Translators: This is a strftime format string.
646
* It is used to display a date. Please leave "%%s" as it is:
647
* it will be used to insert the timezone name later. */
648
loc = g_locale_from_utf8 (_("%A %B %d (%%s)"), -1, NULL, NULL, NULL);
650
strcpy (date, "???");
651
else if (strftime (date, sizeof (date), loc, tm) <= 0)
652
strcpy (date, "???");
655
utf8 = g_locale_to_utf8 (date, -1, NULL, NULL, NULL);
657
/* Add the timezone name */
661
localtime_r (&now_t, &now);
663
if (now.tm_isdst > 0) {
669
tip = g_strdup_printf (utf8, zone);
671
gtk_widget_set_tooltip_text (cd->panel_button, tip);
676
if (cd->calendar_popup)
677
gtk_widget_set_tooltip_text (cd->panel_button,
678
_("Click to hide your appointments and tasks"));
680
gtk_widget_set_tooltip_text (cd->panel_button,
681
_("Click to view your appointments and tasks"));
683
if (cd->calendar_popup)
684
gtk_widget_set_tooltip_text (cd->panel_button,
685
_("Click to hide month calendar"));
687
gtk_widget_set_tooltip_text (cd->panel_button,
688
_("Click to view month calendar"));
694
refresh_clock (ClockData *cd)
701
refresh_clock_timeout(ClockData *cd)
705
update_timeformat (cd);
708
g_source_remove (cd->timeout);
712
clock_set_timeout (cd, cd->current_time);
716
* This is like refresh_clock_timeout(), except that we only care about whether
717
* the time actually changed. We don't care about the format.
720
refresh_click_timeout_time_only (ClockData *cd)
723
g_source_remove (cd->timeout);
724
clock_timeout_callback (cd);
728
free_locations (ClockData *cd)
732
for (l = cd->locations; l; l = l->next)
733
g_object_unref (l->data);
735
g_list_free (cd->locations);
736
cd->locations = NULL;
740
destroy_clock (GtkWidget * widget, ClockData *cd)
745
client = gconf_client_get_default ();
747
for (i = 0; i < N_GCONF_PREFS; i++)
748
gconf_client_notify_remove (
749
client, cd->listeners [i]);
751
g_object_unref (G_OBJECT (client));
754
g_source_remove (cd->timeout);
758
gtk_widget_destroy (cd->props);
761
if (cd->calendar_popup)
762
gtk_widget_destroy (cd->calendar_popup);
763
cd->calendar_popup = NULL;
765
if (cd->datetime_appinfo)
766
g_object_unref (cd->datetime_appinfo);
767
cd->datetime_appinfo = NULL;
769
g_free (cd->timeformat);
770
g_free (cd->custom_format);
774
g_list_free (cd->location_tiles);
775
cd->location_tiles = NULL;
778
g_object_unref (cd->systz);
782
if (cd->cities_store) {
783
g_object_unref (cd->cities_store);
784
cd->cities_store = NULL;
788
g_object_unref (cd->builder);
795
if (clock_numbers > 0) {
796
e_passwords_shutdown ();
803
close_on_escape (GtkWidget *widget,
805
GtkToggleButton *toggle_button)
807
if (event->keyval == GDK_KEY_Escape) {
808
gtk_toggle_button_set_active (toggle_button, FALSE);
816
delete_event (GtkWidget *widget,
818
GtkToggleButton *toggle_button)
820
gtk_toggle_button_set_active (toggle_button, FALSE);
825
edit_locations_cb (CalendarWindow *calwin, gpointer data)
831
display_properties_dialog (cd, TRUE);
835
create_calendar (ClockData *cd)
840
prefs_dir = panel_applet_get_preferences_key (PANEL_APPLET (cd->applet));
841
window = calendar_window_new (&cd->current_time,
843
cd->orient == PANEL_APPLET_ORIENT_UP);
846
g_object_bind_property (cd->applet, "locked-down",
847
window, "locked-down",
848
G_BINDING_DEFAULT|G_BINDING_SYNC_CREATE);
850
calendar_window_set_show_weeks (CALENDAR_WINDOW (window),
852
calendar_window_set_time_format (CALENDAR_WINDOW (window),
855
gtk_window_set_screen (GTK_WINDOW (window),
856
gtk_widget_get_screen (cd->applet));
858
g_signal_connect (window, "edit-locations",
859
G_CALLBACK (edit_locations_cb), cd);
861
g_signal_connect (window, "delete_event",
862
G_CALLBACK (delete_event), cd->panel_button);
863
g_signal_connect (window, "key_press_event",
864
G_CALLBACK (close_on_escape), cd->panel_button);
870
position_calendar_popup (ClockData *cd)
873
GtkAllocation allocation;
875
GdkRectangle monitor;
876
GdkGravity gravity = GDK_GRAVITY_NORTH_WEST;
877
int button_w, button_h;
881
gboolean found_monitor = FALSE;
883
/* Get root origin of the toggle button, and position above that. */
884
gdk_window_get_origin (gtk_widget_get_window (cd->panel_button),
887
gtk_window_get_size (GTK_WINDOW (cd->calendar_popup), &w, &h);
888
gtk_widget_get_preferred_size (cd->calendar_popup, &req, NULL);
892
gtk_widget_get_allocation (cd->panel_button, &allocation);
893
button_w = allocation.width;
894
button_h = allocation.height;
896
screen = gtk_window_get_screen (GTK_WINDOW (cd->calendar_popup));
898
n = gdk_screen_get_n_monitors (screen);
899
for (i = 0; i < n; i++) {
900
gdk_screen_get_monitor_geometry (screen, i, &monitor);
901
if (x >= monitor.x && x <= monitor.x + monitor.width &&
902
y >= monitor.y && y <= monitor.y + monitor.height) {
903
found_monitor = TRUE;
908
if (!found_monitor) {
909
/* eek, we should be on one of those xinerama
913
monitor.width = gdk_screen_get_width (screen);
914
monitor.height = gdk_screen_get_height (screen);
917
/* Based on panel orientation, position the popup.
918
* Ignore window gravity since the window is undecorated.
919
* The orientations are all named backward from what
922
switch (cd->orient) {
923
case PANEL_APPLET_ORIENT_RIGHT:
925
if ((y + h) > monitor.y + monitor.height)
926
y -= (y + h) - (monitor.y + monitor.height);
928
if ((y + h) > (monitor.height / 2))
929
gravity = GDK_GRAVITY_SOUTH_WEST;
931
gravity = GDK_GRAVITY_NORTH_WEST;
934
case PANEL_APPLET_ORIENT_LEFT:
936
if ((y + h) > monitor.y + monitor.height)
937
y -= (y + h) - (monitor.y + monitor.height);
939
if ((y + h) > (monitor.height / 2))
940
gravity = GDK_GRAVITY_SOUTH_EAST;
942
gravity = GDK_GRAVITY_NORTH_EAST;
945
case PANEL_APPLET_ORIENT_DOWN:
947
if ((x + w) > monitor.x + monitor.width)
948
x -= (x + w) - (monitor.x + monitor.width);
950
gravity = GDK_GRAVITY_NORTH_WEST;
953
case PANEL_APPLET_ORIENT_UP:
955
if ((x + w) > monitor.x + monitor.width)
956
x -= (x + w) - (monitor.x + monitor.width);
958
gravity = GDK_GRAVITY_SOUTH_WEST;
963
gtk_window_move (GTK_WINDOW (cd->calendar_popup), x, y);
964
gtk_window_set_gravity (GTK_WINDOW (cd->calendar_popup), gravity);
968
add_to_group (GtkWidget *child, gpointer data)
970
GtkSizeGroup *group = data;
972
gtk_size_group_add_widget (group, child);
976
create_clock_window (ClockData *cd)
978
GtkWidget *locations_box;
980
locations_box = calendar_window_get_locations_box (CALENDAR_WINDOW (cd->calendar_popup));
981
gtk_widget_show (locations_box);
983
cd->clock_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
984
gtk_container_add (GTK_CONTAINER (locations_box), cd->clock_vbox);
986
cd->clock_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
987
gtk_size_group_set_ignore_hidden (cd->clock_group, FALSE);
989
gtk_container_foreach (GTK_CONTAINER (locations_box),
990
(GtkCallback) add_to_group,
995
sort_locations_by_name (gconstpointer a, gconstpointer b)
997
ClockLocation *loc_a = (ClockLocation *) a;
998
ClockLocation *loc_b = (ClockLocation *) b;
1000
const char *name_a = clock_location_get_display_name (loc_a);
1001
const char *name_b = clock_location_get_display_name (loc_b);
1003
return strcmp (name_a, name_b);
1007
create_cities_store (ClockData *cd)
1010
GList *cities = cd->locations;
1013
if (cd->cities_store) {
1014
g_object_unref (G_OBJECT (cd->cities_store));
1015
cd->cities_store = NULL;
1018
/* City name, Timezone name, Coordinates in lat/long */
1019
cd->cities_store = g_object_ref (gtk_list_store_new (COL_CITY_LAST,
1020
G_TYPE_STRING, /* COL_CITY_NAME */
1021
G_TYPE_STRING, /* COL_CITY_TZ */
1022
CLOCK_LOCATION_TYPE)); /* COL_CITY_LOC */
1024
list = g_list_copy (cities);
1025
list = g_list_sort (list, sort_locations_by_name);
1028
ClockLocation *loc = CLOCK_LOCATION (list->data);
1030
gtk_list_store_append (cd->cities_store, &iter);
1031
gtk_list_store_set (cd->cities_store, &iter,
1032
COL_CITY_NAME, clock_location_get_display_name (loc),
1033
/* FIXME: translate the timezone */
1034
COL_CITY_TZ, clock_location_get_timezone (loc),
1042
if (cd->prefs_window) {
1043
GtkWidget *widget = _clock_get_widget (cd, "cities_list");
1044
gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
1045
GTK_TREE_MODEL (cd->cities_store));
1050
sort_locations_by_time (gconstpointer a, gconstpointer b)
1052
ClockLocation *loc_a = (ClockLocation *) a;
1053
ClockLocation *loc_b = (ClockLocation *) b;
1059
clock_location_localtime (loc_a, &tm_a);
1060
clock_location_localtime (loc_b, &tm_b);
1062
ret = (tm_a.tm_year == tm_b.tm_year) ? 0 : 1;
1064
return (tm_a.tm_year < tm_b.tm_year) ? -1 : 1;
1067
ret = (tm_a.tm_mon == tm_b.tm_mon) ? 0 : 1;
1069
return (tm_a.tm_mon < tm_b.tm_mon) ? -1 : 1;
1072
ret = (tm_a.tm_mday == tm_b.tm_mday) ? 0 : 1;
1074
return (tm_a.tm_mday < tm_b.tm_mday) ? -1 : 1;
1077
ret = (tm_a.tm_hour == tm_b.tm_hour) ? 0 : 1;
1079
return (tm_a.tm_hour < tm_b.tm_hour) ? -1 : 1;
1082
ret = (tm_a.tm_min == tm_b.tm_min) ? 0 : 1;
1084
return (tm_a.tm_min < tm_b.tm_min) ? -1 : 1;
1087
ret = (tm_a.tm_sec == tm_b.tm_sec) ? 0 : 1;
1089
return (tm_a.tm_sec < tm_b.tm_sec) ? -1 : 1;
1096
location_tile_pressed_cb (ClockLocationTile *tile, gpointer data)
1098
ClockData *cd = data;
1101
loc = clock_location_tile_get_location (tile);
1103
clock_map_blink_location (CLOCK_MAP (cd->map_widget), loc);
1105
g_object_unref (loc);
1109
location_tile_need_clock_format_cb(ClockLocationTile *tile, gpointer data)
1111
ClockData *cd = data;
1117
create_cities_section (ClockData *cd)
1120
ClockLocationTile *city;
1123
if (cd->cities_section) {
1124
gtk_widget_destroy (cd->cities_section);
1125
cd->cities_section = NULL;
1128
g_list_free (cd->location_tiles);
1129
cd->location_tiles = NULL;
1131
cd->cities_section = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1132
gtk_container_set_border_width (GTK_CONTAINER (cd->cities_section), 0);
1134
cities = cd->locations;
1135
if (g_list_length (cities) == 0) {
1136
/* if the list is empty, don't bother showing the
1138
gtk_widget_hide (cd->cities_section);
1142
/* Copy the existing list, so we can sort it nondestructively */
1143
node = g_list_copy (cities);
1144
node = g_list_sort (node, sort_locations_by_time);
1145
node = g_list_reverse (node);
1148
ClockLocation *loc = node->data;
1150
city = clock_location_tile_new (loc, CLOCK_FACE_SMALL);
1151
g_signal_connect (city, "tile-pressed",
1152
G_CALLBACK (location_tile_pressed_cb), cd);
1153
g_signal_connect (city, "need-clock-format",
1154
G_CALLBACK (location_tile_need_clock_format_cb), cd);
1156
gtk_box_pack_start (GTK_BOX (cd->cities_section),
1160
cd->location_tiles = g_list_prepend (cd->location_tiles, city);
1162
clock_location_tile_refresh (city, TRUE);
1164
node = g_list_next (node);
1169
gtk_box_pack_end (GTK_BOX (cd->clock_vbox),
1170
cd->cities_section, FALSE, FALSE, 0);
1172
gtk_widget_show_all (cd->cities_section);
1176
map_need_locations_cb (ClockMap *map, gpointer data)
1178
ClockData *cd = data;
1180
return cd->locations;
1184
create_map_section (ClockData *cd)
1188
if (cd->map_widget) {
1189
gtk_widget_destroy (GTK_WIDGET (cd->map_section));
1190
cd->map_widget = NULL;
1193
map = clock_map_new ();
1194
g_signal_connect (map, "need-locations",
1195
G_CALLBACK (map_need_locations_cb), cd);
1197
cd->map_section = gtk_alignment_new (0, 0, 1, 1);
1198
cd->map_widget = GTK_WIDGET (map);
1200
gtk_container_add (GTK_CONTAINER (cd->map_section), cd->map_widget);
1202
gtk_alignment_set_padding (GTK_ALIGNMENT (cd->map_section), 1, 1, 1, 1);
1204
gtk_box_pack_start (GTK_BOX (cd->clock_vbox), cd->map_section, FALSE, FALSE, 0);
1205
gtk_widget_show (cd->map_widget);
1206
gtk_widget_show (cd->map_section);
1210
update_calendar_popup (ClockData *cd)
1212
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cd->panel_button))) {
1213
if (cd->calendar_popup) {
1214
gtk_widget_destroy (cd->calendar_popup);
1215
cd->calendar_popup = NULL;
1216
cd->cities_section = NULL;
1217
cd->map_section = NULL;
1218
cd->map_widget = NULL;
1219
cd->clock_vbox = NULL;
1221
g_list_free (cd->location_tiles);
1222
cd->location_tiles = NULL;
1224
update_tooltip (cd);
1228
if (!cd->calendar_popup) {
1229
cd->calendar_popup = create_calendar (cd);
1230
g_object_add_weak_pointer (G_OBJECT (cd->calendar_popup),
1231
(gpointer *) &cd->calendar_popup);
1232
update_tooltip (cd);
1234
create_clock_window (cd);
1235
create_cities_store (cd);
1236
create_cities_section (cd);
1237
create_map_section (cd);
1240
if (cd->calendar_popup && gtk_widget_get_realized (cd->panel_button)) {
1241
calendar_window_refresh (CALENDAR_WINDOW (cd->calendar_popup));
1242
position_calendar_popup (cd);
1243
gtk_window_present (GTK_WINDOW (cd->calendar_popup));
1248
toggle_calendar (GtkWidget *button,
1251
/* if time is wrong, the user might try to fix it by clicking on the
1253
refresh_click_timeout_time_only (cd);
1254
update_calendar_popup (cd);
1258
do_not_eat_button_press (GtkWidget *widget,
1259
GdkEventButton *event)
1261
if (event->button != 1)
1262
g_signal_stop_emission_by_name (widget, "button_press_event");
1267
/* Don't request smaller size then the last one we did, this avoids
1268
jumping when proportional fonts are used. We must take care to
1269
call "unfix_size" whenever options are changed or such where
1270
we'd want to forget the fixed size */
1272
clock_size_request (GtkWidget *clock, GtkRequisition *req, gpointer data)
1274
ClockData *cd = data;
1276
if (req->width > cd->fixed_width)
1277
cd->fixed_width = req->width;
1278
if (req->height > cd->fixed_height)
1279
cd->fixed_height = req->height;
1280
req->width = cd->fixed_width;
1281
req->height = cd->fixed_height;
1285
clock_update_text_gravity (GtkWidget *label)
1287
PangoLayout *layout;
1288
PangoContext *context;
1290
layout = gtk_label_get_layout (GTK_LABEL (label));
1291
context = pango_layout_get_context (layout);
1292
pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO);
1296
force_no_focus_padding (GtkWidget *widget)
1298
static gboolean first_time = TRUE;
1299
GtkCssProvider *provider;
1302
provider = gtk_css_provider_new ();
1303
gtk_css_provider_load_from_data (provider,
1304
"#clock-applet-button {\n"
1305
" -GtkWidget-focus-line-width: 0px;\n"
1306
" -GtkWidget-focus-padding: 0px;\n"
1309
gtk_style_context_add_provider (gtk_widget_get_style_context (widget),
1310
GTK_STYLE_PROVIDER (provider),
1311
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1312
g_object_unref (provider);
1317
gtk_widget_set_name (widget, "clock-applet-button");
1321
create_main_clock_button (void)
1325
button = gtk_toggle_button_new ();
1326
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
1328
force_no_focus_padding (button);
1334
create_main_clock_label (ClockData *cd)
1338
label = gtk_label_new (NULL);
1339
g_signal_connect (label, "size_request",
1340
G_CALLBACK (clock_size_request),
1342
g_signal_connect_swapped (label, "style_set",
1343
G_CALLBACK (unfix_size),
1345
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
1346
clock_update_text_gravity (label);
1347
g_signal_connect (label, "screen-changed",
1348
G_CALLBACK (clock_update_text_gravity),
1355
weather_tooltip (GtkWidget *widget,
1358
gboolean keyboard_mode,
1359
GtkTooltip *tooltip,
1362
GList *locations, *l;
1365
locations = cd->locations;
1367
for (l = locations; l; l = l->next) {
1368
ClockLocation *location = l->data;
1369
if (clock_location_is_current (location)) {
1370
info = clock_location_get_weather_info (location);
1371
if (!info || !weather_info_is_valid (info))
1374
weather_info_setup_tooltip (info, location, tooltip, cd->format);
1384
create_clock_widget (ClockData *cd)
1388
e_passwords_init ();
1391
/* Main toggle button */
1392
cd->panel_button = create_main_clock_button ();
1393
g_signal_connect (cd->panel_button, "button_press_event",
1394
G_CALLBACK (do_not_eat_button_press), NULL);
1395
g_signal_connect (cd->panel_button, "toggled",
1396
G_CALLBACK (toggle_calendar), cd);
1397
g_signal_connect (G_OBJECT (cd->panel_button), "destroy",
1398
G_CALLBACK (destroy_clock),
1400
gtk_widget_show (cd->panel_button);
1402
/* Main orientable box */
1403
cd->main_obox = g_object_new (clock_box_get_type (), NULL);
1404
gtk_box_set_spacing (GTK_BOX (cd->main_obox), 12); /* spacing between weather and time */
1405
gtk_container_add (GTK_CONTAINER (cd->panel_button), cd->main_obox);
1406
gtk_widget_show (cd->main_obox);
1408
/* Weather orientable box */
1409
cd->weather_obox = g_object_new (clock_box_get_type (), NULL);
1410
gtk_box_set_spacing (GTK_BOX (cd->weather_obox), 2); /* spacing between weather icon and temperature */
1411
gtk_box_pack_start (GTK_BOX (cd->main_obox), cd->weather_obox, FALSE, FALSE, 0);
1412
gtk_widget_set_has_tooltip (cd->weather_obox, TRUE);
1413
g_signal_connect (cd->weather_obox, "query-tooltip",
1414
G_CALLBACK (weather_tooltip), cd);
1416
/* Weather widgets */
1417
cd->panel_weather_icon = gtk_image_new ();
1418
gtk_box_pack_start (GTK_BOX (cd->weather_obox), cd->panel_weather_icon, FALSE, FALSE, 0);
1420
cd->panel_temperature_label = gtk_label_new (NULL);
1421
gtk_box_pack_start (GTK_BOX (cd->weather_obox), cd->panel_temperature_label, FALSE, FALSE, 0);
1423
/* Main label for time display */
1424
cd->clockw = create_main_clock_label (cd);
1425
gtk_box_pack_start (GTK_BOX (cd->main_obox), cd->clockw, FALSE, FALSE, 0);
1426
gtk_widget_show (cd->clockw);
1430
set_atk_name_description (GTK_WIDGET (cd->applet), NULL,
1431
_("Computer Clock"));
1433
gtk_container_add (GTK_CONTAINER (cd->applet), cd->panel_button);
1434
gtk_container_set_border_width (GTK_CONTAINER (cd->applet), 0);
1438
cd->size = panel_applet_get_size (PANEL_APPLET (cd->applet));
1440
update_panel_weather (cd);
1442
/* Refresh the clock so that it paints its first state */
1443
refresh_clock_timeout (cd);
1444
applet_change_orient (PANEL_APPLET (cd->applet),
1445
panel_applet_get_orient (PANEL_APPLET (cd->applet)),
1450
update_orient (ClockData *cd)
1454
GtkAllocation allocation;
1458
text = gtk_label_get_text (GTK_LABEL (cd->clockw));
1459
min_width = calculate_minimum_width (cd->panel_button, text);
1460
gtk_widget_get_allocation (cd->panel_button, &allocation);
1462
if (cd->orient == PANEL_APPLET_ORIENT_LEFT &&
1463
min_width > allocation.width)
1465
else if (cd->orient == PANEL_APPLET_ORIENT_RIGHT &&
1466
min_width > allocation.width)
1471
angle = gtk_label_get_angle (GTK_LABEL (cd->clockw));
1472
if (angle != new_angle) {
1474
gtk_label_set_angle (GTK_LABEL (cd->clockw), new_angle);
1475
gtk_label_set_angle (GTK_LABEL (cd->panel_temperature_label), new_angle);
1479
/* this is when the panel orientation changes */
1481
applet_change_orient (PanelApplet *applet,
1482
PanelAppletOrient orient,
1487
if (orient == cd->orient)
1490
cd->orient = orient;
1492
switch (cd->orient) {
1493
case PANEL_APPLET_ORIENT_RIGHT:
1494
o = GTK_ORIENTATION_VERTICAL;
1496
case PANEL_APPLET_ORIENT_LEFT:
1497
o = GTK_ORIENTATION_VERTICAL;
1499
case PANEL_APPLET_ORIENT_DOWN:
1500
o = GTK_ORIENTATION_HORIZONTAL;
1502
case PANEL_APPLET_ORIENT_UP:
1503
o = GTK_ORIENTATION_HORIZONTAL;
1506
g_assert_not_reached ();
1510
gtk_orientable_set_orientation (GTK_ORIENTABLE (cd->main_obox), o);
1511
gtk_orientable_set_orientation (GTK_ORIENTABLE (cd->weather_obox), o);
1515
update_calendar_popup (cd);
1518
/* this is when the panel size changes */
1520
panel_button_change_pixel_size (GtkWidget *widget,
1521
GtkAllocation *allocation,
1526
if (cd->old_allocation.width == allocation->width &&
1527
cd->old_allocation.height == allocation->height)
1530
cd->old_allocation.width = allocation->width;
1531
cd->old_allocation.height = allocation->height;
1533
if (cd->orient == PANEL_APPLET_ORIENT_LEFT ||
1534
cd->orient == PANEL_APPLET_ORIENT_RIGHT)
1535
new_size = allocation->width;
1537
new_size = allocation->height;
1539
cd->size = new_size;
1542
update_timeformat (cd);
1547
copy_time (GtkAction *action,
1553
if (cd->format == CLOCK_FORMAT_UNIX) {
1554
g_snprintf (string, sizeof(string), "%lu",
1555
(unsigned long)cd->current_time);
1556
} else if (cd->format == CLOCK_FORMAT_INTERNET) {
1557
float itime = get_itime (cd->current_time);
1558
if (cd->showseconds)
1559
g_snprintf (string, sizeof (string), "@%3.2f", itime);
1561
g_snprintf (string, sizeof (string), "@%3d",
1562
(unsigned int) itime);
1567
if (cd->format == CLOCK_FORMAT_CUSTOM) {
1568
format = g_locale_from_utf8 (cd->custom_format, -1,
1570
} else if (cd->format == CLOCK_FORMAT_12) {
1571
if (cd->showseconds)
1572
/* Translators: This is a strftime format
1574
* It is used to display the time in 12-hours
1575
* format with a leading 0 if needed (eg, like
1576
* in the US: 08:10 am). The %p expands to
1578
format = g_locale_from_utf8 (_("%I:%M:%S %p"), -1, NULL, NULL, NULL);
1580
/* Translators: This is a strftime format
1582
* It is used to display the time in 12-hours
1583
* format with a leading 0 if needed (eg, like
1584
* in the US: 08:10 am). The %p expands to
1586
format = g_locale_from_utf8 (_("%I:%M %p"), -1, NULL, NULL, NULL);
1588
if (cd->showseconds)
1589
/* Translators: This is a strftime format
1591
* It is used to display the time in 24-hours
1592
* format (eg, like in France: 20:10). */
1593
format = g_locale_from_utf8 (_("%H:%M:%S"), -1, NULL, NULL, NULL);
1595
/* Translators: This is a strftime format
1597
* It is used to display the time in 24-hours
1598
* format (eg, like in France: 20:10). */
1599
format = g_locale_from_utf8 (_("%H:%M"), -1, NULL, NULL, NULL);
1602
tm = localtime (&cd->current_time);
1605
strcpy (string, "???");
1606
else if (strftime (string, sizeof (string), format, tm) <= 0)
1607
strcpy (string, "???");
1611
utf8 = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
1612
gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
1614
gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1620
copy_date (GtkAction *action,
1627
tm = localtime (&cd->current_time);
1629
/* Translators: This is a strftime format string.
1630
* It is used to display a date in the full format (so that people can
1631
* copy and paste it elsewhere). */
1632
loc = g_locale_from_utf8 (_("%A, %B %d %Y"), -1, NULL, NULL, NULL);
1634
strcpy (string, "???");
1635
else if (strftime (string, sizeof (string), loc, tm) <= 0)
1636
strcpy (string, "???");
1639
utf8 = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
1640
gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
1642
gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1648
ensure_datetime_appinfo (ClockData *cd)
1650
if (!cd->datetime_appinfo)
1651
cd->datetime_appinfo = (GAppInfo *) g_desktop_app_info_new ("gnome-datetime-panel.desktop");
1655
update_set_time_button (ClockData *cd)
1657
if (!cd->time_settings_button)
1660
ensure_datetime_appinfo (cd);
1662
gtk_widget_set_sensitive (cd->time_settings_button,
1663
cd->datetime_appinfo != NULL);
1667
run_time_settings (GtkWidget *unused, ClockData *cd)
1670
GdkDisplay *display;
1671
GdkAppLaunchContext *context;
1674
update_set_time_button (cd);
1675
ensure_datetime_appinfo (cd);
1677
if (!cd->datetime_appinfo)
1680
screen = gtk_widget_get_screen (cd->applet);
1681
display = gdk_screen_get_display (screen);
1682
context = gdk_display_get_app_launch_context (display);
1683
gdk_app_launch_context_set_screen (context, screen);
1686
g_app_info_launch (cd->datetime_appinfo, NULL,
1687
(GAppLaunchContext *) context, &error);
1689
g_object_unref (context);
1694
dialog = gtk_message_dialog_new (NULL,
1698
_("Failed to open the time settings"));
1700
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
1701
g_signal_connect (dialog, "response",
1702
G_CALLBACK (gtk_widget_destroy), NULL);
1703
gtk_window_present (GTK_WINDOW (dialog));
1705
g_error_free (error);
1710
config_date (GtkAction *action,
1713
run_time_settings (NULL, cd);
1716
/* current timestamp */
1717
static const GtkActionEntry clock_menu_actions [] = {
1718
{ "ClockPreferences", GTK_STOCK_PROPERTIES, N_("_Preferences"),
1720
G_CALLBACK (verb_display_properties_dialog) },
1721
{ "ClockCopyTime", GTK_STOCK_COPY, N_("Copy _Time"),
1723
G_CALLBACK (copy_time) },
1724
{ "ClockCopyDate", GTK_STOCK_COPY, N_("Copy _Date"),
1726
G_CALLBACK (copy_date) },
1727
{ "ClockConfig", GTK_STOCK_PREFERENCES, N_("Ad_just Date & Time"),
1729
G_CALLBACK (config_date) }
1733
format_changed (GConfClient *client,
1741
if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
1744
value = gconf_value_get_string (entry->value);
1745
if (!gconf_string_to_enum (format_type_enum_map, value, &new_format))
1748
if (!clock->can_handle_format_12 && new_format == CLOCK_FORMAT_12)
1749
new_format = CLOCK_FORMAT_24;
1751
if (new_format == clock->format)
1754
clock->format = new_format;
1755
refresh_clock_timeout (clock);
1757
if (clock->calendar_popup != NULL) {
1758
calendar_window_set_time_format (CALENDAR_WINDOW (clock->calendar_popup), clock->format);
1759
position_calendar_popup (clock);
1765
show_seconds_changed (GConfClient *client,
1772
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
1775
value = gconf_value_get_bool (entry->value);
1777
clock->showseconds = (value != 0);
1778
refresh_clock_timeout (clock);
1782
show_date_changed (GConfClient *client,
1789
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
1792
value = gconf_value_get_bool (entry->value);
1794
clock->showdate = (value != 0);
1795
update_timeformat (clock);
1796
refresh_clock (clock);
1800
update_panel_weather (ClockData *cd)
1802
if (cd->show_weather)
1803
gtk_widget_show (cd->panel_weather_icon);
1805
gtk_widget_hide (cd->panel_weather_icon);
1807
if (cd->show_temperature)
1808
gtk_widget_show (cd->panel_temperature_label);
1810
gtk_widget_hide (cd->panel_temperature_label);
1812
if ((cd->show_weather || cd->show_temperature) &&
1813
g_list_length (cd->locations) > 0)
1814
gtk_widget_show (cd->weather_obox);
1816
gtk_widget_hide (cd->weather_obox);
1818
gtk_widget_queue_resize (cd->applet);
1822
update_weather_bool_value_and_toggle_from_gconf (ClockData *cd, GConfEntry *entry,
1823
gboolean *value_loc, const char *widget_name)
1828
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
1831
value = gconf_value_get_bool (entry->value);
1833
*value_loc = (value != 0);
1835
widget = _clock_get_widget (cd, widget_name);
1837
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
1840
update_panel_weather (cd);
1844
show_weather_changed (GConfClient *client,
1849
update_weather_bool_value_and_toggle_from_gconf (cd, entry, &cd->show_weather, "weather_check");
1853
show_temperature_changed (GConfClient *client,
1858
update_weather_bool_value_and_toggle_from_gconf (cd, entry, &cd->show_temperature, "temperature_check");
1862
location_weather_updated_cb (ClockLocation *location,
1866
ClockData *cd = data;
1867
const gchar *icon_name;
1869
GtkIconTheme *theme;
1872
if (!info || !weather_info_is_valid (info))
1875
if (!clock_location_is_current (location))
1878
icon_name = weather_info_get_icon_name (info);
1879
/* FIXME: mmh, screen please? Also, don't hardcode to 16 */
1880
theme = gtk_icon_theme_get_default ();
1881
pixbuf = gtk_icon_theme_load_icon (theme, icon_name, 16,
1882
GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL);
1884
temp = weather_info_get_temp_summary (info);
1886
gtk_image_set_from_pixbuf (GTK_IMAGE (cd->panel_weather_icon), pixbuf);
1887
gtk_label_set_text (GTK_LABEL (cd->panel_temperature_label), temp);
1891
location_set_current_cb (ClockLocation *loc,
1894
ClockData *cd = data;
1897
info = clock_location_get_weather_info (loc);
1898
location_weather_updated_cb (loc, info, cd);
1901
clock_map_refresh (CLOCK_MAP (cd->map_widget));
1902
update_location_tiles (cd);
1903
save_cities_store (cd);
1907
locations_changed (ClockData *cd)
1913
if (!cd->locations) {
1914
if (cd->weather_obox)
1915
gtk_widget_hide (cd->weather_obox);
1916
if (cd->panel_weather_icon)
1917
gtk_image_set_from_pixbuf (GTK_IMAGE (cd->panel_weather_icon),
1919
if (cd->panel_temperature_label)
1920
gtk_label_set_text (GTK_LABEL (cd->panel_temperature_label),
1923
if (cd->weather_obox)
1924
gtk_widget_show (cd->weather_obox);
1927
for (l = cd->locations; l; l = l->next) {
1930
id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (loc), "weather-updated"));
1932
id = g_signal_connect (loc, "weather-updated",
1933
G_CALLBACK (location_weather_updated_cb), cd);
1934
g_object_set_data (G_OBJECT (loc), "weather-updated", GINT_TO_POINTER (id));
1935
g_signal_connect (loc, "set-current",
1936
G_CALLBACK (location_set_current_cb), cd);
1941
clock_map_refresh (CLOCK_MAP (cd->map_widget));
1944
create_cities_section (cd);
1949
set_locations (ClockData *cd, GList *locations)
1951
free_locations (cd);
1952
cd->locations = locations;
1953
locations_changed (cd);
1959
} LocationParserData;
1961
/* Parser for our serialized locations in gconf */
1963
location_start_element (GMarkupParseContext *context,
1964
const gchar *element_name,
1965
const gchar **attribute_names,
1966
const gchar **attribute_values,
1971
LocationParserData *data = user_data;
1972
ClockData *cd = data->cd;
1974
const gchar *att_name;
1978
gchar *timezone = NULL;
1979
gfloat latitude = 0.0;
1980
gfloat longitude = 0.0;
1982
gboolean current = FALSE;
1986
prefs.temperature_unit = cd->temperature_unit;
1987
prefs.speed_unit = cd->speed_unit;
1989
if (strcmp (element_name, "location") != 0) {
1993
setlocale (LC_NUMERIC, "POSIX");
1995
for (att_name = attribute_names[index]; att_name != NULL;
1996
att_name = attribute_names[++index]) {
1997
if (strcmp (att_name, "name") == 0) {
1998
name = (gchar *)attribute_values[index];
1999
} else if (strcmp (att_name, "city") == 0) {
2000
city = (gchar *)attribute_values[index];
2001
} else if (strcmp (att_name, "timezone") == 0) {
2002
timezone = (gchar *)attribute_values[index];
2003
} else if (strcmp (att_name, "latitude") == 0) {
2004
sscanf (attribute_values[index], "%f", &latitude);
2005
} else if (strcmp (att_name, "longitude") == 0) {
2006
sscanf (attribute_values[index], "%f", &longitude);
2007
} else if (strcmp (att_name, "code") == 0) {
2008
code = (gchar *)attribute_values[index];
2010
else if (strcmp (att_name, "current") == 0) {
2011
if (strcmp (attribute_values[index], "true") == 0) {
2017
setlocale (LC_NUMERIC, "");
2019
if ((!name && !city) || !timezone) {
2023
/* migration from the old configuration, when name == city */
2027
loc = clock_location_find_and_ref (cd->locations, name, city,
2028
timezone, latitude, longitude, code);
2030
loc = clock_location_new (name, city, timezone,
2031
latitude, longitude, code, &prefs);
2033
if (current && clock_location_is_current_timezone (loc))
2034
clock_location_make_current (loc, NULL, NULL, NULL);
2036
data->cities = g_list_append (data->cities, loc);
2039
static GMarkupParser location_parser = {
2040
location_start_element, NULL, NULL, NULL, NULL
2044
cities_changed (GConfClient *client,
2049
LocationParserData data;
2053
GMarkupParseContext *context;
2058
if (!entry->value || entry->value->type != GCONF_VALUE_LIST)
2061
context = g_markup_parse_context_new (&location_parser, 0, &data, NULL);
2063
cur = gconf_value_get_list (entry->value);
2066
const char *str = gconf_value_get_string (cur->data);
2067
g_markup_parse_context_parse (context, str, strlen (str), NULL);
2072
g_markup_parse_context_free (context);
2074
set_locations (cd, data.cities);
2075
create_cities_store (cd);
2079
update_temperature_combo (ClockData *cd)
2084
widget = _clock_get_widget (cd, "temperature_combo");
2086
if (cd->use_temperature_default)
2089
active_index = cd->temperature_unit - 1;
2091
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active_index);
2095
update_weather_locations (ClockData *cd)
2097
GList *locations, *l;
2098
WeatherPrefs prefs = {
2102
TEMP_UNIT_CENTIGRADE,
2108
prefs.temperature_unit = cd->temperature_unit;
2109
prefs.speed_unit = cd->speed_unit;
2111
locations = cd->locations;
2113
for (l = locations; l; l = l->next) {
2114
clock_location_set_weather_prefs (l->data, &prefs);
2119
clock_migrate_to_26 (ClockData *clock)
2122
gboolean internettime;
2125
internettime = panel_applet_gconf_get_bool (PANEL_APPLET (clock->applet),
2128
unixtime = panel_applet_gconf_get_bool (PANEL_APPLET (clock->applet),
2131
hourformat = panel_applet_gconf_get_int (PANEL_APPLET (clock->applet),
2136
clock->format = CLOCK_FORMAT_UNIX;
2137
else if (internettime)
2138
clock->format = CLOCK_FORMAT_INTERNET;
2139
else if (hourformat == 12)
2140
clock->format = CLOCK_FORMAT_12;
2141
else if (hourformat == 24)
2142
clock->format = CLOCK_FORMAT_24;
2144
/* It's still possible that we have none of the old keys, in which case
2145
* we're not migrating from 2.6, but the config is simply wrong. So
2146
* don't set the format key in this case. */
2147
if (clock->format != CLOCK_FORMAT_INVALID)
2148
panel_applet_gconf_set_string (PANEL_APPLET (clock->applet),
2150
gconf_enum_to_string (format_type_enum_map,
2156
clock_timezone_changed (SystemTimezone *systz,
2160
/* This will refresh the current location */
2161
save_cities_store (cd);
2163
refresh_click_timeout_time_only (cd);
2167
parse_and_set_temperature_string (const char *str, ClockData *cd)
2170
gboolean use_default = FALSE;
2172
value = gweather_prefs_parse_temperature (str, &use_default);
2174
cd->use_temperature_default = use_default;
2175
cd->temperature_unit = value;
2179
parse_and_set_speed_string (const char *str, ClockData *cd)
2182
gboolean use_default = FALSE;
2184
value = gweather_prefs_parse_speed (str, &use_default);
2186
cd->use_speed_default = use_default;
2187
cd->speed_unit = value;
2191
temperature_unit_changed (GConfClient *client,
2198
if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
2201
value = gconf_value_get_string (entry->value);
2202
parse_and_set_temperature_string (value, cd);
2203
update_temperature_combo (cd);
2204
update_weather_locations (cd);
2208
update_speed_combo (ClockData *cd)
2213
widget = _clock_get_widget (cd, "wind_speed_combo");
2215
if (cd->use_speed_default)
2218
active_index = cd->speed_unit - 1;
2220
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active_index);
2224
speed_unit_changed (GConfClient *client,
2231
if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
2234
value = gconf_value_get_string (entry->value);
2235
parse_and_set_speed_string (value, cd);
2236
update_speed_combo (cd);
2237
update_weather_locations (cd);
2241
custom_format_changed (GConfClient *client,
2248
if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
2251
value = gconf_value_get_string (entry->value);
2253
g_free (clock->custom_format);
2254
clock->custom_format = g_strdup (value);
2256
if (clock->format == CLOCK_FORMAT_CUSTOM)
2257
refresh_clock (clock);
2261
show_week_changed (GConfClient *client,
2268
if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
2271
value = gconf_value_get_bool (entry->value);
2273
if (clock->showweek == (value != 0))
2276
clock->showweek = (value != 0);
2278
if (clock->calendar_popup != NULL) {
2279
calendar_window_set_show_weeks (CALENDAR_WINDOW (clock->calendar_popup), clock->showweek);
2280
position_calendar_popup (clock);
2285
setup_gconf_preference (ClockData *cd, GConfClient *client, const char *key_name, GConfClientNotifyFunc callback)
2290
key = panel_applet_gconf_get_full_key (PANEL_APPLET (cd->applet),
2292
id = gconf_client_notify_add (client, key,
2301
setup_gconf (ClockData *cd)
2304
const char *key_name;
2305
GConfClientNotifyFunc callback;
2307
{ KEY_FORMAT, (GConfClientNotifyFunc) format_changed },
2308
{ KEY_SHOW_SECONDS, (GConfClientNotifyFunc) show_seconds_changed },
2309
{ KEY_SHOW_DATE, (GConfClientNotifyFunc) show_date_changed },
2310
{ KEY_SHOW_WEATHER, (GConfClientNotifyFunc) show_weather_changed },
2311
{ KEY_SHOW_TEMPERATURE, (GConfClientNotifyFunc) show_temperature_changed },
2312
{ KEY_CUSTOM_FORMAT, (GConfClientNotifyFunc) custom_format_changed },
2313
{ KEY_SHOW_WEEK, (GConfClientNotifyFunc) show_week_changed },
2314
{ KEY_CITIES, (GConfClientNotifyFunc) cities_changed },
2315
{ KEY_TEMPERATURE_UNIT, (GConfClientNotifyFunc) temperature_unit_changed },
2316
{ KEY_SPEED_UNIT, (GConfClientNotifyFunc) speed_unit_changed },
2319
GConfClient *client;
2322
client = gconf_client_get_default ();
2324
for (i = 0; i < G_N_ELEMENTS (prefs); i++)
2325
cd->listeners[i] = setup_gconf_preference (cd, client, prefs[i].key_name, prefs[i].callback);
2327
g_object_unref (G_OBJECT (client));
2331
parse_gconf_cities (ClockData *cd, GSList *values)
2333
GSList *cur = values;
2334
LocationParserData data;
2335
GMarkupParseContext *context;
2341
g_markup_parse_context_new (&location_parser, 0, &data, NULL);
2344
const char *str = (char *)cur->data;
2345
g_markup_parse_context_parse (context, str, strlen(str), NULL);
2350
g_markup_parse_context_free (context);
2356
load_gconf_settings (ClockData *cd)
2358
PanelApplet *applet;
2363
GSList *values = NULL;
2364
GList *cities = NULL;
2366
applet = PANEL_APPLET (cd->applet);
2368
cd->format = CLOCK_FORMAT_INVALID;
2370
format_str = panel_applet_gconf_get_string (applet, KEY_FORMAT, NULL);
2372
gconf_string_to_enum (format_type_enum_map, format_str, &format))
2373
cd->format = format;
2375
clock_migrate_to_26 (cd);
2377
g_free (format_str);
2379
if (cd->format == CLOCK_FORMAT_INVALID)
2380
cd->format = clock_locale_format ();
2382
cd->custom_format = panel_applet_gconf_get_string (applet, KEY_CUSTOM_FORMAT, NULL);
2383
cd->showseconds = panel_applet_gconf_get_bool (applet, KEY_SHOW_SECONDS, NULL);
2386
cd->showdate = panel_applet_gconf_get_bool (applet, KEY_SHOW_DATE, &error);
2388
g_error_free (error);
2389
/* if on a small screen don't show date by default */
2390
if (gdk_screen_width () <= 800)
2391
cd->showdate = FALSE;
2393
cd->showdate = TRUE;
2396
cd->show_weather = panel_applet_gconf_get_bool (applet, KEY_SHOW_WEATHER, NULL);
2397
cd->show_temperature = panel_applet_gconf_get_bool (applet, KEY_SHOW_TEMPERATURE, NULL);
2398
cd->showweek = panel_applet_gconf_get_bool (applet, KEY_SHOW_WEEK, NULL);
2399
cd->timeformat = NULL;
2401
cd->can_handle_format_12 = (clock_locale_format () == CLOCK_FORMAT_12);
2402
if (!cd->can_handle_format_12 && cd->format == CLOCK_FORMAT_12)
2403
cd->format = CLOCK_FORMAT_24;
2405
value = panel_applet_gconf_get_string (applet, KEY_TEMPERATURE_UNIT, NULL);
2406
parse_and_set_temperature_string (value, cd);
2409
value = panel_applet_gconf_get_string (applet, KEY_SPEED_UNIT, NULL);
2410
parse_and_set_speed_string (value, cd);
2413
values = panel_applet_gconf_get_list (PANEL_APPLET (cd->applet), KEY_CITIES,
2414
GCONF_VALUE_STRING, NULL);
2416
if (g_slist_length (values) == 0) {
2419
cities = parse_gconf_cities (cd, values);
2422
set_locations (cd, cities);
2426
fill_clock_applet (PanelApplet *applet)
2429
GtkActionGroup *action_group;
2432
panel_applet_add_preferences (applet, CLOCK_SCHEMA_DIR, NULL);
2433
panel_applet_set_flags (applet, PANEL_APPLET_EXPAND_MINOR);
2435
cd = g_new0 (ClockData, 1);
2436
cd->fixed_width = -1;
2437
cd->fixed_height = -1;
2439
cd->applet = GTK_WIDGET (applet);
2442
load_gconf_settings (cd);
2444
cd->builder = gtk_builder_new ();
2445
gtk_builder_set_translation_domain (cd->builder, GETTEXT_PACKAGE);
2446
gtk_builder_add_from_resource (cd->builder, CLOCK_RESOURCE_PATH "clock.ui", NULL);
2448
create_clock_widget (cd);
2450
#ifndef CLOCK_INPROCESS
2451
gtk_window_set_default_icon_name (CLOCK_ICON);
2453
gtk_widget_show (cd->applet);
2455
/* FIXME: Update this comment. */
2456
/* we have to bind change_orient before we do applet_widget_add
2457
since we need to get an initial change_orient signal to set our
2458
initial oriantation, and we get that during the _add call */
2459
g_signal_connect (G_OBJECT (cd->applet),
2461
G_CALLBACK (applet_change_orient),
2464
g_signal_connect (G_OBJECT (cd->panel_button),
2466
G_CALLBACK (panel_button_change_pixel_size),
2469
panel_applet_set_background_widget (PANEL_APPLET (cd->applet),
2470
GTK_WIDGET (cd->applet));
2472
action_group = gtk_action_group_new ("ClockApplet Menu Actions");
2473
gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
2474
gtk_action_group_add_actions (action_group,
2476
G_N_ELEMENTS (clock_menu_actions),
2478
panel_applet_setup_menu_from_resource (PANEL_APPLET (cd->applet),
2479
CLOCK_RESOURCE_PATH "clock-menu.xml",
2482
action = gtk_action_group_get_action (action_group, "ClockPreferences");
2483
g_object_bind_property (cd->applet, "locked-down",
2485
G_BINDING_DEFAULT|G_BINDING_INVERT_BOOLEAN|G_BINDING_SYNC_CREATE);
2487
action = gtk_action_group_get_action (action_group, "ClockConfig");
2488
g_object_bind_property (cd->applet, "locked-down",
2490
G_BINDING_DEFAULT|G_BINDING_INVERT_BOOLEAN|G_BINDING_SYNC_CREATE);
2492
cd->systz = system_timezone_new ();
2493
g_signal_connect (cd->systz, "changed",
2494
G_CALLBACK (clock_timezone_changed), cd);
2496
g_object_unref (action_group);
2501
/* FIXME old clock applet */
2504
setup_writability_sensitivity (ClockData *clock, GtkWidget *w, GtkWidget *label, const char *key)
2506
/* FMQ: was used from old preferences dialog; fix this up */
2508
GConfClient *client;
2510
client = gconf_client_get_default ();
2512
fullkey = panel_applet_gconf_get_full_key
2513
(PANEL_APPLET (clock->applet), key);
2515
if ( ! gconf_client_key_is_writable (client, fullkey, NULL)) {
2516
g_object_set_data (G_OBJECT (w), NEVER_SENSITIVE,
2517
GINT_TO_POINTER (1));
2518
gtk_widget_set_sensitive (w, FALSE);
2519
if (label != NULL) {
2520
g_object_set_data (G_OBJECT (label), NEVER_SENSITIVE,
2521
GINT_TO_POINTER (1));
2522
gtk_widget_set_sensitive (label, FALSE);
2528
g_object_unref (G_OBJECT (client));
2532
update_properties_for_format (ClockData *cd,
2537
/* show the custom format things the first time we actually
2538
* have a custom format set in GConf, but after that don't
2539
* unshow it if the format changes
2541
if (!cd->custom_format_shown &&
2542
(cd->format == CLOCK_FORMAT_CUSTOM ||
2543
(cd->custom_format && cd->custom_format [0]))) {
2544
gtk_widget_show (cd->custom_hbox);
2545
gtk_widget_show (cd->custom_label);
2546
gtk_widget_show (cd->custom_entry);
2548
gtk_combo_box_append_text (combo, _("Custom format"));
2550
cd->custom_format_shown = TRUE;
2553
/* Some combinations of options do not make sense */
2555
case CLOCK_FORMAT_12:
2556
case CLOCK_FORMAT_24:
2557
gtk_widget_set_sensitive (cd->showseconds_check, TRUE);
2558
gtk_widget_set_sensitive (cd->showdate_check, TRUE);
2559
gtk_widget_set_sensitive (cd->custom_entry, FALSE);
2560
gtk_widget_set_sensitive (cd->custom_label, FALSE);
2562
case CLOCK_FORMAT_UNIX:
2563
gtk_widget_set_sensitive (cd->showseconds_check, FALSE);
2564
gtk_widget_set_sensitive (cd->showdate_check, FALSE);
2565
gtk_widget_set_sensitive (cd->custom_entry, FALSE);
2566
gtk_widget_set_sensitive (cd->custom_label, FALSE);
2568
case CLOCK_FORMAT_INTERNET:
2569
gtk_widget_set_sensitive (cd->showseconds_check, TRUE);
2570
gtk_widget_set_sensitive (cd->showdate_check, FALSE);
2571
gtk_widget_set_sensitive (cd->custom_entry, FALSE);
2572
gtk_widget_set_sensitive (cd->custom_label, FALSE);
2574
case CLOCK_FORMAT_CUSTOM:
2575
gtk_widget_set_sensitive (cd->showseconds_check, FALSE);
2576
gtk_widget_set_sensitive (cd->showdate_check, FALSE);
2577
gtk_widget_set_sensitive (cd->custom_entry, TRUE);
2578
gtk_widget_set_sensitive (cd->custom_label, TRUE);
2581
g_assert_not_reached ();
2587
set_format_cb (GtkComboBox *combo,
2590
/* FMQ: was used from old preferences dialog; fix this up */
2593
/* valid values begin from 1 */
2594
if (cd->can_handle_format_12)
2595
format = gtk_combo_box_get_active (combo) + 1;
2597
format = gtk_combo_box_get_active (combo) + 2;
2599
update_properties_for_format (cd, combo, format);
2601
if (cd->format != format)
2602
panel_applet_gconf_set_string (PANEL_APPLET (cd->applet),
2604
gconf_enum_to_string (format_type_enum_map, format),
2610
set_show_seconds_cb (GtkWidget *w,
2613
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2615
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)),
2620
set_show_date_cb (GtkWidget *w,
2623
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2625
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)),
2630
set_show_weather_cb (GtkWidget *w,
2633
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2635
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)),
2640
set_show_temperature_cb (GtkWidget *w,
2643
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2644
KEY_SHOW_TEMPERATURE,
2645
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)),
2651
set_show_zones_cb (GtkWidget *w,
2654
panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
2656
GTK_TOGGLE_BUTTON (w)->active,
2661
/* FIXME old clock applet */
2664
set_custom_format_cb (GtkEntry *entry,
2667
/* FMQ: was used from old preferences dialog; fix this up */
2668
const char *custom_format;
2670
custom_format = gtk_entry_get_text (entry);
2671
panel_applet_gconf_set_string (PANEL_APPLET (cd->applet),
2672
KEY_CUSTOM_FORMAT, custom_format, NULL);
2677
prefs_locations_changed (GtkTreeSelection *selection, ClockData *cd)
2681
n = gtk_tree_selection_count_selected_rows (selection);
2682
gtk_widget_set_sensitive (cd->prefs_location_edit_button, n > 0);
2683
gtk_widget_set_sensitive (cd->prefs_location_remove_button, n > 0);
2687
loc_to_string (ClockLocation *loc)
2689
const gchar *name, *city;
2690
gfloat latitude, longitude;
2693
name = clock_location_get_name (loc);
2694
city = clock_location_get_city (loc);
2695
clock_location_get_coords (loc, &latitude, &longitude);
2697
setlocale (LC_NUMERIC, "POSIX");
2699
ret = g_markup_printf_escaped
2700
("<location name=\"%s\" city=\"%s\" timezone=\"%s\" latitude=\"%f\" longitude=\"%f\" code=\"%s\" current=\"%s\"/>",
2703
clock_location_get_timezone (loc),
2704
latitude, longitude,
2705
clock_location_get_weather_code (loc),
2706
clock_location_is_current (loc) ? "true" : "false");
2708
setlocale (LC_NUMERIC, "");
2714
save_cities_store (ClockData *cd)
2717
GList *node = cd->locations;
2719
GSList *root = NULL;
2720
GSList *list = NULL;
2723
loc = CLOCK_LOCATION (node->data);
2724
list = g_slist_prepend (list, loc_to_string (loc));
2728
list = g_slist_reverse (list);
2729
panel_applet_gconf_set_list (PANEL_APPLET (cd->applet),
2730
KEY_CITIES, GCONF_VALUE_STRING, list, NULL);
2735
g_free (list->data);
2736
list = g_slist_next (list);
2739
g_slist_free (root);
2743
run_prefs_edit_save (GtkButton *button, ClockData *cd)
2745
GtkWidget *edit_window = _clock_get_widget (cd, "edit-location-window");
2747
ClockLocation *loc = g_object_get_data (G_OBJECT (edit_window), "clock-location");
2749
GtkWidget *lat_entry = _clock_get_widget (cd, "edit-location-latitude-entry");
2750
GtkWidget *lon_entry = _clock_get_widget (cd, "edit-location-longitude-entry");
2751
GtkWidget *lat_combo = _clock_get_widget (cd, "edit-location-latitude-combo");
2752
GtkWidget *lon_combo = _clock_get_widget (cd, "edit-location-longitude-combo");
2754
const gchar *timezone, *weather_code;
2757
GWeatherLocation *gloc;
2761
timezone = gweather_timezone_menu_get_tzid (cd->zone_combo);
2763
edit_hide (NULL, cd);
2768
weather_code = NULL;
2771
gloc = gweather_location_entry_get_location (cd->location_entry);
2773
city = gweather_location_get_city_name (gloc);
2774
weather_code = gweather_location_get_code (gloc);
2777
if (gweather_location_entry_has_custom_text (cd->location_entry)) {
2778
name = gtk_editable_get_chars (GTK_EDITABLE (cd->location_entry), 0, -1);
2781
sscanf (gtk_entry_get_text (GTK_ENTRY (lat_entry)), "%f", &lat);
2782
sscanf (gtk_entry_get_text (GTK_ENTRY (lon_entry)), "%f", &lon);
2784
if (gtk_combo_box_get_active (GTK_COMBO_BOX (lat_combo)) != 0) {
2788
if (gtk_combo_box_get_active (GTK_COMBO_BOX (lon_combo)) != 0) {
2793
clock_location_set_timezone (loc, timezone);
2794
clock_location_set_name (loc, name);
2795
clock_location_set_city (loc, city);
2796
clock_location_set_coords (loc, lat, lon);
2797
clock_location_set_weather_code (loc, weather_code);
2801
prefs.temperature_unit = cd->temperature_unit;
2802
prefs.speed_unit = cd->speed_unit;
2804
loc = clock_location_new (name, city, timezone, lat, lon, weather_code, &prefs);
2805
/* has the side-effect of setting the current location if
2806
* there's none and this one can be considered as a current one
2808
clock_location_is_current (loc);
2810
cd->locations = g_list_append (cd->locations, loc);
2815
/* This will update everything related to locations to take into
2816
* account the new location (via the gconf notification) */
2817
save_cities_store (cd);
2819
edit_hide (edit_window, cd);
2823
update_coords_helper (gfloat value, GtkWidget *entry, GtkWidget *combo)
2827
tmp = g_strdup_printf ("%f", fabsf (value));
2828
gtk_entry_set_text (GTK_ENTRY (entry), tmp);
2832
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
2834
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 1);
2839
update_coords (ClockData *cd, gboolean valid, gfloat lat, gfloat lon)
2841
GtkWidget *lat_entry = _clock_get_widget (cd, "edit-location-latitude-entry");
2842
GtkWidget *lon_entry = _clock_get_widget (cd, "edit-location-longitude-entry");
2843
GtkWidget *lat_combo = _clock_get_widget (cd, "edit-location-latitude-combo");
2844
GtkWidget *lon_combo = _clock_get_widget (cd, "edit-location-longitude-combo");
2847
gtk_entry_set_text (GTK_ENTRY (lat_entry), "");
2848
gtk_entry_set_text (GTK_ENTRY (lon_entry), "");
2849
gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), -1);
2850
gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), -1);
2855
update_coords_helper (lat, lat_entry, lat_combo);
2856
update_coords_helper (lon, lon_entry, lon_combo);
2860
fill_timezone_combo_from_location (ClockData *cd, ClockLocation *loc)
2863
gweather_timezone_menu_set_tzid (cd->zone_combo,
2864
clock_location_get_timezone (loc));
2866
gweather_timezone_menu_set_tzid (cd->zone_combo, NULL);
2871
location_update_ok_sensitivity (ClockData *cd)
2873
GtkWidget *ok_button;
2874
const gchar *timezone;
2877
ok_button = _clock_get_widget (cd, "edit-location-ok-button");
2879
timezone = gweather_timezone_menu_get_tzid (cd->zone_combo);
2880
name = gtk_editable_get_chars (GTK_EDITABLE (cd->location_entry), 0, -1);
2882
if (timezone && name && name[0] != '\0') {
2883
gtk_widget_set_sensitive (ok_button, TRUE);
2885
gtk_widget_set_sensitive (ok_button, FALSE);
2892
location_changed (GObject *object, GParamSpec *param, ClockData *cd)
2894
GWeatherLocationEntry *entry = GWEATHER_LOCATION_ENTRY (object);
2895
GWeatherLocation *gloc;
2896
GWeatherTimezone *zone;
2897
gboolean latlon_valid;
2898
double latitude = 0.0, longitude = 0.0;
2900
gloc = gweather_location_entry_get_location (entry);
2902
latlon_valid = gloc && gweather_location_has_coords (gloc);
2904
gweather_location_get_coords (gloc, &latitude, &longitude);
2905
update_coords (cd, latlon_valid, latitude, longitude);
2907
zone = gloc ? gweather_location_get_timezone (gloc) : NULL;
2909
gweather_timezone_menu_set_tzid (cd->zone_combo, gweather_timezone_get_tzid (zone));
2911
gweather_timezone_menu_set_tzid (cd->zone_combo, NULL);
2914
gweather_location_unref (gloc);
2918
location_name_changed (GObject *object, ClockData *cd)
2920
location_update_ok_sensitivity (cd);
2924
location_timezone_changed (GObject *object, GParamSpec *param, ClockData *cd)
2926
location_update_ok_sensitivity (cd);
2930
edit_clear (ClockData *cd)
2932
GtkWidget *lat_entry = _clock_get_widget (cd, "edit-location-latitude-entry");
2933
GtkWidget *lon_entry = _clock_get_widget (cd, "edit-location-longitude-entry");
2934
GtkWidget *lat_combo = _clock_get_widget (cd, "edit-location-latitude-combo");
2935
GtkWidget *lon_combo = _clock_get_widget (cd, "edit-location-longitude-combo");
2937
/* clear out the old data */
2938
gweather_location_entry_set_location (cd->location_entry, NULL);
2939
gweather_timezone_menu_set_tzid (cd->zone_combo, NULL);
2941
gtk_entry_set_text (GTK_ENTRY (lat_entry), "");
2942
gtk_entry_set_text (GTK_ENTRY (lon_entry), "");
2944
gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), -1);
2945
gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), -1);
2949
edit_hide (GtkWidget *unused, ClockData *cd)
2951
GtkWidget *edit_window = _clock_get_widget (cd, "edit-location-window");
2953
gtk_widget_hide (edit_window);
2958
edit_delete (GtkWidget *unused, GdkEvent *event, ClockData *cd)
2960
edit_hide (unused, cd);
2966
edit_hide_event (GtkWidget *widget, GdkEvent *event, ClockData *cd)
2968
edit_hide (widget, cd);
2974
prefs_hide (GtkWidget *widget, ClockData *cd)
2978
edit_hide (widget, cd);
2980
gtk_widget_hide (cd->prefs_window);
2982
tree = _clock_get_widget (cd, "cities_list");
2984
gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)));
2986
refresh_click_timeout_time_only (cd);
2990
prefs_hide_event (GtkWidget *widget, GdkEvent *event, ClockData *cd)
2992
prefs_hide (widget, cd);
2998
prefs_help (GtkWidget *widget, ClockData *cd)
3000
clock_utils_display_help (cd->prefs_window,
3001
"clock", "clock-settings");
3005
remove_tree_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
3007
ClockData *cd = data;
3008
ClockLocation *loc = NULL;
3010
gtk_tree_model_get (model, iter, COL_CITY_LOC, &loc, -1);
3011
cd->locations = g_list_remove (cd->locations, loc);
3012
g_object_unref (loc);
3014
/* This will update everything related to locations to take into
3015
* account the removed location (via the gconf notification) */
3016
save_cities_store (cd);
3020
run_prefs_locations_remove (GtkButton *button, ClockData *cd)
3022
GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (cd->prefs_locations));
3024
gtk_tree_selection_selected_foreach (sel, remove_tree_row, cd);
3028
run_prefs_locations_add (GtkButton *button, ClockData *cd)
3030
GtkWidget *edit_window = _clock_get_widget (cd, "edit-location-window");
3032
fill_timezone_combo_from_location (cd, NULL);
3034
g_object_set_data (G_OBJECT (edit_window), "clock-location", NULL);
3035
gtk_window_set_title (GTK_WINDOW (edit_window), _("Choose Location"));
3036
gtk_window_set_transient_for (GTK_WINDOW (edit_window), GTK_WINDOW (cd->prefs_window));
3038
if (g_object_get_data (G_OBJECT (edit_window), "delete-handler") == NULL) {
3039
g_object_set_data (G_OBJECT (edit_window), "delete-handler",
3040
GINT_TO_POINTER (g_signal_connect (edit_window, "delete_event", G_CALLBACK (edit_delete), cd)));
3043
location_update_ok_sensitivity (cd);
3045
gtk_widget_grab_focus (GTK_WIDGET (cd->location_entry));
3046
gtk_editable_set_position (GTK_EDITABLE (cd->location_entry), -1);
3048
gtk_window_present_with_time (GTK_WINDOW (edit_window), gtk_get_current_event_time ());
3052
edit_tree_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
3054
ClockData *cd = data;
3060
/* fill the dialog with this location's data, show it */
3061
GtkWidget *edit_window = _clock_get_widget (cd, "edit-location-window");
3063
GtkWidget *lat_entry = _clock_get_widget (cd, "edit-location-latitude-entry");
3065
GtkWidget *lon_entry = _clock_get_widget (cd, "edit-location-longitude-entry");
3067
GtkWidget *lat_combo = _clock_get_widget (cd, "edit-location-latitude-combo");
3069
GtkWidget *lon_combo = _clock_get_widget (cd, "edit-location-longitude-combo");
3073
gtk_tree_model_get (model, iter, COL_CITY_LOC, &loc, -1);
3075
gweather_location_entry_set_city (cd->location_entry,
3076
clock_location_get_city (loc),
3077
clock_location_get_weather_code (loc));
3078
name = clock_location_get_name (loc);
3079
if (name && name[0]) {
3080
gtk_entry_set_text (GTK_ENTRY (cd->location_entry), name);
3083
clock_location_get_coords (loc, &lat, &lon);
3085
fill_timezone_combo_from_location (cd, loc);
3087
tmp = g_strdup_printf ("%f", fabsf(lat));
3088
gtk_entry_set_text (GTK_ENTRY (lat_entry), tmp);
3092
gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), 0);
3094
gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), 1);
3097
tmp = g_strdup_printf ("%f", fabsf(lon));
3098
gtk_entry_set_text (GTK_ENTRY (lon_entry), tmp);
3102
gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), 0);
3104
gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), 1);
3107
location_update_ok_sensitivity (cd);
3109
g_object_set_data (G_OBJECT (edit_window), "clock-location", loc);
3111
gtk_widget_grab_focus (GTK_WIDGET (cd->location_entry));
3112
gtk_editable_set_position (GTK_EDITABLE (cd->location_entry), -1);
3114
gtk_window_set_title (GTK_WINDOW (edit_window), _("Edit Location"));
3115
gtk_window_present (GTK_WINDOW (edit_window));
3119
run_prefs_locations_edit (GtkButton *unused, ClockData *cd)
3121
GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (cd->prefs_locations));
3123
gtk_tree_selection_selected_foreach (sel, edit_tree_row, cd);
3127
set_12hr_format_radio_cb (GtkWidget *widget, ClockData *cd)
3132
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
3133
format = CLOCK_FORMAT_12;
3135
format = CLOCK_FORMAT_24;
3137
val = gconf_enum_to_string (format_type_enum_map, format);
3139
panel_applet_gconf_set_string (PANEL_APPLET (cd->applet),
3140
KEY_FORMAT, val, NULL);
3144
temperature_combo_changed (GtkComboBox *combo, ClockData *cd)
3150
value = gtk_combo_box_get_active (combo) + 1;
3152
if (cd->use_temperature_default)
3153
old_value = TEMP_UNIT_DEFAULT;
3155
old_value = cd->temperature_unit;
3157
if (value == old_value)
3160
str = gweather_prefs_temp_enum_to_string (value);
3162
panel_applet_gconf_set_string (PANEL_APPLET (cd->applet),
3163
KEY_TEMPERATURE_UNIT, str, NULL);
3167
speed_combo_changed (GtkComboBox *combo, ClockData *cd)
3173
value = gtk_combo_box_get_active (combo) + 1;
3175
if (cd->use_speed_default)
3176
old_value = SPEED_UNIT_DEFAULT;
3178
old_value = cd->speed_unit;
3180
if (value == old_value)
3183
str = gweather_prefs_speed_enum_to_string (value);
3185
panel_applet_gconf_set_string (PANEL_APPLET (cd->applet),
3186
KEY_SPEED_UNIT, str, NULL);
3190
fill_prefs_window (ClockData *cd)
3192
static const int temperatures[] = {
3195
TEMP_UNIT_CENTIGRADE,
3196
TEMP_UNIT_FAHRENHEIT,
3200
static const int speeds[] = {
3210
GtkWidget *radio_12hr;
3211
GtkWidget *radio_24hr;
3213
GtkCellRenderer *renderer;
3214
GtkTreeViewColumn *col;
3215
GtkListStore *store;
3219
/* Set the 12 hour / 24 hour widget */
3220
radio_12hr = _clock_get_widget (cd, "12hr_radio");
3221
radio_24hr = _clock_get_widget (cd, "24hr_radio");
3223
if (cd->format == CLOCK_FORMAT_12)
3224
widget = radio_12hr;
3226
widget = radio_24hr;
3228
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
3230
g_signal_connect (radio_12hr, "toggled",
3231
G_CALLBACK (set_12hr_format_radio_cb), cd);
3233
/* Set the "Show Date" checkbox */
3234
widget = _clock_get_widget (cd, "date_check");
3235
g_signal_connect (widget, "toggled",
3236
G_CALLBACK (set_show_date_cb), cd);
3237
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), cd->showdate);
3239
/* Set the "Show Seconds" checkbox */
3240
widget = _clock_get_widget (cd, "seconds_check");
3241
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), cd->showseconds);
3242
g_signal_connect (widget, "toggled",
3243
G_CALLBACK (set_show_seconds_cb), cd);
3245
/* Set the "Show weather" checkbox */
3246
widget = _clock_get_widget (cd, "weather_check");
3247
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), cd->show_weather);
3248
g_signal_connect (widget, "toggled",
3249
G_CALLBACK (set_show_weather_cb), cd);
3251
/* Set the "Show temperature" checkbox */
3252
widget = _clock_get_widget (cd, "temperature_check");
3253
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), cd->show_temperature);
3254
g_signal_connect (widget, "toggled",
3255
G_CALLBACK (set_show_temperature_cb), cd);
3257
/* Fill the Cities list */
3258
widget = _clock_get_widget (cd, "cities_list");
3260
renderer = gtk_cell_renderer_text_new ();
3261
col = gtk_tree_view_column_new_with_attributes (_("City Name"), renderer, "text", COL_CITY_NAME, NULL);
3262
gtk_tree_view_insert_column (GTK_TREE_VIEW (widget), col, -1);
3264
renderer = gtk_cell_renderer_text_new ();
3265
col = gtk_tree_view_column_new_with_attributes (_("City Time Zone"), renderer, "text", COL_CITY_TZ, NULL);
3266
gtk_tree_view_insert_column (GTK_TREE_VIEW (widget), col, -1);
3268
if (cd->cities_store == NULL)
3269
create_cities_store (cd);
3271
gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
3272
GTK_TREE_MODEL (cd->cities_store));
3274
/* Temperature combo */
3275
widget = _clock_get_widget (cd, "temperature_combo");
3276
store = gtk_list_store_new (1, G_TYPE_STRING);
3277
gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
3278
renderer = gtk_cell_renderer_text_new ();
3279
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE);
3280
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer, "text", 0, NULL);
3282
for (i = 0; temperatures[i] != -1; i++)
3283
gtk_list_store_insert_with_values (store, &iter, -1,
3284
0, gweather_prefs_get_temp_display_name (temperatures[i]),
3287
update_temperature_combo (cd);
3288
g_signal_connect (widget, "changed",
3289
G_CALLBACK (temperature_combo_changed), cd);
3291
/* Wind speed combo */
3292
widget = _clock_get_widget (cd, "wind_speed_combo");
3293
store = gtk_list_store_new (1, G_TYPE_STRING);
3294
gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
3295
renderer = gtk_cell_renderer_text_new ();
3296
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE);
3297
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer, "text", 0, NULL);
3299
for (i = 0; speeds[i] != -1; i++)
3300
gtk_list_store_insert_with_values (store, &iter, -1,
3301
0, gweather_prefs_get_speed_display_name (speeds[i]),
3304
update_speed_combo (cd);
3305
g_signal_connect (widget, "changed",
3306
G_CALLBACK (speed_combo_changed), cd);
3310
ensure_prefs_window_is_created (ClockData *cd)
3312
GtkWidget *edit_window;
3313
GtkWidget *prefs_close_button;
3314
GtkWidget *prefs_help_button;
3315
GtkWidget *clock_options;
3316
GtkWidget *edit_cancel_button;
3317
GtkWidget *edit_ok_button;
3318
GtkWidget *location_box;
3319
GtkWidget *zone_box;
3320
GtkWidget *location_name_label;
3321
GtkWidget *timezone_label;
3322
GtkTreeSelection *selection;
3323
GWeatherLocation *world;
3325
if (cd->prefs_window)
3328
cd->prefs_window = _clock_get_widget (cd, "prefs-window");
3330
gtk_window_set_icon_name (GTK_WINDOW (cd->prefs_window), CLOCK_ICON);
3332
prefs_close_button = _clock_get_widget (cd, "prefs-close-button");
3333
prefs_help_button = _clock_get_widget (cd, "prefs-help-button");
3334
clock_options = _clock_get_widget (cd, "clock-options");
3335
cd->prefs_locations = GTK_TREE_VIEW (_clock_get_widget (cd, "cities_list"));
3336
location_name_label = _clock_get_widget (cd, "location-name-label");
3337
timezone_label = _clock_get_widget (cd, "timezone-label");
3340
if (!clock_locale_supports_am_pm ())
3341
gtk_widget_hide (clock_options);
3343
selection = gtk_tree_view_get_selection (cd->prefs_locations);
3344
g_signal_connect (G_OBJECT (selection), "changed",
3345
G_CALLBACK (prefs_locations_changed), cd);
3347
g_signal_connect (G_OBJECT (cd->prefs_window), "delete_event",
3348
G_CALLBACK (prefs_hide_event), cd);
3350
g_signal_connect (G_OBJECT (prefs_close_button), "clicked",
3351
G_CALLBACK (prefs_hide), cd);
3353
g_signal_connect (G_OBJECT (prefs_help_button), "clicked",
3354
G_CALLBACK (prefs_help), cd);
3356
cd->prefs_location_remove_button = _clock_get_widget (cd, "prefs-locations-remove-button");
3358
g_signal_connect (G_OBJECT (cd->prefs_location_remove_button), "clicked",
3359
G_CALLBACK (run_prefs_locations_remove), cd);
3361
cd->prefs_location_add_button = _clock_get_widget (cd, "prefs-locations-add-button");
3363
g_signal_connect (G_OBJECT (cd->prefs_location_add_button), "clicked",
3364
G_CALLBACK (run_prefs_locations_add), cd);
3366
cd->prefs_location_edit_button = _clock_get_widget (cd, "prefs-locations-edit-button");
3368
g_signal_connect (G_OBJECT (cd->prefs_location_edit_button), "clicked",
3369
G_CALLBACK (run_prefs_locations_edit), cd);
3371
edit_window = _clock_get_widget (cd, "edit-location-window");
3373
gtk_window_set_transient_for (GTK_WINDOW (edit_window),
3374
GTK_WINDOW (cd->prefs_window));
3376
g_signal_connect (G_OBJECT (edit_window), "delete_event",
3377
G_CALLBACK (edit_hide_event), cd);
3379
edit_cancel_button = _clock_get_widget (cd, "edit-location-cancel-button");
3381
edit_ok_button = _clock_get_widget (cd, "edit-location-ok-button");
3383
world = gweather_location_new_world (FALSE);
3385
location_box = _clock_get_widget (cd, "edit-location-name-box");
3386
cd->location_entry = GWEATHER_LOCATION_ENTRY (gweather_location_entry_new (world));
3387
gtk_widget_show (GTK_WIDGET (cd->location_entry));
3388
gtk_container_add (GTK_CONTAINER (location_box), GTK_WIDGET (cd->location_entry));
3389
gtk_label_set_mnemonic_widget (GTK_LABEL (location_name_label),
3390
GTK_WIDGET (cd->location_entry));
3392
g_signal_connect (G_OBJECT (cd->location_entry), "notify::location",
3393
G_CALLBACK (location_changed), cd);
3394
g_signal_connect (G_OBJECT (cd->location_entry), "changed",
3395
G_CALLBACK (location_name_changed), cd);
3397
zone_box = _clock_get_widget (cd, "edit-location-timezone-box");
3398
cd->zone_combo = GWEATHER_TIMEZONE_MENU (gweather_timezone_menu_new (world));
3399
gtk_widget_show (GTK_WIDGET (cd->zone_combo));
3400
gtk_container_add (GTK_CONTAINER (zone_box), GTK_WIDGET (cd->zone_combo));
3401
gtk_label_set_mnemonic_widget (GTK_LABEL (timezone_label),
3402
GTK_WIDGET (cd->zone_combo));
3404
g_signal_connect (G_OBJECT (cd->zone_combo), "notify::tzid",
3405
G_CALLBACK (location_timezone_changed), cd);
3407
gweather_location_unref (world);
3409
g_signal_connect (G_OBJECT (edit_cancel_button), "clicked",
3410
G_CALLBACK (edit_hide), cd);
3412
g_signal_connect (G_OBJECT (edit_ok_button), "clicked",
3413
G_CALLBACK (run_prefs_edit_save), cd);
3415
/* Set up the time setting section */
3417
cd->time_settings_button = _clock_get_widget (cd, "time-settings-button");
3418
g_signal_connect (cd->time_settings_button, "clicked",
3419
G_CALLBACK (run_time_settings), cd);
3421
/* fill it with the current preferences */
3422
fill_prefs_window (cd);
3426
display_properties_dialog (ClockData *cd, gboolean start_in_locations_page)
3428
ensure_prefs_window_is_created (cd);
3430
if (start_in_locations_page) {
3431
GtkWidget *notebook = _clock_get_widget (cd, "notebook");
3432
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1);
3435
update_set_time_button (cd);
3437
gtk_window_set_screen (GTK_WINDOW (cd->prefs_window),
3438
gtk_widget_get_screen (cd->applet));
3439
gtk_window_present (GTK_WINDOW (cd->prefs_window));
3441
refresh_click_timeout_time_only (cd);
3443
/* FMQ: cd->props was the old preferences window; remove references to it */
3444
/* FMQ: connect to the Help button by hand; look at properties_response_cb() for the help code */
3446
/* FMQ: check the code below; replace the proper parts */
3452
gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("24 hour"));
3453
gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("UNIX time"));
3454
gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Internet time"));
3456
gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
3457
gtk_widget_show (combo);
3459
cd->custom_hbox = gtk_hbox_new (FALSE, 12);
3460
gtk_box_pack_start (GTK_BOX (vbox), cd->custom_hbox, TRUE, TRUE, 0);
3462
cd->custom_label = gtk_label_new_with_mnemonic (_("Custom _format:"));
3463
gtk_label_set_use_markup (GTK_LABEL (cd->custom_label), TRUE);
3464
gtk_label_set_justify (GTK_LABEL (cd->custom_label),
3466
gtk_misc_set_alignment (GTK_MISC (cd->custom_label), 0, 0.5);
3467
gtk_box_pack_start (GTK_BOX (cd->custom_hbox),
3471
cd->custom_entry = gtk_entry_new ();
3472
gtk_box_pack_start (GTK_BOX (cd->custom_hbox),
3475
gtk_entry_set_text (GTK_ENTRY (cd->custom_entry),
3477
g_signal_connect (cd->custom_entry, "changed",
3478
G_CALLBACK (set_custom_format_cb),
3481
g_signal_connect (cd->props, "destroy",
3482
G_CALLBACK (gtk_widget_destroyed),
3484
g_signal_connect (cd->props, "response",
3485
G_CALLBACK (properties_response_cb),
3488
cd->custom_format_shown = FALSE;
3489
update_properties_for_format (cd, GTK_COMBO_BOX (combo), cd->format);
3491
/* valid values begin from 1 */
3492
if (cd->can_handle_format_12)
3493
gtk_combo_box_set_active (GTK_COMBO_BOX (combo),
3496
gtk_combo_box_set_active (GTK_COMBO_BOX (combo),
3499
g_signal_connect (combo, "changed",
3500
G_CALLBACK (set_format_cb), cd);
3502
/* Now set up the sensitivity based on gconf key writability */
3503
setup_writability_sensitivity (cd, combo, label, KEY_FORMAT);
3504
setup_writability_sensitivity (cd, cd->custom_entry, cd->custom_label,
3506
setup_writability_sensitivity (cd, cd->showseconds_check, NULL, KEY_SHOW_SECONDS);
3507
setup_writability_sensitivity (cd, cd->showdate_check, NULL, KEY_SHOW_DATE);
3509
gtk_widget_show (cd->props);
3514
verb_display_properties_dialog (GtkAction *action,
3517
display_properties_dialog (cd, FALSE);
3521
clock_factory (PanelApplet *applet,
3525
gboolean retval = FALSE;
3527
if (!strcmp (iid, "ClockApplet"))
3528
retval = fill_clock_applet (applet);
3533
#ifdef CLOCK_INPROCESS
3534
PANEL_APPLET_IN_PROCESS_FACTORY ("ClockAppletFactory",
3539
PANEL_APPLET_OUT_PROCESS_FACTORY ("ClockAppletFactory",