73
83
XfceScreenPosition position);
74
84
static void clock_plugin_configure_plugin (XfcePanelPlugin *panel_plugin);
75
85
static void clock_plugin_set_mode (ClockPlugin *plugin);
76
static void clock_plugin_reposition_calendar (ClockPlugin *plugin);
77
static void clock_plugin_popup_calendar (ClockPlugin *plugin);
86
static void clock_plugin_reposition_calendar (ClockPlugin *plugin);
87
static gboolean clock_plugin_pointer_grab (ClockPlugin *plugin,
90
static void clock_plugin_pointer_ungrab (ClockPlugin *plugin,
92
static gboolean clock_plugin_calendar_pointed (GtkWidget *calendar_window,
95
static gboolean clock_plugin_calendar_button_press_event (GtkWidget *calendar_window,
96
GdkEventButton *event,
98
static gboolean clock_plugin_calendar_key_press_event (GtkWidget *calendar_window,
100
ClockPlugin *plugin);
101
static void clock_plugin_popup_calendar (ClockPlugin *plugin,
78
103
static void clock_plugin_hide_calendar (ClockPlugin *plugin);
79
104
static gboolean clock_plugin_tooltip (gpointer user_data);
80
static gboolean clock_plugin_timeout_running (gpointer user_data);
81
static void clock_plugin_timeout_destroyed (gpointer user_data);
82
static gboolean clock_plugin_timeout_sync (gpointer user_data);
254
268
plugin->mode = CLOCK_PLUGIN_MODE_DEFAULT;
255
269
plugin->clock = NULL;
256
plugin->show_frame = TRUE;
257
270
plugin->tooltip_format = g_strdup (DEFAULT_TOOLTIP_FORMAT);
258
271
plugin->tooltip_timeout = NULL;
259
272
plugin->command = NULL;
273
plugin->time_config_tool = g_strdup (DEFAULT_TIME_CONFIG_TOOL);
260
274
plugin->rotate_vertically = TRUE;
275
plugin->time = clock_time_new ();
262
plugin->frame = gtk_frame_new (NULL);
263
gtk_container_add (GTK_CONTAINER (plugin), plugin->frame);
264
gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), GTK_SHADOW_ETCHED_IN);
265
gtk_widget_show (plugin->frame);
277
plugin->button = xfce_panel_create_toggle_button ();
278
/* xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->button); */
279
gtk_container_add (GTK_CONTAINER (plugin), plugin->button);
280
gtk_widget_set_name (plugin->button, "clock-button");
281
gtk_button_set_relief (GTK_BUTTON (plugin->button), GTK_RELIEF_NONE);
282
/* Have to handle all events in the button object rather than the plugin.
283
* Otherwise, default handlers will block the events. */
284
g_signal_connect (G_OBJECT (plugin->button), "button-press-event",
285
G_CALLBACK (clock_plugin_button_press_event), plugin);
286
g_signal_connect (G_OBJECT (plugin->button), "enter-notify-event",
287
G_CALLBACK (clock_plugin_enter_notify_event), plugin);
288
g_signal_connect (G_OBJECT (plugin->button), "leave-notify-event",
289
G_CALLBACK (clock_plugin_leave_notify_event), plugin);
290
gtk_widget_show (plugin->button);
796
823
clock_plugin_configure_plugin_free (gpointer user_data)
798
g_slice_free (ClockPluginDialog, user_data);
825
ClockPluginDialog *dialog = user_data;
827
if (dialog->zonecompletion_idle != 0)
828
g_source_remove (dialog->zonecompletion_idle);
830
g_slice_free (ClockPluginDialog, dialog);
836
clock_plugin_configure_config_tool_changed (ClockPluginDialog *dialog)
841
panel_return_if_fail (GTK_IS_BUILDER (dialog->builder));
842
panel_return_if_fail (XFCE_IS_CLOCK_PLUGIN (dialog->plugin));
844
object = gtk_builder_get_object (dialog->builder, "run-time-config-tool");
845
panel_return_if_fail (GTK_IS_BUTTON (object));
846
path = g_find_program_in_path (dialog->plugin->time_config_tool);
847
gtk_widget_set_visible (GTK_WIDGET (object), path != NULL);
854
clock_plugin_configure_run_config_tool (GtkWidget *button,
857
GError *error = NULL;
859
panel_return_if_fail (XFCE_IS_CLOCK_PLUGIN (plugin));
861
if (!xfce_spawn_command_line_on_screen (gtk_widget_get_screen (button),
862
plugin->time_config_tool,
863
FALSE, FALSE, &error))
865
xfce_dialog_show_error (NULL, error, _("Failed to execute command \"%s\"."), plugin->time_config_tool);
866
g_error_free (error);
873
clock_plugin_configure_zoneinfo_model_insert (GtkListStore *store,
880
gsize dirlen = strlen (ZONEINFO_DIR);
882
panel_return_if_fail (GTK_IS_LIST_STORE (store));
884
dir = g_dir_open (parent, 0, NULL);
890
name = g_dir_read_name (dir);
894
filename = g_build_filename (parent, name, NULL);
896
if (g_file_test (filename, G_FILE_TEST_IS_DIR))
898
clock_plugin_configure_zoneinfo_model_insert (store, filename);
902
gtk_list_store_append (store, &iter);
903
gtk_list_store_set (store, &iter, 0, filename + dirlen, -1);
915
clock_plugin_configure_zoneinfo_model (gpointer data)
917
ClockPluginDialog *dialog = data;
918
GtkEntryCompletion *completion;
922
GDK_THREADS_ENTER ();
924
dialog->zonecompletion_idle = 0;
926
object = gtk_builder_get_object (dialog->builder, "timezone-name");
927
panel_return_val_if_fail (GTK_IS_ENTRY (object), FALSE);
929
/* build timezone model */
930
store = gtk_list_store_new (1, G_TYPE_STRING);
931
clock_plugin_configure_zoneinfo_model_insert (store, ZONEINFO_DIR);
932
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), 0, GTK_SORT_ASCENDING);
934
completion = gtk_entry_completion_new ();
935
gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store));
936
g_object_unref (G_OBJECT (store));
938
gtk_entry_set_completion (GTK_ENTRY (object), completion);
939
gtk_entry_completion_set_popup_single_match (completion, TRUE);
940
gtk_entry_completion_set_text_column (completion, 0);
942
g_object_unref (G_OBJECT (completion));
944
GDK_THREADS_LEAVE ();
823
971
dialog->plugin = plugin;
824
972
dialog->builder = builder;
974
object = gtk_builder_get_object (builder, "run-time-config-tool");
975
panel_return_if_fail (GTK_IS_BUTTON (object));
976
g_signal_connect_swapped (G_OBJECT (plugin), "notify::time-config-tool",
977
G_CALLBACK (clock_plugin_configure_config_tool_changed),
979
clock_plugin_configure_config_tool_changed (dialog);
980
g_signal_connect (G_OBJECT (object), "clicked",
981
G_CALLBACK (clock_plugin_configure_run_config_tool), plugin);
983
object = gtk_builder_get_object (builder, "timezone-name");
984
panel_return_if_fail (GTK_IS_ENTRY (object));
985
exo_mutual_binding_new (G_OBJECT (plugin->time), "timezone",
986
G_OBJECT (object), "text");
988
/* idle add the zone completion */
989
dialog->zonecompletion_idle = g_idle_add (clock_plugin_configure_zoneinfo_model, dialog);
826
991
object = gtk_builder_get_object (builder, "mode");
827
992
g_signal_connect_data (G_OBJECT (object), "changed",
828
993
G_CALLBACK (clock_plugin_configure_plugin_mode_changed), dialog,
830
995
exo_mutual_binding_new (G_OBJECT (plugin), "mode",
831
996
G_OBJECT (object), "active");
833
object = gtk_builder_get_object (builder, "show-frame");
834
exo_mutual_binding_new (G_OBJECT (plugin), "show-frame",
835
G_OBJECT (object), "active");
837
998
object = gtk_builder_get_object (builder, "tooltip-format");
838
999
exo_mutual_binding_new (G_OBJECT (plugin), "tooltip-format",
839
1000
G_OBJECT (object), "text");
840
1001
combo = gtk_builder_get_object (builder, "tooltip-chooser");
841
clock_plugin_configure_plugin_chooser_fill (GTK_COMBO_BOX (combo),
1002
clock_plugin_configure_plugin_chooser_fill (plugin,
1003
GTK_COMBO_BOX (combo),
842
1004
GTK_ENTRY (object),
843
1005
tooltip_formats);
845
1007
object = gtk_builder_get_object (builder, "digital-format");
846
1008
combo = gtk_builder_get_object (builder, "digital-chooser");
847
clock_plugin_configure_plugin_chooser_fill (GTK_COMBO_BOX (combo),
1009
clock_plugin_configure_plugin_chooser_fill (plugin,
1010
GTK_COMBO_BOX (combo),
848
1011
GTK_ENTRY (object),
849
1012
digital_formats);
948
1112
clock_plugin_calendar_show_event (GtkWidget *calendar_window,
949
1113
ClockPlugin *plugin)
953
1117
panel_return_if_fail (XFCE_IS_PANEL_PLUGIN (plugin));
955
1119
clock_plugin_reposition_calendar (plugin);
957
clock_plugin_get_localtime (&tm);
958
gtk_calendar_select_month (GTK_CALENDAR (plugin->calendar), tm.tm_mon,
960
gtk_calendar_select_day (GTK_CALENDAR (plugin->calendar), tm.tm_mday);
966
clock_plugin_popup_calendar (ClockPlugin *plugin)
968
GtkWidget *calendar_frame;
1121
time = clock_time_get_time (plugin->time);
1122
gtk_calendar_select_month (GTK_CALENDAR (plugin->calendar), g_date_time_get_month (time) - 1,
1123
g_date_time_get_year (time));
1124
gtk_calendar_select_day (GTK_CALENDAR (plugin->calendar), g_date_time_get_day_of_month (time));
1125
g_date_time_unref (time);
1131
clock_plugin_pointer_ungrab (ClockPlugin *plugin,
1134
if (plugin->grab_pointer == GDK_GRAB_SUCCESS)
1135
gdk_pointer_ungrab (GDK_CURRENT_TIME);
1136
if (plugin->grab_keyboard == GDK_GRAB_SUCCESS)
1137
gdk_keyboard_ungrab (GDK_CURRENT_TIME);
1143
clock_plugin_pointer_grab (ClockPlugin *plugin,
1148
gboolean grab_succeed = FALSE;
1150
GdkEventMask pointer_mask = GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
1151
| GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
1152
| GDK_POINTER_MOTION_MASK;
1154
window = widget->window;
1156
/* don't try to get the grab for longer then 1/4 second */
1157
for (i = 0; i < (G_USEC_PER_SEC / 100 / 4); i++)
1159
plugin->grab_keyboard = gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME);
1160
if (plugin->grab_keyboard == GDK_GRAB_SUCCESS)
1162
plugin->grab_pointer = gdk_pointer_grab (window, TRUE, pointer_mask,
1163
NULL, NULL, GDK_CURRENT_TIME);
1164
if (plugin->grab_pointer == GDK_GRAB_SUCCESS)
1166
grab_succeed = TRUE;
1174
/* release the grab */
1176
clock_plugin_pointer_ungrab (plugin, widget);
1180
clock_plugin_pointer_ungrab (plugin, widget);
1181
g_printerr (PACKAGE_NAME ": Unable to get keyboard and mouse "
1182
"grab. Popup failed.\n");
1185
return grab_succeed;
1191
clock_plugin_calendar_pointed (GtkWidget *calendar_window,
1195
gint window_x, window_y;
1197
if (gtk_widget_get_mapped (calendar_window))
1199
gdk_window_get_position (calendar_window->window, &window_x, &window_y);
1201
if (x_root >= window_x && x_root < window_x + calendar_window->allocation.width &&
1202
y_root >= window_y && y_root < window_y + calendar_window->allocation.height)
1212
clock_plugin_calendar_button_press_event (GtkWidget *calendar_window,
1213
GdkEventButton *event,
1214
ClockPlugin *plugin)
1216
if (event->type == GDK_BUTTON_PRESS &&
1217
!clock_plugin_calendar_pointed (calendar_window, event->x_root, event->y_root))
1219
clock_plugin_hide_calendar (plugin);
1229
clock_plugin_calendar_key_press_event (GtkWidget *calendar_window,
1231
ClockPlugin *plugin)
1233
if (event->type == GDK_KEY_PRESS && event->keyval == GDK_KEY_Escape)
1235
clock_plugin_hide_calendar (plugin);
1245
clock_plugin_popup_calendar (ClockPlugin *plugin,
970
1248
if (plugin->calendar_window == NULL)
972
1250
plugin->calendar_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
991
1264
| GTK_CALENDAR_SHOW_WEEK_NUMBERS);
992
1265
g_signal_connect (G_OBJECT (plugin->calendar_window), "show",
993
1266
G_CALLBACK (clock_plugin_calendar_show_event), plugin);
994
gtk_container_add (GTK_CONTAINER (calendar_frame), plugin->calendar);
1267
g_signal_connect (G_OBJECT (plugin->calendar_window), "button-press-event",
1268
G_CALLBACK (clock_plugin_calendar_button_press_event), plugin);
1269
g_signal_connect (G_OBJECT (plugin->calendar_window), "key-press-event",
1270
G_CALLBACK (clock_plugin_calendar_key_press_event), plugin);
1271
gtk_container_add (GTK_CONTAINER (plugin->calendar_window), plugin->calendar);
995
1272
gtk_widget_show (plugin->calendar);
1275
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->button), TRUE);
998
1276
gtk_widget_show (GTK_WIDGET (plugin->calendar_window));
999
1277
xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (plugin), TRUE);
1279
clock_plugin_pointer_grab (plugin, GTK_WIDGET (plugin->calendar_window), TRUE);
1033
1313
/* keep the timeout running */
1040
clock_plugin_timeout_running (gpointer user_data)
1042
ClockPluginTimeout *timeout = user_data;
1046
GDK_THREADS_ENTER ();
1047
result = (timeout->function) (timeout->data);
1048
GDK_THREADS_LEAVE ();
1050
/* check if the timeout still runs in time if updating once a minute */
1051
if (result && timeout->interval == CLOCK_INTERVAL_MINUTE)
1053
/* sync again when we don't run on time */
1054
clock_plugin_get_localtime (&tm);
1055
timeout->restart = tm.tm_sec != 0;
1058
return result && !timeout->restart;
1064
clock_plugin_timeout_destroyed (gpointer user_data)
1066
ClockPluginTimeout *timeout = user_data;
1068
timeout->timeout_id = 0;
1070
if (G_UNLIKELY (timeout->restart))
1071
clock_plugin_timeout_set_interval (timeout, timeout->interval);
1077
clock_plugin_timeout_sync (gpointer user_data)
1079
ClockPluginTimeout *timeout = user_data;
1081
/* run the user function */
1082
if ((timeout->function) (timeout->data))
1084
/* start the real timeout */
1085
timeout->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, timeout->interval,
1086
clock_plugin_timeout_running, timeout,
1087
clock_plugin_timeout_destroyed);
1091
timeout->timeout_id = 0;
1094
/* stop the sync timeout */
1100
ClockPluginTimeout *
1101
clock_plugin_timeout_new (guint interval,
1102
GSourceFunc function,
1105
ClockPluginTimeout *timeout;
1107
panel_return_val_if_fail (interval > 0, NULL);
1108
panel_return_val_if_fail (function != NULL, NULL);
1110
timeout = g_slice_new0 (ClockPluginTimeout);
1111
timeout->interval = 0;
1112
timeout->function = function;
1113
timeout->data = data;
1114
timeout->timeout_id = 0;
1115
timeout->restart = FALSE;
1117
clock_plugin_timeout_set_interval (timeout, interval);
1125
clock_plugin_timeout_set_interval (ClockPluginTimeout *timeout,
1129
guint next_interval;
1130
gboolean restart = timeout->restart;
1132
panel_return_if_fail (timeout != NULL);
1133
panel_return_if_fail (interval > 0);
1135
/* leave if nothing changed and we're not restarting */
1136
if (!restart && timeout->interval == interval)
1138
timeout->interval = interval;
1139
timeout->restart = FALSE;
1141
/* stop running timeout */
1142
if (G_LIKELY (timeout->timeout_id != 0))
1143
g_source_remove (timeout->timeout_id);
1144
timeout->timeout_id = 0;
1146
/* run function when not restarting, leave if it returns false */
1147
if (!restart && !(timeout->function) (timeout->data))
1150
/* get the seconds to the next internal */
1151
if (interval == CLOCK_INTERVAL_MINUTE)
1153
clock_plugin_get_localtime (&tm);
1154
next_interval = 60 - tm.tm_sec;
1161
if (next_interval > 0)
1163
/* start the sync timeout */
1164
timeout->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, next_interval,
1165
clock_plugin_timeout_sync,
1170
/* directly start running the normal timeout */
1171
timeout->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval,
1172
clock_plugin_timeout_running, timeout,
1173
clock_plugin_timeout_destroyed);
1180
clock_plugin_timeout_free (ClockPluginTimeout *timeout)
1182
panel_return_if_fail (timeout != NULL);
1184
timeout->restart = FALSE;
1185
if (G_LIKELY (timeout->timeout_id != 0))
1186
g_source_remove (timeout->timeout_id);
1187
g_slice_free (ClockPluginTimeout, timeout);
1193
clock_plugin_get_localtime (struct tm *tm)
1195
time_t now = time (NULL);
1197
#ifndef HAVE_LOCALTIME_R
1200
tmbuf = localtime (&now);
1203
localtime_r (&now, tm);
1210
clock_plugin_strdup_strftime (const gchar *format,
1211
const struct tm *tm)
1213
gchar *converted, *result;
1217
/* leave when format is null */
1218
if (G_UNLIKELY (exo_str_is_empty (format)))
1221
/* convert to locale, because that's what strftime uses */
1222
converted = g_locale_from_utf8 (format, -1, NULL, NULL, NULL);
1223
if (G_UNLIKELY (converted == NULL))
1226
/* parse the time string */
1227
length = strftime (buffer, sizeof (buffer), converted, tm);
1228
if (G_UNLIKELY (length == 0))
1231
/* convert the string back to utf-8 */
1232
result = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
1243
clock_plugin_interval_from_format (const gchar *format)
1247
if (G_UNLIKELY (exo_str_is_empty (format)))
1248
return CLOCK_INTERVAL_MINUTE;
1250
for (p = format; *p != '\0'; ++p)
1252
if (p[0] == '%' && p[1] != '\0')
1263
return CLOCK_INTERVAL_SECOND;
1268
return CLOCK_INTERVAL_MINUTE;