2 * Copyright (C) 2002, 2003 Sebastian Rittau <srittau@jroger.in-berlin.de>
5 * Based on GnomeDateEdit by Miguel de Icaza.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with the Gnome Library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
22 /****************************************************************/
23 /* This file is modified for the use with gtodo. */
24 /* The following changes are made: */
25 /* - Fixed crashing when trying to set
26 a gdate withouth a valid dmy (but julian) */
27 /* - Made the entry box one char widther. this to fix that the text doesnt fit */
28 /* - Added a today and no_date button to the date popup */
29 /* And the needed interface for this. */
30 /* - The Date in the calendar is set tot the date represented by the datetime widget */
31 /****************************************************************/
41 #include <gdk/gdkkeysyms.h>
44 #include "egg-datetime.h"
49 * o "now" button in calendar popup?
51 * o Implement time list as a popup a la Evo, or time as a spin button?
52 * o In lazy mode: choose a different way to mark an invalid date instead
53 * of just blanking the widget.
57 * o limit GtkCalendar to clamp times
60 static void cal_set_today (EggDateTime
*edt
, GtkCalendar
*calendar
);
61 static void cal_set_nodate (EggDateTime
*edt
, GtkCalendar
*calendar
);
65 _add_atk_name_desc (GtkWidget *widget, gchar *name, gchar *desc)
69 g_return_if_fail (GTK_IS_WIDGET (widget));
71 aobj = gtk_widget_get_accessible (widget);
74 atk_object_set_name (aobj, name);
76 atk_object_set_description (aobj, desc);
79 /* This leaks.. and not little, so I remove this for now. */
83 _add_atk_relation (GtkWidget *widget1, GtkWidget *widget2,
84 AtkRelationType w1_to_w2, AtkRelationType w2_to_w1)
86 AtkObject *atk_widget1;
87 AtkObject *atk_widget2;
88 AtkRelationSet *relation_set;
89 AtkRelation *relation;
90 AtkObject *targets[1];
92 atk_widget1 = gtk_widget_get_accessible (widget1);
93 atk_widget2 = gtk_widget_get_accessible (widget2);
95 /* Create the widget1 -> widget2 relation */
96 /* relation_set = atk_object_ref_relation_set (atk_widget1);
97 targets[0] = atk_widget2;
98 relation = atk_relation_new (targets, 1, w1_to_w2);
99 atk_relation_set_add (relation_set, relation);
100 g_object_unref (relation);
102 /* Create the widget2 -> widget1 relation */
103 /* relation_set = atk_object_ref_relation_set (atk_widget2);
104 targets[0] = atk_widget1;
105 relation = atk_relation_new (targets, 1, w2_to_w1);
106 atk_relation_set_add (relation_set, relation);
107 g_object_unref (relation);
111 * Time List Declarations
114 #define TIMELIST(x) GTK_SCROLLED_WINDOW(x)
115 #define Timelist GtkScrolledWindow
117 static GtkWidget
*timelist_new (EggDateTime
*edt
);
118 static void timelist_set_list (Timelist
*timelist
, guint8 minhour
, guint8 minminute
, guint8 maxhour
, guint8 maxminute
);
119 static void timelist_set_time (Timelist
*timelist
, gint hour
, gint minute
);
120 static gboolean
timelist_get_time (Timelist
*timelist
, gint
*hour
, gint
*minute
);
121 static void timelist_clamp (Timelist
*timelist
, guint8 minhour
, guint8 minminute
, guint8 maxhour
, guint8 maxminute
);
122 static void timelist_set_selection_callback (Timelist
*timelist
, void (*cb
)(void), gpointer data
);
125 * Class and Object Handling
128 struct _EggDateTimePrivate
133 GtkWidget
*date_entry
;
134 GtkWidget
*date_button
;
136 GtkWidget
*time_entry
;
137 GtkWidget
*time_button
;
138 GtkWidget
*cal_popup
;
140 GtkWidget
*time_popup
;
147 EggDateTimeDisplayMode display_mode
;
149 gboolean week_start_monday
;
151 /* Current Date/Time */
164 guint16 clamp_minyear
, clamp_maxyear
;
165 guint8 clamp_minmonth
, clamp_maxmonth
;
166 guint8 clamp_minday
, clamp_maxday
;
167 guint8 clamp_minhour
, clamp_maxhour
;
168 guint8 clamp_minminute
, clamp_maxminute
;
169 guint8 clamp_minsecond
, clamp_maxsecond
;
179 ARG_DISPLAY_MODE
= 1,
202 static gint egg_datetime_signals
[SIGNAL_LAST
] = { 0 };
205 static void egg_datetime_class_init (EggDateTimeClass
*klass
);
206 static void egg_datetime_init (EggDateTime
*edt
);
207 static void egg_datetime_set_property (GObject
*object
,
211 static void egg_datetime_get_property (GObject
*object
,
216 static void egg_datetime_destroy (GtkObject
*object
);
217 static void egg_datetime_finalize (GObject
*object
);
219 static gchar
*get_time_string (guint8 hour
, guint8 minute
, guint8 second
);
221 static gboolean
date_focus_out (EggDateTime
*edt
, GtkEntry
*entry
);
222 static gboolean
time_focus_out (EggDateTime
*edt
, GtkEntry
*entry
);
223 static void date_arrow_toggled (EggDateTime
*edt
, GtkToggleButton
*button
);
224 static void time_arrow_toggled (EggDateTime
*edt
, GtkToggleButton
*button
);
225 static void cal_popup_changed (EggDateTime
*edt
, GtkCalendar
*calendar
);
226 static void cal_popup_double_click (EggDateTime
*edt
, GtkCalendar
*calendar
);
227 static gboolean
cal_popup_key_pressed (EggDateTime
*edt
, GdkEventKey
*event
, GtkWidget
*widget
);
228 static gboolean
cal_popup_button_pressed (EggDateTime
*edt
, GdkEventButton
*event
, GtkWidget
*widget
);
229 static gboolean
cal_popup_closed (EggDateTime
*edt
, GtkWindow
*popup
);
230 static void cal_popup_hide (EggDateTime
*edt
);
231 static void time_popup_changed (EggDateTime
*edt
, Timelist
*timelist
);
232 static gboolean
time_popup_key_pressed (EggDateTime
*edt
, GdkEventKey
*event
, GtkWidget
*widget
);
233 static gboolean
time_popup_button_pressed (EggDateTime
*edt
, GdkEventButton
*event
, GtkWidget
*widget
);
234 static gboolean
time_popup_closed (EggDateTime
*edt
, GtkWindow
*popup
);
235 static void time_popup_hide (EggDateTime
*edt
);
237 static void apply_display_mode (EggDateTime
*edt
);
238 static void clamp_time_labels (EggDateTime
*edt
);
239 static void parse_date (EggDateTime
*edt
);
240 static void parse_time (EggDateTime
*edt
);
241 static void normalize_date (EggDateTime
*edt
);
242 static void normalize_time (EggDateTime
*edt
);
243 static void parse_and_update_date (EggDateTime
*edt
);
244 static void parse_and_update_time (EggDateTime
*edt
);
245 static void update_date_label (EggDateTime
*edt
);
246 static void update_time_label (EggDateTime
*edt
);
249 static GtkHBoxClass
*parent_class
= NULL
;
253 egg_datetime_get_type (void)
255 static GtkType datetime_type
= 0;
257 if (!datetime_type
) {
258 static const GTypeInfo datetime_info
= {
259 sizeof (EggDateTimeClass
),
260 NULL
, /* base_init */
261 NULL
, /* base_finalize */
262 (GClassInitFunc
) egg_datetime_class_init
,
263 NULL
, /* class_finalize */
264 NULL
, /* class_data */
265 sizeof (EggDateTime
),
267 (GInstanceInitFunc
) egg_datetime_init
270 datetime_type
= g_type_register_static (GTK_TYPE_HBOX
, "EggDateTime", &datetime_info
, 0);
273 return datetime_type
;
277 egg_datetime_class_init (EggDateTimeClass
*klass
)
279 GObjectClass
*o_class
;
280 GtkObjectClass
*go_class
;
283 parent_class
= g_type_class_peek_parent (klass
);
285 o_class
= G_OBJECT_CLASS (klass
);
286 go_class
= GTK_OBJECT_CLASS (klass
);
288 o_class
->finalize
= egg_datetime_finalize
;
289 o_class
->set_property
= egg_datetime_set_property
;
290 o_class
->get_property
= egg_datetime_get_property
;
291 go_class
->destroy
= egg_datetime_destroy
;
295 pspec
= g_param_spec_uint ("display-flags",
297 _("Displayed date and/or time properties"),
298 0, G_MAXUINT
, EGG_DATETIME_DISPLAY_DATE
,
299 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
300 g_object_class_install_property (o_class
, ARG_DISPLAY_MODE
, pspec
);
301 pspec
= g_param_spec_boolean ("lazy",
303 _("Lazy mode doesn't normalize entered date and time values"),
305 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
306 g_object_class_install_property (o_class
, ARG_LAZY
, pspec
);
307 pspec
= g_param_spec_uint ("year",
311 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
312 g_object_class_install_property (o_class
, ARG_YEAR
, pspec
);
313 pspec
= g_param_spec_uint ("month",
315 _("Displayed month"),
316 G_DATE_JANUARY
, G_DATE_DECEMBER
, G_DATE_JANUARY
,
317 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
318 g_object_class_install_property (o_class
, ARG_MONTH
, pspec
);
319 pspec
= g_param_spec_uint ("day",
321 _("Displayed day of month"),
323 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
324 g_object_class_install_property (o_class
, ARG_DAY
, pspec
);
325 pspec
= g_param_spec_uint ("hour",
329 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
330 g_object_class_install_property (o_class
, ARG_HOUR
, pspec
);
331 pspec
= g_param_spec_uint ("minute",
333 _("Displayed minute"),
335 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
336 g_object_class_install_property (o_class
, ARG_MINUTE
, pspec
);
337 /* second (time) not 2nd */
338 pspec
= g_param_spec_uint ("second",
340 _("Displayed second"),
342 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
343 g_object_class_install_property (o_class
, ARG_SECOND
, pspec
);
344 pspec
= g_param_spec_uint ("clamp-minyear",
345 _("Lower limit year"),
346 _("Year part of the lower date limit"),
348 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
349 g_object_class_install_property (o_class
, ARG_CLAMP_MINYEAR
, pspec
);
350 pspec
= g_param_spec_uint ("clamp-maxyear",
351 _("Upper limit year"),
352 _("Year part of the upper date limit"),
354 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
355 g_object_class_install_property (o_class
, ARG_CLAMP_MAXYEAR
, pspec
);
356 pspec
= g_param_spec_uint ("clamp-minmonth",
357 _("Lower limit month"),
358 _("Month part of the lower date limit"),
359 G_DATE_JANUARY
, G_DATE_DECEMBER
, G_DATE_JANUARY
,
360 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
361 g_object_class_install_property (o_class
, ARG_CLAMP_MINMONTH
, pspec
);
362 pspec
= g_param_spec_uint ("clamp-maxmonth",
363 _("Upper limit month"),
364 _("Month part of the upper date limit"),
365 G_DATE_JANUARY
, G_DATE_DECEMBER
, G_DATE_DECEMBER
,
366 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
367 g_object_class_install_property (o_class
, ARG_CLAMP_MAXMONTH
, pspec
);
368 pspec
= g_param_spec_uint ("clamp-minday",
369 _("Lower limit day"),
370 _("Day of month part of the lower date limit"),
372 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
373 g_object_class_install_property (o_class
, ARG_CLAMP_MINDAY
, pspec
);
374 pspec
= g_param_spec_uint ("clamp-maxday",
375 _("Upper limit day"),
376 _("Day of month part of the upper date limit"),
378 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
379 g_object_class_install_property (o_class
, ARG_CLAMP_MAXDAY
, pspec
);
380 pspec
= g_param_spec_uint ("clamp-minhour",
381 _("Lower limit hour"),
382 _("Hour part of the lower time limit"),
384 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
385 g_object_class_install_property (o_class
, ARG_CLAMP_MINHOUR
, pspec
);
386 pspec
= g_param_spec_uint ("clamp-maxhour",
387 _("Upper limit hour"),
388 _("Hour part of the upper time limit"),
390 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
391 g_object_class_install_property (o_class
, ARG_CLAMP_MAXHOUR
, pspec
);
392 pspec
= g_param_spec_uint ("clamp-minminute",
393 _("Lower limit minute"),
394 _("Minute part of the lower time limit"),
396 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
397 g_object_class_install_property (o_class
, ARG_CLAMP_MINMINUTE
, pspec
);
398 pspec
= g_param_spec_uint ("clamp-maxminute",
399 _("Upper limit minute"),
400 _("Minute part of the upper time limit"),
402 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
403 g_object_class_install_property (o_class
, ARG_CLAMP_MAXMINUTE
, pspec
);
404 pspec
= g_param_spec_uint ("clamp-minsecond",
405 _("Lower limit second"),
406 _("Second part of the lower time limit"),
408 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
409 g_object_class_install_property (o_class
, ARG_CLAMP_MINSECOND
, pspec
);
410 pspec
= g_param_spec_uint ("clamp-maxsecond",
411 _("Upper limit second"),
412 _("Second part of the upper time limit"),
414 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
415 g_object_class_install_property (o_class
, ARG_CLAMP_MAXSECOND
, pspec
);
419 egg_datetime_signals
[SIGNAL_DATE_CHANGED
] =
420 g_signal_new ("date-changed",
421 G_TYPE_FROM_CLASS (klass
),
422 G_SIGNAL_RUN_LAST
| G_SIGNAL_ACTION
,
423 G_STRUCT_OFFSET (EggDateTimeClass
, date_changed
),
425 g_cclosure_marshal_VOID__VOID
,
428 egg_datetime_signals
[SIGNAL_TIME_CHANGED
] =
429 g_signal_new ("time-changed",
430 G_TYPE_FROM_CLASS (klass
),
431 G_SIGNAL_RUN_LAST
| G_SIGNAL_ACTION
,
432 G_STRUCT_OFFSET (EggDateTimeClass
, time_changed
),
434 g_cclosure_marshal_VOID__VOID
,
439 egg_datetime_init (EggDateTime
*edt
)
441 EggDateTimePrivate
*priv
;
442 GtkWidget
*arrow
, *hbox
, *vbox
, *frame
;
443 GtkCalendarDisplayOptions cal_options
;
444 priv
= g_new0 (EggDateTimePrivate
, 1);
447 /* Translators: Change this if you want to start weeks at mondays. */
448 priv
->week_start_monday
= strcmp (_("week-starts-monday: yes"), "week-starts-monday: yes") == 0 ? TRUE
: FALSE
;
450 priv
->date_valid
= FALSE
;
451 priv
->time_valid
= FALSE
;
453 /* Initialize Widgets */
455 gtk_box_set_spacing (GTK_BOX (edt
), 4);
459 priv
->date_box
= gtk_hbox_new (FALSE
, 0);
460 gtk_box_pack_start (GTK_BOX (edt
), priv
->date_box
, TRUE
, TRUE
, 0);
462 priv
->date_entry
= gtk_entry_new ();
463 gtk_entry_set_width_chars (GTK_ENTRY (priv
->date_entry
), 13);
465 _add_atk_name_desc (priv->date_entry, _("Date"), _("Enter the date directly"));
467 g_signal_connect_swapped (G_OBJECT (priv
->date_entry
), "focus-out-event",
468 G_CALLBACK (date_focus_out
), edt
);
469 gtk_widget_show (priv
->date_entry
);
470 gtk_box_pack_start (GTK_BOX (priv
->date_box
), priv
->date_entry
, TRUE
, TRUE
, 0);
472 priv
->date_button
= gtk_toggle_button_new ();
474 _add_atk_name_desc (priv->date_button, _("Select Date"), _("Select the date from a calendar"));
476 gtk_box_pack_start (GTK_BOX (priv
->date_box
), priv
->date_button
, FALSE
, FALSE
, 0);
477 arrow
= gtk_arrow_new (GTK_ARROW_DOWN
, GTK_SHADOW_OUT
);
478 gtk_container_add (GTK_CONTAINER (priv
->date_button
), arrow
);
479 gtk_widget_show (arrow
);
481 g_signal_connect_swapped (G_OBJECT (priv
->date_button
), "toggled",
482 G_CALLBACK (date_arrow_toggled
), edt
);
484 _add_atk_relation (priv->date_button, priv->date_entry,
485 ATK_RELATION_CONTROLLER_FOR, ATK_RELATION_CONTROLLED_BY);
489 priv
->time_box
= gtk_hbox_new (FALSE
, 0);
490 gtk_box_pack_start (GTK_BOX (edt
), priv
->time_box
, TRUE
, TRUE
, 0);
492 priv
->time_entry
= gtk_entry_new ();
493 gtk_entry_set_width_chars (GTK_ENTRY (priv
->time_entry
), 10);
495 _add_atk_name_desc (priv->time_entry, _("Time"), _("Enter the time directly"));
497 g_signal_connect_swapped (G_OBJECT (priv
->time_entry
), "focus-out-event",
498 G_CALLBACK (time_focus_out
), edt
);
499 gtk_widget_show (priv
->time_entry
);
500 gtk_box_pack_start (GTK_BOX (priv
->time_box
), priv
->time_entry
, TRUE
, TRUE
, 0);
502 priv
->time_button
= gtk_toggle_button_new ();
504 _add_atk_name_desc (priv->date_button, _("Select Time"), _("Select the time from a list"));
506 gtk_box_pack_start (GTK_BOX (priv
->time_box
), priv
->time_button
, FALSE
, FALSE
, 0);
507 arrow
= gtk_arrow_new (GTK_ARROW_DOWN
, GTK_SHADOW_OUT
);
508 gtk_container_add (GTK_CONTAINER (priv
->time_button
), arrow
);
509 gtk_widget_show (arrow
);
510 g_signal_connect_swapped (G_OBJECT (priv
->time_button
), "toggled",
511 G_CALLBACK (time_arrow_toggled
), edt
);
513 _add_atk_relation (priv->time_button, priv->time_entry,
514 ATK_RELATION_CONTROLLER_FOR, ATK_RELATION_CONTROLLED_BY);
518 priv
->cal_popup
= gtk_window_new (GTK_WINDOW_POPUP
);
519 gtk_widget_set_events (priv
->cal_popup
,
520 gtk_widget_get_events (priv
->cal_popup
) | GDK_KEY_PRESS_MASK
);
521 gtk_window_set_resizable (GTK_WINDOW (priv
->cal_popup
), FALSE
);
522 g_signal_connect_swapped (G_OBJECT (priv
->cal_popup
), "delete-event",
523 G_CALLBACK (cal_popup_closed
), edt
);
524 g_signal_connect_swapped (G_OBJECT (priv
->cal_popup
), "key-press-event",
525 G_CALLBACK (cal_popup_key_pressed
), edt
);
526 g_signal_connect_swapped (G_OBJECT (priv
->cal_popup
), "button-press-event",
527 G_CALLBACK (cal_popup_button_pressed
), edt
);
529 vbox
= gtk_vbox_new(FALSE
, 0);
530 frame
= gtk_frame_new(NULL
);
531 priv
->calendar
= gtk_calendar_new ();
532 gtk_window_set_focus(GTK_WINDOW(priv
->cal_popup
), priv
->calendar
);
533 gtk_container_add (GTK_CONTAINER (frame
), vbox
);
534 gtk_container_add (GTK_CONTAINER (priv
->cal_popup
), frame
);
535 cal_options
= GTK_CALENDAR_SHOW_DAY_NAMES
| GTK_CALENDAR_SHOW_HEADING
;
536 if (priv
->week_start_monday
)
537 cal_options
|= GTK_CALENDAR_WEEK_START_MONDAY
;
538 gtk_calendar_display_options (GTK_CALENDAR (priv
->calendar
), cal_options
);
539 gtk_box_pack_start(GTK_BOX(vbox
), priv
->calendar
, TRUE
, TRUE
,0);
540 g_signal_connect_swapped (G_OBJECT (priv
->calendar
), "day-selected",
541 G_CALLBACK (cal_popup_changed
), edt
);
542 g_signal_connect_swapped (G_OBJECT (priv
->calendar
), "day-selected-double-click",
543 G_CALLBACK (cal_popup_double_click
), edt
);
544 hbox
= gtk_hbox_new(FALSE
, 0);
545 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, FALSE
, TRUE
,0);
546 priv
->today
= gtk_button_new_with_mnemonic(_("_Today"));
547 priv
->nodate
= gtk_button_new_with_mnemonic(_("_No Date"));
548 gtk_box_pack_start(GTK_BOX(hbox
), priv
->today
, TRUE
, TRUE
,0);
549 gtk_box_pack_start(GTK_BOX(hbox
), priv
->nodate
, TRUE
, TRUE
,0);
550 g_signal_connect_swapped (G_OBJECT (priv
->today
), "clicked",
551 G_CALLBACK (cal_set_today
), edt
);
552 g_signal_connect_swapped (G_OBJECT (priv
->nodate
), "clicked",
553 G_CALLBACK (cal_set_nodate
), edt
);
556 gtk_widget_show_all(frame
);
557 gtk_widget_show(priv
->calendar
);
560 priv
->time_popup
= gtk_window_new (GTK_WINDOW_POPUP
);
561 gtk_widget_set_events (priv
->time_popup
,
562 gtk_widget_get_events (priv
->time_popup
) | GDK_KEY_PRESS_MASK
);
563 gtk_window_set_resizable (GTK_WINDOW (priv
->time_popup
), FALSE
);
564 g_signal_connect_swapped (G_OBJECT (priv
->time_popup
), "delete-event",
565 G_CALLBACK (time_popup_closed
), edt
);
566 g_signal_connect_swapped (G_OBJECT (priv
->time_popup
), "key-press-event",
567 G_CALLBACK (time_popup_key_pressed
), edt
);
568 g_signal_connect_swapped (G_OBJECT (priv
->time_popup
), "button-press-event",
569 G_CALLBACK (time_popup_button_pressed
), edt
);
571 priv
->timelist
= timelist_new (edt
);
573 gtk_window_set_default(GTK_WINDOW(priv->time_popup), gtk_bin_get_child(GTK_BIN(priv->timelist)));
575 timelist_set_selection_callback (TIMELIST (priv
->timelist
), G_CALLBACK (time_popup_changed
), edt
);
576 gtk_widget_set_size_request (priv
->timelist
, -1, 400);
577 gtk_container_add (GTK_CONTAINER (priv
->time_popup
), priv
->timelist
);
578 gtk_widget_show (priv
->timelist
);
579 if(priv
->no_date
) gtk_widget_set_sensitive(priv
->time_box
, FALSE
);
583 egg_datetime_set_property (GObject
*object
,
589 EggDateTimePrivate
*priv
;
591 g_return_if_fail (object
!= NULL
);
592 g_return_if_fail (EGG_IS_DATETIME (object
));
594 edt
= EGG_DATETIME (object
);
597 switch (property_id
) {
598 case ARG_DISPLAY_MODE
:
599 egg_datetime_set_display_mode (edt
, g_value_get_uint (value
));
602 egg_datetime_set_lazy (edt
, g_value_get_boolean (value
));
605 priv
->year
= g_value_get_uint (value
);
608 priv
->minute
= g_value_get_uint (value
);
611 priv
->day
= g_value_get_uint (value
);
614 priv
->hour
= g_value_get_uint (value
);
617 priv
->minute
= g_value_get_uint (value
);
620 priv
->second
= g_value_get_uint (value
);
622 case ARG_CLAMP_MINYEAR
:
623 priv
->clamp_minyear
= g_value_get_uint (value
);
625 case ARG_CLAMP_MINMONTH
:
626 priv
->clamp_minmonth
= g_value_get_uint (value
);
628 case ARG_CLAMP_MINDAY
:
629 priv
->clamp_minday
= g_value_get_uint (value
);
631 case ARG_CLAMP_MINHOUR
:
632 priv
->clamp_minhour
= g_value_get_uint (value
);
634 case ARG_CLAMP_MINMINUTE
:
635 priv
->clamp_minminute
= g_value_get_uint (value
);
637 case ARG_CLAMP_MINSECOND
:
638 priv
->clamp_minsecond
= g_value_get_uint (value
);
640 case ARG_CLAMP_MAXYEAR
:
641 priv
->clamp_maxyear
= g_value_get_uint (value
);
643 case ARG_CLAMP_MAXMONTH
:
644 priv
->clamp_maxmonth
= g_value_get_uint (value
);
646 case ARG_CLAMP_MAXDAY
:
647 priv
->clamp_maxday
= g_value_get_uint (value
);
649 case ARG_CLAMP_MAXHOUR
:
650 priv
->clamp_maxhour
= g_value_get_uint (value
);
652 case ARG_CLAMP_MAXMINUTE
:
653 priv
->clamp_maxminute
= g_value_get_uint (value
);
655 case ARG_CLAMP_MAXSECOND
:
656 priv
->clamp_maxsecond
= g_value_get_uint (value
);
662 egg_datetime_get_property (GObject
*object
,
667 EggDateTimePrivate
*priv
;
669 g_return_if_fail (object
!= NULL
);
670 g_return_if_fail (EGG_IS_DATETIME (object
));
672 priv
= EGG_DATETIME (object
)->priv
;
674 switch (property_id
) {
675 case ARG_DISPLAY_MODE
:
676 g_value_set_uint (value
, (guint
) priv
->display_mode
);
679 g_value_set_boolean (value
, priv
->lazy
);
682 g_value_set_uint (value
, priv
->year
);
685 g_value_set_uint (value
, priv
->month
);
688 g_value_set_uint (value
, priv
->day
);
691 g_value_set_uint (value
, priv
->hour
);
694 g_value_set_uint (value
, priv
->minute
);
697 g_value_set_uint (value
, priv
->second
);
699 case ARG_CLAMP_MINYEAR
:
700 g_value_set_uint (value
, priv
->clamp_minyear
);
702 case ARG_CLAMP_MINMONTH
:
703 g_value_set_uint (value
, priv
->clamp_minmonth
);
705 case ARG_CLAMP_MINDAY
:
706 g_value_set_uint (value
, priv
->clamp_minday
);
708 case ARG_CLAMP_MINHOUR
:
709 g_value_set_uint (value
, priv
->clamp_minhour
);
711 case ARG_CLAMP_MINMINUTE
:
712 g_value_set_uint (value
, priv
->clamp_minminute
);
714 case ARG_CLAMP_MINSECOND
:
715 g_value_set_uint (value
, priv
->clamp_minsecond
);
717 case ARG_CLAMP_MAXYEAR
:
718 g_value_set_uint (value
, priv
->clamp_maxyear
);
720 case ARG_CLAMP_MAXMONTH
:
721 g_value_set_uint (value
, priv
->clamp_maxmonth
);
723 case ARG_CLAMP_MAXDAY
:
724 g_value_set_uint (value
, priv
->clamp_maxday
);
726 case ARG_CLAMP_MAXHOUR
:
727 g_value_set_uint (value
, priv
->clamp_maxhour
);
729 case ARG_CLAMP_MAXMINUTE
:
730 g_value_set_uint (value
, priv
->clamp_maxminute
);
732 case ARG_CLAMP_MAXSECOND
:
733 g_value_set_uint (value
, priv
->clamp_maxsecond
);
739 egg_datetime_destroy (GtkObject
*object
)
741 EggDateTime
*edt
= EGG_DATETIME (object
);
742 EggDateTimePrivate
*priv
= edt
->priv
;
744 if (priv
->cal_popup
) {
745 gtk_widget_destroy (priv
->cal_popup
);
746 priv
->cal_popup
= NULL
;
749 if (priv
->time_popup
) {
750 gtk_widget_destroy (priv
->time_popup
);
751 priv
->time_popup
= NULL
;
754 if (GTK_OBJECT_CLASS (parent_class
)->destroy
)
755 (* GTK_OBJECT_CLASS (parent_class
)->destroy
) (object
);
759 egg_datetime_finalize (GObject
*object
)
761 EggDateTime
*edt
= EGG_DATETIME (object
);
765 if (G_OBJECT_CLASS (parent_class
)->finalize
)
766 (* G_OBJECT_CLASS (parent_class
)->finalize
) (object
);
773 /* Determine the number of bits, time_t uses. */
779 for (t
= 1, i
= 0; t
!= 0; t
= t
<< 1, i
++)
786 get_time_string (guint8 hour
, guint8 minute
, guint8 second
)
790 /* Translators: set this to anything else if you want to use a
793 if (!strcmp (_("24hr: no"), "24hr: yes")) {
806 /* Translators: This is hh:mm:ss AM/PM. */
807 s
= g_strdup_printf (_("%02d:%02d:%02d %s"), hour
, minute
, second
, ampm_s
);
809 /* Translators: This is hh:mm AM/PM. */
810 s
= g_strdup_printf (_("%02d:%02d %s"), hour
, minute
, ampm_s
);
813 /* Translators: This is hh:mm:ss. */
814 s
= g_strdup_printf (_("%02d:%02d:%02d"), hour
, minute
, second
);
816 /* Translators: This is hh:mm. */
817 s
= g_strdup_printf (_("%02d:%02d"), hour
, minute
);
824 popup_position (GtkWidget
*widget
, GtkWindow
*popup
)
826 GtkRequisition requisition
;
827 gint x
, y
, width
, height
;
829 gtk_widget_size_request (GTK_WIDGET (popup
), &requisition
);
830 gdk_window_get_origin (widget
->window
, &x
, &y
);
832 x
+= widget
->allocation
.x
;
833 y
+= widget
->allocation
.y
;
834 width
= widget
->allocation
.width
;
835 height
= widget
->allocation
.height
;
837 x
+= width
- requisition
.width
;
845 gtk_window_move (popup
, x
, y
);
849 popup_show (GtkWindow
*popup
)
851 /* GdkCursor *cursor;*/
853 gtk_widget_show_all (GTK_WIDGET (popup
));
854 gtk_widget_grab_focus (GTK_WIDGET (popup
));
855 gtk_grab_add (GTK_WIDGET (popup
));
857 /* Think its ugly to change the cursor.. */
859 cursor = gdk_cursor_new (GDK_ARROW);
860 gdk_pointer_grab (GTK_WIDGET (popup)->window, TRUE,
861 (GDK_BUTTON_PRESS_MASK
862 | GDK_BUTTON_RELEASE_MASK
863 | GDK_POINTER_MOTION_MASK),
864 NULL, cursor, GDK_CURRENT_TIME);
865 gdk_cursor_unref (cursor);
870 popup_hide (GtkWindow
*popup
)
872 gtk_widget_hide (GTK_WIDGET (popup
));
873 gtk_grab_remove (GTK_WIDGET (popup
));
874 gdk_pointer_ungrab (GDK_CURRENT_TIME
);
882 date_arrow_toggled (EggDateTime
*edt
, GtkToggleButton
*button
)
884 EggDateTimePrivate
*priv
= edt
->priv
;
886 if (!gtk_toggle_button_get_active (button
))
893 if(priv
->nodate
== 0)
895 gtk_calendar_select_month (GTK_CALENDAR (priv
->calendar
), priv
->month
- 1, priv
->year
);
896 gtk_calendar_select_day (GTK_CALENDAR (priv
->calendar
), priv
->day
);
901 popup_position (priv
->date_button
, GTK_WINDOW (priv
->cal_popup
));
905 popup_show (GTK_WINDOW (priv
->cal_popup
));
909 cal_popup_changed (EggDateTime
*edt
, GtkCalendar
*calendar
)
911 guint year
, month
, day
;
912 gtk_calendar_get_date (GTK_CALENDAR (edt
->priv
->calendar
), &year
, &month
, &day
);
914 edt
->priv
->no_date
= FALSE
;
916 edt
->priv
->year
= year
;
917 edt
->priv
->month
= month
+ 1;
918 edt
->priv
->day
= day
;
919 edt
->priv
->date_valid
= TRUE
;
921 normalize_date (edt
);
922 update_date_label (edt
);
924 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
928 cal_set_today (EggDateTime
*edt
, GtkCalendar
*calendar
)
931 guint year
, month
, day
;
932 edt
->priv
->no_date
= FALSE
;
935 g_date_set_time (now
, time (NULL
));
937 year
= g_date_get_year(now
);
938 month
= g_date_get_month(now
);
939 day
= g_date_get_day(now
);
941 edt
->priv
->year
= year
;
942 edt
->priv
->month
= month
;
943 edt
->priv
->day
= day
;
944 edt
->priv
->date_valid
= TRUE
;
946 gtk_calendar_select_month(GTK_CALENDAR (edt
->priv
->calendar
), month
-1, year
);
947 gtk_calendar_select_day(GTK_CALENDAR (edt
->priv
->calendar
), day
);
948 gtk_widget_show_all(edt
->priv
->calendar
);
950 gtk_calendar_set_date (GTK_CALENDAR (edt->priv->calendar), &year, &month, &day);
952 normalize_date (edt
);
953 update_date_label (edt
);
955 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
962 cal_set_nodate (EggDateTime
*edt
, GtkCalendar
*calendar
)
964 edt
->priv
->no_date
= TRUE
;
966 normalize_date (edt
);
967 update_date_label (edt
);
969 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
974 void egg_set_nodate(EggDateTime
*edt
, gboolean val
)
976 edt
->priv
->no_date
= val
;
978 normalize_date (edt
);
979 update_date_label (edt
);
981 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
985 gboolean
egg_get_nodate(EggDateTime
*edt
)
987 return edt
->priv
->no_date
;
992 cal_popup_double_click (EggDateTime
*edt
, GtkCalendar
*calendar
)
994 edt
->priv
->no_date
= FALSE
;
996 gtk_widget_set_sensitive(priv->time_box, edt->priv->no_date);
998 cal_popup_hide (edt
);
1002 cal_popup_key_pressed (EggDateTime
*edt
, GdkEventKey
*event
, GtkWidget
*widget
)
1004 if (event
->keyval
!= GDK_Escape
)
1007 g_signal_stop_emission_by_name (G_OBJECT (widget
), "key_press_event");
1009 cal_popup_hide (edt
);
1015 cal_popup_button_pressed (EggDateTime
*edt
, GdkEventButton
*event
, GtkWidget
*widget
)
1019 child
= gtk_get_event_widget ((GdkEvent
*) event
);
1021 /* We don't ask for button press events on the grab widget, so
1022 * if an event is reported directly to the grab widget, it must
1023 * be on a window outside the application (and thus we remove
1024 * the popup window). Otherwise, we check if the widget is a child
1025 * of the grab widget, and only remove the popup window if it
1028 if (child
!= widget
) {
1030 if (child
== widget
)
1032 child
= child
->parent
;
1036 cal_popup_hide (edt
);
1042 cal_popup_closed (EggDateTime
*edt
, GtkWindow
*popup
)
1044 cal_popup_hide (edt
);
1050 cal_popup_hide (EggDateTime
*edt
)
1052 EggDateTimePrivate
*priv
= edt
->priv
;
1054 popup_hide (GTK_WINDOW (priv
->cal_popup
));
1056 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv
->date_button
), FALSE
);
1057 gtk_widget_grab_focus (priv
->date_entry
);
1059 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1067 time_arrow_toggled (EggDateTime
*edt
, GtkToggleButton
*button
)
1069 EggDateTimePrivate
*priv
= edt
->priv
;
1071 if (!gtk_toggle_button_get_active (button
))
1077 /* Position Popup */
1079 popup_position (priv
->time_button
, GTK_WINDOW (priv
->time_popup
));
1082 /* dirty hack to stop it selecting the first item when showing for the first time in new window*/
1083 /* I should fix this.. because this is quiet nasty */
1085 minute
= priv
->minute
;
1086 popup_show (GTK_WINDOW (priv
->time_popup
));
1088 priv
->minute
= minute
;
1089 timelist_set_time (TIMELIST (priv
->timelist
), priv
->hour
, priv
->minute
);
1090 update_time_label(edt
);
1094 time_popup_changed (EggDateTime
*edt
, Timelist
*timelist
)
1096 EggDateTimePrivate
*priv
= edt
->priv
;
1098 if (!timelist_get_time (timelist
, &priv
->hour
, &priv
->minute
))
1102 priv
->time_valid
= TRUE
;
1104 normalize_time (edt
);
1106 if(GTK_WIDGET_VISIBLE(timelist
))update_time_label (edt
);
1108 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1112 time_popup_key_pressed (EggDateTime
*edt
, GdkEventKey
*event
, GtkWidget
*widget
)
1114 if (event
->keyval
!= GDK_Escape
)
1117 g_signal_stop_emission_by_name (G_OBJECT (widget
), "key_press_event");
1119 time_popup_hide (edt
);
1125 time_popup_button_pressed (EggDateTime
*edt
, GdkEventButton
*event
, GtkWidget
*widget
)
1129 child
= gtk_get_event_widget ((GdkEvent
*) event
);
1131 /* We don't ask for button press events on the grab widget, so
1132 * if an event is reported directly to the grab widget, it must
1133 * be on a window outside the application (and thus we remove
1134 * the popup window). Otherwise, we check if the widget is a child
1135 * of the grab widget, and only remove the popup window if it
1138 if (child
!= widget
) {
1140 if (child
== widget
)
1142 child
= child
->parent
;
1146 time_popup_hide (edt
);
1152 time_popup_closed (EggDateTime
*edt
, GtkWindow
*popup
)
1154 time_popup_hide (edt
);
1160 time_popup_hide (EggDateTime
*edt
)
1162 EggDateTimePrivate
*priv
= edt
->priv
;
1163 popup_hide (GTK_WINDOW (priv
->time_popup
));
1165 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv
->time_button
), FALSE
);
1166 gtk_widget_grab_focus (priv
->time_entry
);
1168 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1176 date_focus_out (EggDateTime
*edt
, GtkEntry
*entry
)
1179 update_date_label (edt
);
1181 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1187 time_focus_out (EggDateTime
*edt
, GtkEntry
*entry
)
1190 update_time_label (edt
);
1192 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1202 apply_display_mode (EggDateTime
*edt
)
1204 if (edt
->priv
->display_mode
& EGG_DATETIME_DISPLAY_DATE
)
1205 gtk_widget_show (edt
->priv
->date_box
);
1207 gtk_widget_hide (edt
->priv
->date_box
);
1208 if (edt
->priv
->display_mode
& EGG_DATETIME_DISPLAY_MONTH
)
1209 gtk_widget_show (edt
->priv
->date_button
);
1211 gtk_widget_hide (edt
->priv
->date_button
);
1213 if (edt
->priv
->display_mode
& EGG_DATETIME_DISPLAY_TIME
)
1214 gtk_widget_show (edt
->priv
->time_box
);
1216 gtk_widget_hide (edt
->priv
->time_box
);
1217 if (edt
->priv
->display_mode
& EGG_DATETIME_DISPLAY_HOUR
)
1218 gtk_widget_show (edt
->priv
->time_button
);
1220 gtk_widget_hide (edt
->priv
->time_button
);
1224 clamp_time_labels (EggDateTime
*edt
)
1226 EggDateTimePrivate
*priv
= edt
->priv
;
1228 timelist_clamp (TIMELIST (priv
->timelist
),
1229 priv
->clamp_minhour
,
1230 priv
->clamp_minminute
,
1231 priv
->clamp_maxhour
,
1232 priv
->clamp_maxminute
);
1235 /* Updates the date entry to the current date. */
1237 update_date_label (EggDateTime
*edt
)
1239 EggDateTimePrivate
*priv
= edt
->priv
;
1241 gtk_widget_set_sensitive(priv
->time_box
, !priv
->no_date
);
1244 gtk_entry_set_text(GTK_ENTRY(priv
->date_entry
), _("No Date"));
1248 if (!priv
->date_valid
) {
1249 gtk_entry_set_text (GTK_ENTRY (priv
->date_entry
), "");
1253 /* TODO: should handle other display modes as well... */
1255 /* Translators: This is yyyy-mm-dd. */
1256 s
= g_strdup_printf (_("%04d-%02d-%02d"), priv
->year
, priv
->month
, priv
->day
);
1257 gtk_entry_set_text (GTK_ENTRY (priv
->date_entry
), s
);
1261 /* Updates the time entry to the current time. */
1263 update_time_label (EggDateTime
*edt
)
1265 EggDateTimePrivate
*priv
= edt
->priv
;
1268 if (!priv
->time_valid
) {
1269 gtk_entry_set_text (GTK_ENTRY (priv
->time_entry
), "");
1273 /* TODO: should handle other display modes as well... */
1275 if ((priv
->display_mode
& EGG_DATETIME_DISPLAY_SECOND
) ||
1276 (priv
->display_mode
& EGG_DATETIME_DISPLAY_SECOND_OPT
))
1277 s
= get_time_string (priv
->hour
, priv
->minute
, priv
->second
);
1279 if(priv
->hour
== -1 && priv
->minute
== 0)
1280 s
= g_strdup(_("no end time"));
1281 else s
= get_time_string (priv
->hour
, priv
->minute
, 0xff);
1283 gtk_entry_set_text (GTK_ENTRY (priv
->time_entry
), s
);
1288 /* Parse the current date entry and normalize the date. */
1290 parse_date (EggDateTime
*edt
)
1293 g_date_set_parse (&date
, gtk_entry_get_text (GTK_ENTRY (edt
->priv
->date_entry
)));
1294 if (!g_date_valid (&date
)) {
1295 edt
->priv
->no_date
= TRUE
;
1296 gtk_entry_set_text(GTK_ENTRY(edt
->priv
->date_entry
), _("No Date"));
1300 edt
->priv
->year
= date
.year
;
1301 edt
->priv
->month
= date
.month
;
1302 edt
->priv
->day
= date
.day
;
1303 edt
->priv
->date_valid
= TRUE
;
1305 normalize_date (edt
);
1308 /* Parse the current time entry and normalize the time. */
1310 parse_time (EggDateTime
*edt
)
1314 unsigned int hour
, minute
, second
= 0;
1315 size_t len1
, len2
, len3
;
1317 /* Retrieve and Parse String */
1319 s
= gtk_entry_get_text (GTK_ENTRY (edt
->priv
->time_entry
));
1321 /* Translators: This is hh:mm:ss AM/PM. */
1322 if (sscanf (s
, _("%u:%u:%u"), &hour
, &minute
, &second
) < 2) {
1323 if (sscanf (s
, "%u:%u:%u", &hour
, &minute
, &second
) < 2) {
1324 if (edt
->priv
->lazy
)
1325 edt
->priv
->time_valid
= FALSE
;
1330 if (hour
> 23 || minute
> 59 || second
> 59) {
1331 if (edt
->priv
->lazy
)
1332 edt
->priv
->time_valid
= FALSE
;
1336 /* AM/PM Handling */
1339 scp
= g_strchomp (scp
);
1341 len1
= strlen (_("AM"));
1342 len2
= strlen (_("PM"));
1343 len3
= strlen (scp
);
1345 if (len1
< len3
&& !strcasecmp (scp
+ len3
- len1
, _("AM"))) {
1349 if (len2
< len3
&& !strcasecmp (scp
+ len3
- len2
, _("PM"))) {
1357 edt
->priv
->hour
= hour
;
1358 edt
->priv
->minute
= minute
;
1359 edt
->priv
->second
= second
;
1360 edt
->priv
->time_valid
= TRUE
;
1366 normalize_time (edt
);
1369 /* Clamp the current date to the date clamp range if lazy is turned off. */
1371 normalize_date (EggDateTime
*edt
)
1373 GDate date
, min_date
, max_date
;
1375 if (edt
->priv
->lazy
)
1378 g_date_clear (&date
, 1);
1379 g_date_set_dmy (&date
, edt
->priv
->day
, edt
->priv
->month
, edt
->priv
->year
);
1380 g_date_clear (&min_date
, 1);
1381 g_date_set_dmy (&min_date
, edt
->priv
->clamp_minday
, edt
->priv
->clamp_minmonth
, edt
->priv
->clamp_minyear
);
1382 g_date_clear (&max_date
, 1);
1383 g_date_set_dmy (&max_date
, edt
->priv
->clamp_maxday
, edt
->priv
->clamp_maxmonth
, edt
->priv
->clamp_maxyear
);
1385 g_date_clamp (&date
, &min_date
, &max_date
);
1387 edt
->priv
->year
= date
.year
;
1388 edt
->priv
->month
= date
.month
;
1389 edt
->priv
->day
= date
.day
;
1390 edt
->priv
->date_valid
= TRUE
;
1393 /* Clamp the current time to the time clamp range if lazy is turned off. */
1395 normalize_time (EggDateTime
*edt
)
1397 if (edt
->priv
->lazy
)
1400 if (edt
->priv
->hour
< edt
->priv
->clamp_minhour
) {
1401 edt
->priv
->hour
= -1;;
1402 edt
->priv
->minute
= edt
->priv
->clamp_minminute
;
1403 edt
->priv
->second
= edt
->priv
->clamp_minsecond
;
1404 } else if (edt
->priv
->hour
== edt
->priv
->clamp_minhour
) {
1405 if (edt
->priv
->minute
< edt
->priv
->clamp_minminute
) {
1406 edt
->priv
->minute
= edt
->priv
->clamp_minminute
;
1407 edt
->priv
->second
= edt
->priv
->clamp_minsecond
;
1408 } else if (edt
->priv
->minute
== edt
->priv
->clamp_minminute
) {
1409 if (edt
->priv
->second
< edt
->priv
->clamp_minsecond
)
1410 edt
->priv
->second
= edt
->priv
->clamp_minsecond
;
1414 if (edt
->priv
->hour
> edt
->priv
->clamp_maxhour
) {
1415 edt
->priv
->hour
= edt
->priv
->clamp_maxhour
;
1416 edt
->priv
->minute
= edt
->priv
->clamp_maxminute
;
1417 edt
->priv
->second
= edt
->priv
->clamp_maxsecond
;
1418 } else if (edt
->priv
->hour
== edt
->priv
->clamp_maxhour
) {
1419 if (edt
->priv
->minute
> edt
->priv
->clamp_maxminute
) {
1420 edt
->priv
->minute
= edt
->priv
->clamp_maxminute
;
1421 edt
->priv
->second
= edt
->priv
->clamp_maxsecond
;
1422 } else if (edt
->priv
->minute
== edt
->priv
->clamp_maxminute
) {
1423 if (edt
->priv
->second
> edt
->priv
->clamp_maxsecond
)
1424 edt
->priv
->second
= edt
->priv
->clamp_maxsecond
;
1428 edt
->priv
->time_valid
= TRUE
;
1432 parse_and_update_date (EggDateTime
*edt
)
1434 if (edt
->priv
->lazy
)
1438 update_date_label (edt
);
1442 parse_and_update_time (EggDateTime
*edt
)
1444 if (edt
->priv
->lazy
)
1448 update_time_label (edt
);
1458 * Creates a new #EggDateTime widget. By default this widget will show
1459 * only the date component and is set to the current date and time.
1461 * Return value: a newly created #EggDateTime widget
1464 egg_datetime_new (void)
1468 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1469 egg_datetime_set_from_time_t (edt
, time (NULL
));
1471 return GTK_WIDGET (edt
);
1475 * egg_datetime_new_from_time_t:
1476 * @t: initial time and date
1478 * Creates a new #EggDateTime widget and sets it to the date and time
1479 * given as @t argument. This does also call egg_datetime_set_clamp_time_t().
1480 * By default this widget will show only the date component.
1482 * Return value: a newly created #EggDateTime widget
1485 egg_datetime_new_from_time_t (time_t t
)
1489 g_return_val_if_fail (t
>= 0, NULL
);
1491 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1492 egg_datetime_set_from_time_t (edt
, t
);
1493 egg_datetime_set_clamp_time_t (edt
);
1495 return GTK_WIDGET (edt
);
1499 * egg_datetime_new_from_struct_tm:
1500 * @tm: initial time and date
1502 * Creates a new #EggDateTime widget and sets it to the date and time
1503 * given as @tm argument. By default this widget will show only the date
1506 * Return value: a newly created #EggDateTime widget
1509 egg_datetime_new_from_struct_tm (struct tm
*tm
)
1513 g_return_val_if_fail (tm
!= NULL
, NULL
);
1515 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1516 egg_datetime_set_from_struct_tm (edt
, tm
);
1518 return GTK_WIDGET (edt
);
1522 * egg_datetime_new_from_gdate:
1523 * @date: initial time and date
1525 * Creates a new #EggDateTime widget and sets it to the date and time
1526 * given as @date argument. By default this widget will show only the
1529 * Return value: a newly created #EggDateTime widget
1532 egg_datetime_new_from_gdate (GDate
*date
)
1536 g_return_val_if_fail (date
!= NULL
, NULL
);
1538 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1539 egg_datetime_set_from_gdate (edt
, date
);
1541 return GTK_WIDGET (edt
);
1545 * egg_datetime_new_from_datetime:
1546 * @year: initial year
1547 * @month: initial month
1549 * @hour: initial hour
1550 * @minute: initial minute
1551 * @second: initial second
1553 * Creates a new #EggDateTime widget and sets it to the date and time
1554 * given as arguments.
1556 * Return value: a newly created #EggDateTime widget
1559 egg_datetime_new_from_datetime (GDateYear year
, GDateMonth month
, GDateDay day
, guint8 hour
, guint8 minute
, guint8 second
)
1563 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1564 egg_datetime_set_date (edt
, year
, month
, day
);
1565 egg_datetime_set_time (edt
, hour
, minute
, second
);
1567 return GTK_WIDGET (edt
);
1571 * egg_datetime_set_none:
1572 * @edt: an #EggDateTime
1574 * Sets the date to an invalid value. If lazy mode is turned off the date
1575 * and time will be set to a random value.
1578 egg_datetime_set_none (EggDateTime
*edt
)
1580 g_return_if_fail (edt
!= NULL
);
1581 g_return_if_fail (EGG_IS_DATETIME (edt
));
1583 edt
->priv
->date_valid
= FALSE
;
1584 edt
->priv
->time_valid
= FALSE
;
1586 update_date_label (edt
);
1587 update_time_label (edt
);
1589 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1590 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1594 * egg_datetime_set_from_time_t:
1595 * @edt: an #EggDateTime
1596 * @t: date and time to set the widget to
1598 * Sets the date and time of the widget to @t.
1601 egg_datetime_set_from_time_t (EggDateTime
*edt
, time_t t
)
1605 g_return_if_fail (edt
!= NULL
);
1606 g_return_if_fail (EGG_IS_DATETIME (edt
));
1608 if (localtime_r (&t
, &tm
)) {
1609 egg_datetime_set_date (edt
, tm
.tm_year
+ 1900, tm
.tm_mon
+ 1, tm
.tm_mday
);
1610 egg_datetime_set_time (edt
, tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
);
1612 egg_datetime_set_none (edt
);
1616 * egg_datetime_get_as_time_t:
1617 * @edt: an #EggDateTime
1618 * @t: pointer to a %time_t value
1620 * Returns the current time as a %time_t value. If the currently entered
1621 * value is invalid and lazy mode is turned on or if the entered date
1622 * can't be represented as a %time_t value, the value is set to -1 and
1623 * FALSE is returned.
1625 * Return value: success indicator
1628 egg_datetime_get_as_time_t (EggDateTime
*edt
, time_t *t
)
1634 gint hour
, minute
, second
;
1636 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1637 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1642 if (!egg_datetime_get_date (edt
, &year
, &month
, &day
)) {
1646 if (!egg_datetime_get_time (edt
, &hour
, &minute
, &second
)) {
1651 memset (&tm
, 0, sizeof (struct tm
));
1652 tm
.tm_year
= year
- 1900;
1653 tm
.tm_mon
= month
- 1;
1670 * egg_datetime_set_from_struct_tm:
1671 * @edt: an #EggDateTime
1672 * @tm: date and time to set the widget to
1674 * Sets the date and time of the widget to @tm.
1677 egg_datetime_set_from_struct_tm (EggDateTime
*edt
, struct tm
*tm
)
1679 g_return_if_fail (edt
!= NULL
);
1680 g_return_if_fail (EGG_IS_DATETIME (edt
));
1681 g_return_if_fail (tm
!= NULL
);
1683 egg_datetime_set_date (edt
, tm
->tm_year
+ 1900, tm
->tm_mon
+ 1, tm
->tm_mday
);
1684 egg_datetime_set_time (edt
, tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
1688 * egg_datetime_get_as_struct_tm:
1689 * @edt: an #EggDateTime
1690 * @tm: pointer to an allocated struct tm
1692 * Fill the supplied struct tm with the widget's current date and time.
1693 * If the currently entered value is invalid and lazy mode is turned
1694 * on or if the entered date can't be represented as a struct tm, the
1695 * struct is filled with invalid data and FALSE is returned.
1697 * Return value: success indicator
1700 egg_datetime_get_as_struct_tm (EggDateTime
*edt
, struct tm
*tm
)
1705 gint hour
, minute
, second
;
1707 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1708 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1713 memset (tm
, 0, sizeof (struct tm
));
1715 if (!egg_datetime_get_date (edt
, &year
, &month
, &day
))
1717 if (!egg_datetime_get_time (edt
, &hour
, &minute
, &second
))
1720 tm
->tm_year
= year
- 1900;
1721 tm
->tm_mon
= month
- 1;
1724 tm
->tm_min
= minute
;
1725 tm
->tm_sec
= second
;
1733 * egg_datetime_set_from_gdate:
1734 * @edt: an #EggDateTime
1735 * @date: date to set the widget to
1737 * Sets the date of the widget to @date. The time will remain unchanged.
1740 egg_datetime_set_from_gdate (EggDateTime
*edt
, GDate
*date
)
1746 g_return_if_fail (edt
!= NULL
);
1747 g_return_if_fail (EGG_IS_DATETIME (edt
));
1748 g_return_if_fail (date
!= NULL
);
1750 year
= g_date_get_year(date
);
1751 month
= g_date_get_month(date
);
1752 day
= g_date_get_day(date
);
1753 g_return_if_fail(g_date_valid_dmy(day
, month
, year
));
1755 if (g_date_valid (date
))
1756 egg_datetime_set_date (edt
, year
, month
, day
);
1758 egg_datetime_set_none (edt
);
1762 * egg_datetime_get_as_gdate:
1763 * @edt: an #EggDateTime
1764 * @date: pointer to an allocated #GDate
1766 * Fills the supplied #GDate with the widget's current date. If the
1767 * currently entered date value is invalid and lazy mode is turned
1768 * on or if the entered date can't be represented as a #GDate, the
1769 * @date is set to an invalid value and FALSE is returned.
1771 * Return value: success indicator
1774 egg_datetime_get_as_gdate (EggDateTime
*edt
, GDate
*date
)
1780 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1781 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1786 g_date_clear (date
, 1);
1788 if (!egg_datetime_get_date (edt
, &year
, &month
, &day
))
1791 g_date_set_dmy (date
, day
, month
, year
);
1797 * egg_datetime_set_date:
1798 * @edt: an #EggDateTime
1799 * @year: a #guint16 between 1 and 9999
1800 * @month: a #guint8 between 1 and 12
1801 * @day: a #guint8 between 1 and 28-31 (depending on @month)
1803 * Sets the date of the widget. The time will remain unchanged.
1806 egg_datetime_set_date (EggDateTime
*edt
, GDateYear year
, GDateMonth month
, GDateDay day
)
1808 g_return_if_fail (edt
!= NULL
);
1809 g_return_if_fail (EGG_IS_DATETIME (edt
));
1810 g_return_if_fail (year
>= 1 && year
<= 9999);
1811 g_return_if_fail (month
>= 1 && month
<= 12);
1812 g_return_if_fail (day
>= 1 && day
<= g_date_get_days_in_month (month
, year
));
1814 edt
->priv
->year
= year
;
1815 edt
->priv
->month
= month
;
1816 edt
->priv
->day
= day
;
1817 edt
->priv
->date_valid
= TRUE
;
1818 gtk_calendar_select_month(GTK_CALENDAR(edt
->priv
->calendar
), month
-1, year
);
1819 gtk_calendar_select_day(GTK_CALENDAR(edt
->priv
->calendar
), day
);
1821 normalize_date (edt
);
1822 update_date_label (edt
);
1824 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1828 * egg_datetime_get_date:
1829 * @edt: an #EggDateTime
1830 * @year: a pointer to a #guint16 or %NULL
1831 * @month: a pointer to #guint8 or %NULL
1832 * @day: a pointer to a #guint8 or %NULL
1834 * Fills the supplied arguments with the widget's current date. If the
1835 * currently entered date value is invalid and lazy mode is turned
1836 * on, the arguments are set to %EGG_DATETIME_INVALID_DATE and FALSE
1839 * Return value: success indicator
1842 egg_datetime_get_date (EggDateTime
*edt
, GDateYear
*year
, GDateMonth
*month
, GDateDay
*day
)
1844 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1845 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1849 if (!edt
->priv
->date_valid
) {
1860 *year
= edt
->priv
->year
;
1862 *month
= edt
->priv
->month
;
1864 *day
= edt
->priv
->day
;
1870 * egg_datetime_set_time:
1871 * @edt: an #EggDateTime
1872 * @hour: a #guint8 between 0 and 23
1873 * @minute: a #guint8 between 0 and 59
1874 * @second: a #guint8 between 0 and 59
1876 * Sets the time of the widget. The date will remain unchanged.
1879 egg_datetime_set_time (EggDateTime
*edt
, gint hour
, gint minute
, guint8 second
)
1881 g_return_if_fail (edt
!= NULL
);
1882 g_return_if_fail (EGG_IS_DATETIME (edt
));
1883 g_return_if_fail (hour
<= 23);
1884 g_return_if_fail (minute
<= 59);
1885 g_return_if_fail (second
<= 59);
1887 edt
->priv
->hour
= hour
;
1888 edt
->priv
->minute
= minute
;
1889 edt
->priv
->second
= second
;
1890 edt
->priv
->time_valid
= TRUE
;
1892 normalize_time (edt
);
1893 update_time_label (edt
);
1895 timelist_set_time(edt->priv->timelist, hour, minute);
1897 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1901 * egg_datetime_get_date:
1902 * @edt: an #EggDateTime
1903 * @hour: a pointer to a #guint8 or %NULL
1904 * @minute: a pointer to #guint8 or %NULL
1905 * @second: a pointer to a #guint8 or %NULL
1907 * Fills the supplied arguments with the widget's current time. If the
1908 * currently entered time value is invalid and lazy mode is turned
1909 * on, the arguments are set to %EGG_DATETIME_INVALID_TIME and FALSE
1912 * Return value: success indicator
1915 egg_datetime_get_time (EggDateTime
*edt
, gint
*hour
, gint
*minute
, gint
*second
)
1917 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1918 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1922 if (!edt
->priv
->time_valid
) {
1933 *hour
= edt
->priv
->hour
;
1935 *minute
= edt
->priv
->minute
;
1937 *second
= edt
->priv
->second
;
1943 * egg_datetime_set_lazy:
1944 * @edt: an #EggDateTime
1945 * @lazy: a boolean value
1947 * Turns the widget's lazy mode on or off. In lazy mode the widget will
1948 * allow invalid values to be entered. If lazy mode is turned off the
1949 * widget will normalize all invalid values entered in the date and time
1950 * widgets to the nearest valid value. This guarantees that the get methods
1951 * will always return valid values.
1953 * Lazy mode defaults to %TRUE.
1956 egg_datetime_set_lazy (EggDateTime
*edt
, gboolean lazy
)
1958 g_return_if_fail (edt
!= NULL
);
1959 g_return_if_fail (EGG_IS_DATETIME (edt
));
1961 edt
->priv
->lazy
= lazy
? TRUE
: FALSE
;
1963 parse_and_update_date (edt
);
1964 parse_and_update_time (edt
);
1966 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1967 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1971 * egg_datetime_get_lazy:
1972 * @edt: an #EggDateTime
1974 * Returns whether the widget is in lazy mode.
1976 * Return value: a boolean value
1979 egg_datetime_get_lazy (EggDateTime
*edt
)
1981 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1982 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1984 return edt
->priv
->lazy
;
1988 * egg_datetime_set_display_mode:
1989 * @edt: an #EggDateTime
1990 * @mode: new display mode
1992 * Sets the widget's new display mode to @mode. The display mode defaults
1993 * to %EGG_DATETIME_DISPLAY_DATE.
1996 egg_datetime_set_display_mode (EggDateTime
*edt
, EggDateTimeDisplayMode mode
)
1998 g_return_if_fail (edt
!= NULL
);
1999 g_return_if_fail (EGG_IS_DATETIME (edt
));
2001 edt
->priv
->display_mode
= mode
;
2003 apply_display_mode (edt
);
2007 * egg_datetime_get_display_mode:
2008 * @edt: an #EggDateTime
2010 * Returns the current display mode.
2012 * Return value: The current display mode.
2014 EggDateTimeDisplayMode
2015 egg_datetime_get_display_mode (EggDateTime
*edt
)
2017 g_return_val_if_fail (edt
!= NULL
, 0);
2018 g_return_val_if_fail (EGG_IS_DATETIME (edt
), 0);
2020 return edt
->priv
->display_mode
;
2024 * egg_datetime_set_clamp_date:
2025 * @edt: an #EggDateTime
2026 * @minyear: minimum year
2027 * @minmonth: minimum month
2028 * @minday: minimum day
2029 * @maxyear: maximum year
2030 * @maxmonth: maximum month
2031 * @maxday: maximum day
2033 * Limits the allowed dates to the range given. If lazy mode is
2034 * turned off, dates that are outside of this range are snapped to the
2035 * minimum or maximum date. Otherwise such dates return an invalid value.
2037 * This defaults to the minimum date 1-1-1 and maximum date 9999-12-31.
2038 * The maximum year is always limited to 9999.
2041 egg_datetime_set_clamp_date (EggDateTime
*edt
,
2043 GDateMonth minmonth
,
2046 GDateMonth maxmonth
,
2052 g_return_if_fail (minyear
>= 1 && minyear
<= 9999 && maxyear
>= 1);
2053 g_return_if_fail (minmonth
>= 1 && minmonth
<= 12 && maxmonth
>= 1 && maxmonth
<= 12);
2054 g_return_if_fail (minday
>= 1 && minday
<= g_date_get_days_in_month (minmonth
, minyear
));
2055 g_return_if_fail (maxday
>= 1 && maxday
<= g_date_get_days_in_month (maxmonth
, maxyear
));
2056 g_return_if_fail (minyear
<= maxyear
);
2057 g_return_if_fail (minyear
< maxyear
|| minmonth
<= maxmonth
);
2058 g_return_if_fail (minyear
< maxyear
|| minmonth
< maxmonth
|| minday
<= maxday
);
2060 edt
->priv
->clamp_minyear
= minyear
;
2061 edt
->priv
->clamp_minmonth
= minmonth
;
2062 edt
->priv
->clamp_minday
= minday
;
2063 edt
->priv
->clamp_maxyear
= maxyear
;
2064 edt
->priv
->clamp_maxmonth
= maxmonth
;
2065 edt
->priv
->clamp_maxday
= maxday
;
2067 parse_and_update_date (edt
);
2069 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
2073 * egg_datetime_set_clamp_time:
2074 * @edt: an #EggDateTime
2075 * @minhour: minimum hour
2076 * @minminute: minimum minute
2077 * @minsecond: minimum second
2078 * @maxhour: maximum hour
2079 * @maxminute: maximum minute
2080 * @maxsecond: maximum second
2082 * Limits the allowed times to the range given. If lazy mode is turned
2083 * off, times that are outside of this range are snapped to the minimum or
2084 * maximum time. Otherwise such times return an invalid value.
2087 egg_datetime_set_clamp_time (EggDateTime
*edt
, guint8 minhour
, guint8 minminute
, guint8 minsecond
, guint8 maxhour
, guint8 maxminute
, guint8 maxsecond
)
2089 g_return_if_fail (minhour
<= 23 && maxhour
<= 23);
2090 g_return_if_fail (minminute
<= 59 && maxminute
<= 59);
2091 g_return_if_fail (minsecond
<= 59 && maxsecond
<= 59);
2092 g_return_if_fail (minhour
<= maxhour
);
2093 g_return_if_fail (minhour
< maxhour
|| minminute
<= maxminute
);
2094 g_return_if_fail (minhour
< maxhour
|| minminute
< maxminute
|| minsecond
<= maxsecond
);
2096 edt
->priv
->clamp_minhour
= minhour
;
2097 edt
->priv
->clamp_minminute
= minminute
;
2098 edt
->priv
->clamp_minsecond
= minsecond
;
2099 edt
->priv
->clamp_maxhour
= maxhour
;
2100 edt
->priv
->clamp_maxminute
= maxminute
;
2101 edt
->priv
->clamp_maxsecond
= maxsecond
;
2103 clamp_time_labels (edt
);
2104 parse_and_update_time (edt
);
2106 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
2110 * egg_datetime_set_clamp_time_t:
2111 * @edt: an #EggDateTime
2113 * Clamps the allowed dates of the widget to valid #time_t values.
2114 * The time clamp settings are not changed.
2117 egg_datetime_set_clamp_time_t (EggDateTime
*edt
)
2120 struct tm start_tm
, end_tm
;
2125 g_return_if_fail (edt
!= NULL
);
2126 g_return_if_fail (EGG_IS_DATETIME (edt
));
2129 gmtime_r (&t
, &start_tm
);
2132 bits
= time_t_bits ();
2134 t
&= ~(1 << (bits
- 1));
2136 gmtime_r (&t
, &end_tm
);
2138 /* Subtract one day from the end date, since not all times of
2139 * the last day can be represented.
2142 year
= end_tm
.tm_year
+ 1900;
2143 month
= end_tm
.tm_mon
+ 1;
2144 day
= end_tm
.tm_mday
;
2152 day
= g_date_get_days_in_month (month
, year
);
2155 egg_datetime_set_clamp_date (edt
, start_tm
.tm_year
+ 1900, start_tm
.tm_mon
+ 1, start_tm
.tm_mday
, year
, month
, day
);
2159 * egg_datetime_get_clamp_date:
2160 * @edt: an #EggDateTime
2161 * @minyear: #guint16 pointer or %NULL
2162 * @minmonth: #guint8 pointer or %NULL
2163 * @minday: #guint8 pointer or %NULL
2164 * @maxyear: #guint16 pointer or %NULL
2165 * @maxmonth: #guint8 pointer or %NULL
2166 * @maxday: #guint8 pointer or %NULL
2168 * Returns the current date limit settings.
2171 egg_datetime_get_clamp_date (EggDateTime
*edt
,
2173 GDateMonth
*minmonth
,
2176 GDateMonth
*maxmonth
,
2179 g_return_if_fail (edt
!= NULL
);
2180 g_return_if_fail (EGG_IS_DATETIME (edt
));
2183 *minyear
= edt
->priv
->clamp_minyear
;
2185 *minmonth
= edt
->priv
->clamp_minmonth
;
2187 *minday
= edt
->priv
->clamp_minday
;
2189 *maxyear
= edt
->priv
->clamp_maxyear
;
2191 *maxmonth
= edt
->priv
->clamp_maxmonth
;
2193 *maxday
= edt
->priv
->clamp_maxday
;
2197 * egg_datetime_get_clamp_time:
2198 * @edt: an #EggDateTime
2199 * @minhour: #guint8 pointer or %NULL
2200 * @minminute: #guint8 pointer or %NULL
2201 * @minsecond: #guint8 pointer or %NULL
2202 * @maxhour: #guint8 pointer or %NULL
2203 * @maxminute: #guint8 pointer or %NULL
2204 * @maxsecond: #guint8 pointer or %NULL
2206 * Returns the current time limit settings.
2209 egg_datetime_get_clamp_time (EggDateTime
*edt
, guint8
*minhour
, guint8
*minminute
, guint8
*minsecond
, guint8
*maxhour
, guint8
*maxminute
, guint8
*maxsecond
)
2211 g_return_if_fail (edt
!= NULL
);
2212 g_return_if_fail (EGG_IS_DATETIME (edt
));
2215 *minhour
= edt
->priv
->clamp_minhour
;
2217 *minminute
= edt
->priv
->clamp_minminute
;
2219 *minsecond
= edt
->priv
->clamp_minsecond
;
2221 *maxhour
= edt
->priv
->clamp_maxhour
;
2223 *maxminute
= edt
->priv
->clamp_maxminute
;
2225 *maxsecond
= edt
->priv
->clamp_maxsecond
;
2229 * egg_datetime_get_date_layout:
2230 * @edt: an #EggDateTime
2232 * Gets the PangoLayout used to display the date. See gtk_entry_get_layout()
2233 * for more information. The returned layout is owned by the date/time
2234 * widget so need not be freed by the caller.
2236 * Return value: the #PangoLayout for this widget's date part
2239 egg_datetime_get_date_layout (EggDateTime
*edt
)
2241 g_return_val_if_fail (edt
!= NULL
, NULL
);
2242 g_return_val_if_fail (EGG_IS_DATETIME (edt
), NULL
);
2244 return gtk_entry_get_layout (GTK_ENTRY (edt
->priv
->date_entry
));
2248 * egg_datetime_get_time_layout:
2249 * @edt: an #EggDateTime
2251 * Gets the PangoLayout used to display the time. See gtk_entry_get_layout()
2252 * for more information. The returned layout is owned by the date/time
2253 * widget so need not be freed by the caller.
2255 * Return value: the #PangoLayout for this widget's time part
2258 egg_datetime_get_time_layout (EggDateTime
*edt
)
2260 g_return_val_if_fail (edt
!= NULL
, NULL
);
2261 g_return_val_if_fail (EGG_IS_DATETIME (edt
), NULL
);
2263 return gtk_entry_get_layout (GTK_ENTRY (edt
->priv
->time_entry
));
2266 /**************************************************************************/
2268 /* This is a private time list widget implementation for use as time popup.
2272 timelist_new (EggDateTime
*edt
)
2274 GtkWidget
*timelist
;
2276 GtkListStore
*model
;
2277 GtkTreeSelection
*selection
;
2278 GtkCellRenderer
*renderer
;
2280 timelist
= gtk_scrolled_window_new (NULL
, NULL
);
2281 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (timelist
),
2285 model
= gtk_list_store_new (2, G_TYPE_STRING
, G_TYPE_UINT
);
2286 list
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (model
));
2287 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list
), FALSE
);
2288 gtk_widget_show (list
);
2290 renderer
= gtk_cell_renderer_text_new ();
2291 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (list
),
2298 gtk_container_add (GTK_CONTAINER (timelist
), list
);
2300 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (list
));
2301 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
2302 g_signal_connect_swapped(G_OBJECT(list
), "row-activated", G_CALLBACK(time_popup_hide
), edt
);
2303 timelist_set_list (TIMELIST (timelist
), 00, 00, 23, 59);
2309 timelist_set_list (Timelist
*timelist
,
2310 guint8 minhour
, guint8 minminute
,
2311 guint8 maxhour
, guint8 maxminute
)
2313 GtkWidget
*tree
= gtk_bin_get_child (GTK_BIN (timelist
));
2314 GtkTreeModel
*model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
));
2315 gint minidx
, maxidx
;
2319 minidx
= minhour
* 2 + (minminute
+ 29) / 30;
2320 maxidx
= maxhour
* 2 + (maxminute
+ 29) / 30;
2322 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
2323 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
2324 0, _("no end time"),
2328 for (i
= minidx
; i
< maxidx
; i
++) {
2333 minute
= (i
% 2) * 30;
2335 s
= get_time_string (hour
, minute
, 0xff);
2337 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
2338 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
2340 1, hour
* 100 + minute
,
2348 timelist_set_time (Timelist
*timelist
, gint hour
, gint minute
)
2350 GtkWidget
*tree
= gtk_bin_get_child (GTK_BIN (timelist
));
2351 GtkTreeModel
*model
;
2352 GtkTreeSelection
*selection
;
2355 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
));
2356 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
2358 if (!gtk_tree_model_get_iter_first (model
, &iter
))
2365 gtk_tree_model_get (model
, &iter
, 1, &time
, -1);
2367 if (time
/ 100 == hour
&& time
% 100 == minute
) {
2368 gtk_tree_selection_select_iter (selection
, &iter
);
2372 } while (gtk_tree_model_iter_next (model
, &iter
));
2374 gtk_tree_selection_unselect_all (selection
);
2378 timelist_get_time (Timelist
*timelist
, gint
*hour
, gint
*minute
)
2380 GtkWidget
*tree
= gtk_bin_get_child (GTK_BIN (timelist
));
2381 GtkTreeSelection
*selection
;
2382 GtkTreeModel
*model
;
2386 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
2388 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
2393 gtk_tree_model_get (model
, &iter
, 1, &time
, -1);
2405 *minute
= time
% 100;
2411 timelist_clamp (Timelist
*timelist
,
2412 guint8 minhour
, guint8 minminute
,
2413 guint8 maxhour
, guint8 maxminute
)
2415 timelist_set_list (timelist
, minhour
, minminute
, maxhour
, maxminute
);
2419 timelist_selection_cb (Timelist
*timelist
, GtkTreeSelection
*selection
)
2421 void (*cb
)(gpointer
, Timelist
*);
2424 cb
= g_object_get_data (G_OBJECT (selection
), "cb");
2425 data
= g_object_get_data (G_OBJECT (selection
), "data");
2427 cb (data
, timelist
);
2431 timelist_set_selection_callback (Timelist
*timelist
, void (*cb
)(void), gpointer data
)
2433 GtkWidget
*tree
= gtk_bin_get_child (GTK_BIN (timelist
));
2434 GtkTreeSelection
*selection
;
2436 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
2438 g_object_set_data (G_OBJECT (selection
), "cb", cb
);
2439 g_object_set_data (G_OBJECT (selection
), "data", data
);
2440 g_signal_connect_swapped (G_OBJECT (selection
), "changed",
2441 G_CALLBACK (timelist_selection_cb
), timelist
);