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., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, 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 pspec
= g_param_spec_uint ("second",
339 _("Displayed second"),
341 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
342 g_object_class_install_property (o_class
, ARG_SECOND
, pspec
);
343 pspec
= g_param_spec_uint ("clamp-minyear",
344 _("Lower limit year"),
345 _("Year part of the lower date limit"),
347 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
348 g_object_class_install_property (o_class
, ARG_CLAMP_MINYEAR
, pspec
);
349 pspec
= g_param_spec_uint ("clamp-maxyear",
350 _("Upper limit year"),
351 _("Year part of the upper date limit"),
353 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
354 g_object_class_install_property (o_class
, ARG_CLAMP_MAXYEAR
, pspec
);
355 pspec
= g_param_spec_uint ("clamp-minmonth",
356 _("Lower limit month"),
357 _("Month part of the lower date limit"),
358 G_DATE_JANUARY
, G_DATE_DECEMBER
, G_DATE_JANUARY
,
359 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
360 g_object_class_install_property (o_class
, ARG_CLAMP_MINMONTH
, pspec
);
361 pspec
= g_param_spec_uint ("clamp-maxmonth",
362 _("Upper limit month"),
363 _("Month part of the upper date limit"),
364 G_DATE_JANUARY
, G_DATE_DECEMBER
, G_DATE_DECEMBER
,
365 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
366 g_object_class_install_property (o_class
, ARG_CLAMP_MAXMONTH
, pspec
);
367 pspec
= g_param_spec_uint ("clamp-minday",
368 _("Lower limit day"),
369 _("Day of month part of the lower date limit"),
371 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
372 g_object_class_install_property (o_class
, ARG_CLAMP_MINDAY
, pspec
);
373 pspec
= g_param_spec_uint ("clamp-maxday",
374 _("Upper limit day"),
375 _("Day of month part of the upper date limit"),
377 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
378 g_object_class_install_property (o_class
, ARG_CLAMP_MAXDAY
, pspec
);
379 pspec
= g_param_spec_uint ("clamp-minhour",
380 _("Lower limit hour"),
381 _("Hour part of the lower time limit"),
383 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
384 g_object_class_install_property (o_class
, ARG_CLAMP_MINHOUR
, pspec
);
385 pspec
= g_param_spec_uint ("clamp-maxhour",
386 _("Upper limit hour"),
387 _("Hour part of the upper time limit"),
389 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
390 g_object_class_install_property (o_class
, ARG_CLAMP_MAXHOUR
, pspec
);
391 pspec
= g_param_spec_uint ("clamp-minminute",
392 _("Lower limit minute"),
393 _("Minute part of the lower time limit"),
395 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
396 g_object_class_install_property (o_class
, ARG_CLAMP_MINMINUTE
, pspec
);
397 pspec
= g_param_spec_uint ("clamp-maxminute",
398 _("Upper limit minute"),
399 _("Minute part of the upper time limit"),
401 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
402 g_object_class_install_property (o_class
, ARG_CLAMP_MAXMINUTE
, pspec
);
403 pspec
= g_param_spec_uint ("clamp-minsecond",
404 _("Lower limit second"),
405 _("Second part of the lower time limit"),
407 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
408 g_object_class_install_property (o_class
, ARG_CLAMP_MINSECOND
, pspec
);
409 pspec
= g_param_spec_uint ("clamp-maxsecond",
410 _("Upper limit second"),
411 _("Second part of the upper time limit"),
413 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
);
414 g_object_class_install_property (o_class
, ARG_CLAMP_MAXSECOND
, pspec
);
418 egg_datetime_signals
[SIGNAL_DATE_CHANGED
] =
419 g_signal_new ("date-changed",
420 G_TYPE_FROM_CLASS (klass
),
421 G_SIGNAL_RUN_LAST
| G_SIGNAL_ACTION
,
422 G_STRUCT_OFFSET (EggDateTimeClass
, date_changed
),
424 g_cclosure_marshal_VOID__VOID
,
427 egg_datetime_signals
[SIGNAL_TIME_CHANGED
] =
428 g_signal_new ("time-changed",
429 G_TYPE_FROM_CLASS (klass
),
430 G_SIGNAL_RUN_LAST
| G_SIGNAL_ACTION
,
431 G_STRUCT_OFFSET (EggDateTimeClass
, time_changed
),
433 g_cclosure_marshal_VOID__VOID
,
438 egg_datetime_init (EggDateTime
*edt
)
440 EggDateTimePrivate
*priv
;
441 GtkWidget
*arrow
, *hbox
, *vbox
, *frame
;
442 GtkCalendarDisplayOptions cal_options
;
443 priv
= g_new0 (EggDateTimePrivate
, 1);
446 /* Translators: Change this if you want to start weeks at mondays. */
447 priv
->week_start_monday
= strcmp (_("week-starts-monday: yes"), "week-starts-monday: yes") == 0 ? TRUE
: FALSE
;
449 priv
->date_valid
= FALSE
;
450 priv
->time_valid
= FALSE
;
452 /* Initialize Widgets */
454 gtk_box_set_spacing (GTK_BOX (edt
), 4);
458 priv
->date_box
= gtk_hbox_new (FALSE
, 0);
459 gtk_box_pack_start (GTK_BOX (edt
), priv
->date_box
, TRUE
, TRUE
, 0);
461 priv
->date_entry
= gtk_entry_new ();
462 gtk_entry_set_width_chars (GTK_ENTRY (priv
->date_entry
), 13);
464 _add_atk_name_desc (priv->date_entry, _("Date"), _("Enter the date directly"));
466 g_signal_connect_swapped (G_OBJECT (priv
->date_entry
), "focus-out-event",
467 G_CALLBACK (date_focus_out
), edt
);
468 gtk_widget_show (priv
->date_entry
);
469 gtk_box_pack_start (GTK_BOX (priv
->date_box
), priv
->date_entry
, TRUE
, TRUE
, 0);
471 priv
->date_button
= gtk_toggle_button_new ();
473 _add_atk_name_desc (priv->date_button, _("Select Date"), _("Select the date from a calendar"));
475 gtk_box_pack_start (GTK_BOX (priv
->date_box
), priv
->date_button
, FALSE
, FALSE
, 0);
476 arrow
= gtk_arrow_new (GTK_ARROW_DOWN
, GTK_SHADOW_OUT
);
477 gtk_container_add (GTK_CONTAINER (priv
->date_button
), arrow
);
478 gtk_widget_show (arrow
);
480 g_signal_connect_swapped (G_OBJECT (priv
->date_button
), "toggled",
481 G_CALLBACK (date_arrow_toggled
), edt
);
483 _add_atk_relation (priv->date_button, priv->date_entry,
484 ATK_RELATION_CONTROLLER_FOR, ATK_RELATION_CONTROLLED_BY);
488 priv
->time_box
= gtk_hbox_new (FALSE
, 0);
489 gtk_box_pack_start (GTK_BOX (edt
), priv
->time_box
, TRUE
, TRUE
, 0);
491 priv
->time_entry
= gtk_entry_new ();
492 gtk_entry_set_width_chars (GTK_ENTRY (priv
->time_entry
), 10);
494 _add_atk_name_desc (priv->time_entry, _("Time"), _("Enter the time directly"));
496 g_signal_connect_swapped (G_OBJECT (priv
->time_entry
), "focus-out-event",
497 G_CALLBACK (time_focus_out
), edt
);
498 gtk_widget_show (priv
->time_entry
);
499 gtk_box_pack_start (GTK_BOX (priv
->time_box
), priv
->time_entry
, TRUE
, TRUE
, 0);
501 priv
->time_button
= gtk_toggle_button_new ();
503 _add_atk_name_desc (priv->date_button, _("Select Time"), _("Select the time from a list"));
505 gtk_box_pack_start (GTK_BOX (priv
->time_box
), priv
->time_button
, FALSE
, FALSE
, 0);
506 arrow
= gtk_arrow_new (GTK_ARROW_DOWN
, GTK_SHADOW_OUT
);
507 gtk_container_add (GTK_CONTAINER (priv
->time_button
), arrow
);
508 gtk_widget_show (arrow
);
509 g_signal_connect_swapped (G_OBJECT (priv
->time_button
), "toggled",
510 G_CALLBACK (time_arrow_toggled
), edt
);
512 _add_atk_relation (priv->time_button, priv->time_entry,
513 ATK_RELATION_CONTROLLER_FOR, ATK_RELATION_CONTROLLED_BY);
517 priv
->cal_popup
= gtk_window_new (GTK_WINDOW_POPUP
);
518 gtk_widget_set_events (priv
->cal_popup
,
519 gtk_widget_get_events (priv
->cal_popup
) | GDK_KEY_PRESS_MASK
);
520 gtk_window_set_resizable (GTK_WINDOW (priv
->cal_popup
), FALSE
);
521 g_signal_connect_swapped (G_OBJECT (priv
->cal_popup
), "delete-event",
522 G_CALLBACK (cal_popup_closed
), edt
);
523 g_signal_connect_swapped (G_OBJECT (priv
->cal_popup
), "key-press-event",
524 G_CALLBACK (cal_popup_key_pressed
), edt
);
525 g_signal_connect_swapped (G_OBJECT (priv
->cal_popup
), "button-press-event",
526 G_CALLBACK (cal_popup_button_pressed
), edt
);
528 vbox
= gtk_vbox_new(FALSE
, 0);
529 frame
= gtk_frame_new(NULL
);
530 priv
->calendar
= gtk_calendar_new ();
531 gtk_window_set_focus(GTK_WINDOW(priv
->cal_popup
), priv
->calendar
);
532 gtk_container_add (GTK_CONTAINER (frame
), vbox
);
533 gtk_container_add (GTK_CONTAINER (priv
->cal_popup
), frame
);
534 cal_options
= GTK_CALENDAR_SHOW_DAY_NAMES
| GTK_CALENDAR_SHOW_HEADING
;
535 if (priv
->week_start_monday
)
536 cal_options
|= GTK_CALENDAR_WEEK_START_MONDAY
;
537 gtk_calendar_display_options (GTK_CALENDAR (priv
->calendar
), cal_options
);
538 gtk_box_pack_start(GTK_BOX(vbox
), priv
->calendar
, TRUE
, TRUE
,0);
539 g_signal_connect_swapped (G_OBJECT (priv
->calendar
), "day-selected",
540 G_CALLBACK (cal_popup_changed
), edt
);
541 g_signal_connect_swapped (G_OBJECT (priv
->calendar
), "day-selected-double-click",
542 G_CALLBACK (cal_popup_double_click
), edt
);
543 hbox
= gtk_hbox_new(FALSE
, 0);
544 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, FALSE
, TRUE
,0);
545 priv
->today
= gtk_button_new_with_mnemonic(_("_Today"));
546 priv
->nodate
= gtk_button_new_with_mnemonic(_("_No Date"));
547 gtk_box_pack_start(GTK_BOX(hbox
), priv
->today
, TRUE
, TRUE
,0);
548 gtk_box_pack_start(GTK_BOX(hbox
), priv
->nodate
, TRUE
, TRUE
,0);
549 g_signal_connect_swapped (G_OBJECT (priv
->today
), "clicked",
550 G_CALLBACK (cal_set_today
), edt
);
551 g_signal_connect_swapped (G_OBJECT (priv
->nodate
), "clicked",
552 G_CALLBACK (cal_set_nodate
), edt
);
555 gtk_widget_show_all(frame
);
556 gtk_widget_show(priv
->calendar
);
559 priv
->time_popup
= gtk_window_new (GTK_WINDOW_POPUP
);
560 gtk_widget_set_events (priv
->time_popup
,
561 gtk_widget_get_events (priv
->time_popup
) | GDK_KEY_PRESS_MASK
);
562 gtk_window_set_resizable (GTK_WINDOW (priv
->time_popup
), FALSE
);
563 g_signal_connect_swapped (G_OBJECT (priv
->time_popup
), "delete-event",
564 G_CALLBACK (time_popup_closed
), edt
);
565 g_signal_connect_swapped (G_OBJECT (priv
->time_popup
), "key-press-event",
566 G_CALLBACK (time_popup_key_pressed
), edt
);
567 g_signal_connect_swapped (G_OBJECT (priv
->time_popup
), "button-press-event",
568 G_CALLBACK (time_popup_button_pressed
), edt
);
570 priv
->timelist
= timelist_new (edt
);
572 gtk_window_set_default(GTK_WINDOW(priv->time_popup), gtk_bin_get_child(GTK_BIN(priv->timelist)));
574 timelist_set_selection_callback (TIMELIST (priv
->timelist
), G_CALLBACK (time_popup_changed
), edt
);
575 gtk_widget_set_size_request (priv
->timelist
, -1, 400);
576 gtk_container_add (GTK_CONTAINER (priv
->time_popup
), priv
->timelist
);
577 gtk_widget_show (priv
->timelist
);
578 if(priv
->no_date
) gtk_widget_set_sensitive(priv
->time_box
, FALSE
);
582 egg_datetime_set_property (GObject
*object
,
588 EggDateTimePrivate
*priv
;
590 g_return_if_fail (object
!= NULL
);
591 g_return_if_fail (EGG_IS_DATETIME (object
));
593 edt
= EGG_DATETIME (object
);
596 switch (property_id
) {
597 case ARG_DISPLAY_MODE
:
598 egg_datetime_set_display_mode (edt
, g_value_get_uint (value
));
601 egg_datetime_set_lazy (edt
, g_value_get_boolean (value
));
604 priv
->year
= g_value_get_uint (value
);
607 priv
->minute
= g_value_get_uint (value
);
610 priv
->day
= g_value_get_uint (value
);
613 priv
->hour
= g_value_get_uint (value
);
616 priv
->minute
= g_value_get_uint (value
);
619 priv
->second
= g_value_get_uint (value
);
621 case ARG_CLAMP_MINYEAR
:
622 priv
->clamp_minyear
= g_value_get_uint (value
);
624 case ARG_CLAMP_MINMONTH
:
625 priv
->clamp_minmonth
= g_value_get_uint (value
);
627 case ARG_CLAMP_MINDAY
:
628 priv
->clamp_minday
= g_value_get_uint (value
);
630 case ARG_CLAMP_MINHOUR
:
631 priv
->clamp_minhour
= g_value_get_uint (value
);
633 case ARG_CLAMP_MINMINUTE
:
634 priv
->clamp_minminute
= g_value_get_uint (value
);
636 case ARG_CLAMP_MINSECOND
:
637 priv
->clamp_minsecond
= g_value_get_uint (value
);
639 case ARG_CLAMP_MAXYEAR
:
640 priv
->clamp_maxyear
= g_value_get_uint (value
);
642 case ARG_CLAMP_MAXMONTH
:
643 priv
->clamp_maxmonth
= g_value_get_uint (value
);
645 case ARG_CLAMP_MAXDAY
:
646 priv
->clamp_maxday
= g_value_get_uint (value
);
648 case ARG_CLAMP_MAXHOUR
:
649 priv
->clamp_maxhour
= g_value_get_uint (value
);
651 case ARG_CLAMP_MAXMINUTE
:
652 priv
->clamp_maxminute
= g_value_get_uint (value
);
654 case ARG_CLAMP_MAXSECOND
:
655 priv
->clamp_maxsecond
= g_value_get_uint (value
);
661 egg_datetime_get_property (GObject
*object
,
666 EggDateTimePrivate
*priv
;
668 g_return_if_fail (object
!= NULL
);
669 g_return_if_fail (EGG_IS_DATETIME (object
));
671 priv
= EGG_DATETIME (object
)->priv
;
673 switch (property_id
) {
674 case ARG_DISPLAY_MODE
:
675 g_value_set_uint (value
, (guint
) priv
->display_mode
);
678 g_value_set_boolean (value
, priv
->lazy
);
681 g_value_set_uint (value
, priv
->year
);
684 g_value_set_uint (value
, priv
->month
);
687 g_value_set_uint (value
, priv
->day
);
690 g_value_set_uint (value
, priv
->hour
);
693 g_value_set_uint (value
, priv
->minute
);
696 g_value_set_uint (value
, priv
->second
);
698 case ARG_CLAMP_MINYEAR
:
699 g_value_set_uint (value
, priv
->clamp_minyear
);
701 case ARG_CLAMP_MINMONTH
:
702 g_value_set_uint (value
, priv
->clamp_minmonth
);
704 case ARG_CLAMP_MINDAY
:
705 g_value_set_uint (value
, priv
->clamp_minday
);
707 case ARG_CLAMP_MINHOUR
:
708 g_value_set_uint (value
, priv
->clamp_minhour
);
710 case ARG_CLAMP_MINMINUTE
:
711 g_value_set_uint (value
, priv
->clamp_minminute
);
713 case ARG_CLAMP_MINSECOND
:
714 g_value_set_uint (value
, priv
->clamp_minsecond
);
716 case ARG_CLAMP_MAXYEAR
:
717 g_value_set_uint (value
, priv
->clamp_maxyear
);
719 case ARG_CLAMP_MAXMONTH
:
720 g_value_set_uint (value
, priv
->clamp_maxmonth
);
722 case ARG_CLAMP_MAXDAY
:
723 g_value_set_uint (value
, priv
->clamp_maxday
);
725 case ARG_CLAMP_MAXHOUR
:
726 g_value_set_uint (value
, priv
->clamp_maxhour
);
728 case ARG_CLAMP_MAXMINUTE
:
729 g_value_set_uint (value
, priv
->clamp_maxminute
);
731 case ARG_CLAMP_MAXSECOND
:
732 g_value_set_uint (value
, priv
->clamp_maxsecond
);
738 egg_datetime_destroy (GtkObject
*object
)
740 EggDateTime
*edt
= EGG_DATETIME (object
);
741 EggDateTimePrivate
*priv
= edt
->priv
;
743 if (priv
->cal_popup
) {
744 gtk_widget_destroy (priv
->cal_popup
);
745 priv
->cal_popup
= NULL
;
748 if (priv
->time_popup
) {
749 gtk_widget_destroy (priv
->time_popup
);
750 priv
->time_popup
= NULL
;
753 if (GTK_OBJECT_CLASS (parent_class
)->destroy
)
754 (* GTK_OBJECT_CLASS (parent_class
)->destroy
) (object
);
758 egg_datetime_finalize (GObject
*object
)
760 EggDateTime
*edt
= EGG_DATETIME (object
);
764 if (G_OBJECT_CLASS (parent_class
)->finalize
)
765 (* G_OBJECT_CLASS (parent_class
)->finalize
) (object
);
772 /* Determine the number of bits, time_t uses. */
778 for (t
= 1, i
= 0; t
!= 0; t
= t
<< 1, i
++)
785 get_time_string (guint8 hour
, guint8 minute
, guint8 second
)
789 /* Translators: set this to anything else if you want to use a
792 if (!strcmp (_("24hr: no"), "24hr: yes")) {
805 /* Translators: This is hh:mm:ss AM/PM. */
806 s
= g_strdup_printf (_("%02d:%02d:%02d %s"), hour
, minute
, second
, ampm_s
);
808 /* Translators: This is hh:mm AM/PM. */
809 s
= g_strdup_printf (_("%02d:%02d %s"), hour
, minute
, ampm_s
);
812 /* Translators: This is hh:mm:ss. */
813 s
= g_strdup_printf (_("%02d:%02d:%02d"), hour
, minute
, second
);
815 /* Translators: This is hh:mm. */
816 s
= g_strdup_printf (_("%02d:%02d"), hour
, minute
);
823 popup_position (GtkWidget
*widget
, GtkWindow
*popup
)
825 GtkRequisition requisition
;
826 gint x
, y
, width
, height
;
828 gtk_widget_size_request (GTK_WIDGET (popup
), &requisition
);
829 gdk_window_get_origin (widget
->window
, &x
, &y
);
831 x
+= widget
->allocation
.x
;
832 y
+= widget
->allocation
.y
;
833 width
= widget
->allocation
.width
;
834 height
= widget
->allocation
.height
;
836 x
+= width
- requisition
.width
;
844 gtk_window_move (popup
, x
, y
);
848 popup_show (GtkWindow
*popup
)
850 /* GdkCursor *cursor;*/
852 gtk_widget_show_all (GTK_WIDGET (popup
));
853 gtk_widget_grab_focus (GTK_WIDGET (popup
));
854 gtk_grab_add (GTK_WIDGET (popup
));
856 /* Think its ugly to change the cursor.. */
858 cursor = gdk_cursor_new (GDK_ARROW);
859 gdk_pointer_grab (GTK_WIDGET (popup)->window, TRUE,
860 (GDK_BUTTON_PRESS_MASK
861 | GDK_BUTTON_RELEASE_MASK
862 | GDK_POINTER_MOTION_MASK),
863 NULL, cursor, GDK_CURRENT_TIME);
864 gdk_cursor_unref (cursor);
869 popup_hide (GtkWindow
*popup
)
871 gtk_widget_hide (GTK_WIDGET (popup
));
872 gtk_grab_remove (GTK_WIDGET (popup
));
873 gdk_pointer_ungrab (GDK_CURRENT_TIME
);
881 date_arrow_toggled (EggDateTime
*edt
, GtkToggleButton
*button
)
883 EggDateTimePrivate
*priv
= edt
->priv
;
885 if (!gtk_toggle_button_get_active (button
))
892 if(priv
->nodate
== 0)
894 gtk_calendar_select_month (GTK_CALENDAR (priv
->calendar
), priv
->month
- 1, priv
->year
);
895 gtk_calendar_select_day (GTK_CALENDAR (priv
->calendar
), priv
->day
);
900 popup_position (priv
->date_button
, GTK_WINDOW (priv
->cal_popup
));
904 popup_show (GTK_WINDOW (priv
->cal_popup
));
908 cal_popup_changed (EggDateTime
*edt
, GtkCalendar
*calendar
)
910 guint year
, month
, day
;
911 gtk_calendar_get_date (GTK_CALENDAR (edt
->priv
->calendar
), &year
, &month
, &day
);
913 edt
->priv
->no_date
= FALSE
;
915 edt
->priv
->year
= year
;
916 edt
->priv
->month
= month
+ 1;
917 edt
->priv
->day
= day
;
918 edt
->priv
->date_valid
= TRUE
;
920 normalize_date (edt
);
921 update_date_label (edt
);
923 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
927 cal_set_today (EggDateTime
*edt
, GtkCalendar
*calendar
)
930 guint year
, month
, day
;
931 edt
->priv
->no_date
= FALSE
;
934 g_date_set_time (now
, time (NULL
));
936 year
= g_date_get_year(now
);
937 month
= g_date_get_month(now
);
938 day
= g_date_get_day(now
);
940 edt
->priv
->year
= year
;
941 edt
->priv
->month
= month
;
942 edt
->priv
->day
= day
;
943 edt
->priv
->date_valid
= TRUE
;
945 gtk_calendar_select_month(GTK_CALENDAR (edt
->priv
->calendar
), month
-1, year
);
946 gtk_calendar_select_day(GTK_CALENDAR (edt
->priv
->calendar
), day
);
947 gtk_widget_show_all(edt
->priv
->calendar
);
949 gtk_calendar_set_date (GTK_CALENDAR (edt->priv->calendar), &year, &month, &day);
951 normalize_date (edt
);
952 update_date_label (edt
);
954 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
961 cal_set_nodate (EggDateTime
*edt
, GtkCalendar
*calendar
)
963 edt
->priv
->no_date
= TRUE
;
965 normalize_date (edt
);
966 update_date_label (edt
);
968 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
973 void egg_set_nodate(EggDateTime
*edt
, gboolean val
)
975 edt
->priv
->no_date
= val
;
977 normalize_date (edt
);
978 update_date_label (edt
);
980 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
984 gboolean
egg_get_nodate(EggDateTime
*edt
)
986 return edt
->priv
->no_date
;
991 cal_popup_double_click (EggDateTime
*edt
, GtkCalendar
*calendar
)
993 edt
->priv
->no_date
= FALSE
;
995 gtk_widget_set_sensitive(priv->time_box, edt->priv->no_date);
997 cal_popup_hide (edt
);
1001 cal_popup_key_pressed (EggDateTime
*edt
, GdkEventKey
*event
, GtkWidget
*widget
)
1003 if (event
->keyval
!= GDK_Escape
)
1006 g_signal_stop_emission_by_name (G_OBJECT (widget
), "key_press_event");
1008 cal_popup_hide (edt
);
1014 cal_popup_button_pressed (EggDateTime
*edt
, GdkEventButton
*event
, GtkWidget
*widget
)
1018 child
= gtk_get_event_widget ((GdkEvent
*) event
);
1020 /* We don't ask for button press events on the grab widget, so
1021 * if an event is reported directly to the grab widget, it must
1022 * be on a window outside the application (and thus we remove
1023 * the popup window). Otherwise, we check if the widget is a child
1024 * of the grab widget, and only remove the popup window if it
1027 if (child
!= widget
) {
1029 if (child
== widget
)
1031 child
= child
->parent
;
1035 cal_popup_hide (edt
);
1041 cal_popup_closed (EggDateTime
*edt
, GtkWindow
*popup
)
1043 cal_popup_hide (edt
);
1049 cal_popup_hide (EggDateTime
*edt
)
1051 EggDateTimePrivate
*priv
= edt
->priv
;
1053 popup_hide (GTK_WINDOW (priv
->cal_popup
));
1055 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv
->date_button
), FALSE
);
1056 gtk_widget_grab_focus (priv
->date_entry
);
1058 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1066 time_arrow_toggled (EggDateTime
*edt
, GtkToggleButton
*button
)
1068 EggDateTimePrivate
*priv
= edt
->priv
;
1070 if (!gtk_toggle_button_get_active (button
))
1076 /* Position Popup */
1078 popup_position (priv
->time_button
, GTK_WINDOW (priv
->time_popup
));
1081 /* dirty hack to stop it selecting the first item when showing for the first time in new window*/
1082 /* I should fix this.. because this is quiet nasty */
1084 minute
= priv
->minute
;
1085 popup_show (GTK_WINDOW (priv
->time_popup
));
1087 priv
->minute
= minute
;
1088 timelist_set_time (TIMELIST (priv
->timelist
), priv
->hour
, priv
->minute
);
1089 update_time_label(edt
);
1093 time_popup_changed (EggDateTime
*edt
, Timelist
*timelist
)
1095 EggDateTimePrivate
*priv
= edt
->priv
;
1097 if (!timelist_get_time (timelist
, &priv
->hour
, &priv
->minute
))
1101 priv
->time_valid
= TRUE
;
1103 normalize_time (edt
);
1105 if(GTK_WIDGET_VISIBLE(timelist
))update_time_label (edt
);
1107 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1111 time_popup_key_pressed (EggDateTime
*edt
, GdkEventKey
*event
, GtkWidget
*widget
)
1113 if (event
->keyval
!= GDK_Escape
)
1116 g_signal_stop_emission_by_name (G_OBJECT (widget
), "key_press_event");
1118 time_popup_hide (edt
);
1124 time_popup_button_pressed (EggDateTime
*edt
, GdkEventButton
*event
, GtkWidget
*widget
)
1128 child
= gtk_get_event_widget ((GdkEvent
*) event
);
1130 /* We don't ask for button press events on the grab widget, so
1131 * if an event is reported directly to the grab widget, it must
1132 * be on a window outside the application (and thus we remove
1133 * the popup window). Otherwise, we check if the widget is a child
1134 * of the grab widget, and only remove the popup window if it
1137 if (child
!= widget
) {
1139 if (child
== widget
)
1141 child
= child
->parent
;
1145 time_popup_hide (edt
);
1151 time_popup_closed (EggDateTime
*edt
, GtkWindow
*popup
)
1153 time_popup_hide (edt
);
1159 time_popup_hide (EggDateTime
*edt
)
1161 EggDateTimePrivate
*priv
= edt
->priv
;
1162 popup_hide (GTK_WINDOW (priv
->time_popup
));
1164 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv
->time_button
), FALSE
);
1165 gtk_widget_grab_focus (priv
->time_entry
);
1167 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1175 date_focus_out (EggDateTime
*edt
, GtkEntry
*entry
)
1178 update_date_label (edt
);
1180 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1186 time_focus_out (EggDateTime
*edt
, GtkEntry
*entry
)
1189 update_time_label (edt
);
1191 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1201 apply_display_mode (EggDateTime
*edt
)
1203 if (edt
->priv
->display_mode
& EGG_DATETIME_DISPLAY_DATE
)
1204 gtk_widget_show (edt
->priv
->date_box
);
1206 gtk_widget_hide (edt
->priv
->date_box
);
1207 if (edt
->priv
->display_mode
& EGG_DATETIME_DISPLAY_MONTH
)
1208 gtk_widget_show (edt
->priv
->date_button
);
1210 gtk_widget_hide (edt
->priv
->date_button
);
1212 if (edt
->priv
->display_mode
& EGG_DATETIME_DISPLAY_TIME
)
1213 gtk_widget_show (edt
->priv
->time_box
);
1215 gtk_widget_hide (edt
->priv
->time_box
);
1216 if (edt
->priv
->display_mode
& EGG_DATETIME_DISPLAY_HOUR
)
1217 gtk_widget_show (edt
->priv
->time_button
);
1219 gtk_widget_hide (edt
->priv
->time_button
);
1223 clamp_time_labels (EggDateTime
*edt
)
1225 EggDateTimePrivate
*priv
= edt
->priv
;
1227 timelist_clamp (TIMELIST (priv
->timelist
),
1228 priv
->clamp_minhour
,
1229 priv
->clamp_minminute
,
1230 priv
->clamp_maxhour
,
1231 priv
->clamp_maxminute
);
1234 /* Updates the date entry to the current date. */
1236 update_date_label (EggDateTime
*edt
)
1238 EggDateTimePrivate
*priv
= edt
->priv
;
1240 gtk_widget_set_sensitive(priv
->time_box
, !priv
->no_date
);
1243 gtk_entry_set_text(GTK_ENTRY(priv
->date_entry
), _("No Date"));
1247 if (!priv
->date_valid
) {
1248 gtk_entry_set_text (GTK_ENTRY (priv
->date_entry
), "");
1252 /* TODO: should handle other display modes as well... */
1254 /* Translators: This is yyyy-mm-dd. */
1255 s
= g_strdup_printf (_("%04d-%02d-%02d"), priv
->year
, priv
->month
, priv
->day
);
1256 gtk_entry_set_text (GTK_ENTRY (priv
->date_entry
), s
);
1260 /* Updates the time entry to the current time. */
1262 update_time_label (EggDateTime
*edt
)
1264 EggDateTimePrivate
*priv
= edt
->priv
;
1267 if (!priv
->time_valid
) {
1268 gtk_entry_set_text (GTK_ENTRY (priv
->time_entry
), "");
1272 /* TODO: should handle other display modes as well... */
1274 if ((priv
->display_mode
& EGG_DATETIME_DISPLAY_SECOND
) ||
1275 (priv
->display_mode
& EGG_DATETIME_DISPLAY_SECOND_OPT
))
1276 s
= get_time_string (priv
->hour
, priv
->minute
, priv
->second
);
1278 if(priv
->hour
== -1 && priv
->minute
== 0)
1279 s
= g_strdup(_("no end time"));
1280 else s
= get_time_string (priv
->hour
, priv
->minute
, 0xff);
1282 gtk_entry_set_text (GTK_ENTRY (priv
->time_entry
), s
);
1287 /* Parse the current date entry and normalize the date. */
1289 parse_date (EggDateTime
*edt
)
1292 g_date_set_parse (&date
, gtk_entry_get_text (GTK_ENTRY (edt
->priv
->date_entry
)));
1293 if (!g_date_valid (&date
)) {
1294 edt
->priv
->no_date
= TRUE
;
1295 gtk_entry_set_text(GTK_ENTRY(edt
->priv
->date_entry
), _("No Date"));
1299 edt
->priv
->year
= date
.year
;
1300 edt
->priv
->month
= date
.month
;
1301 edt
->priv
->day
= date
.day
;
1302 edt
->priv
->date_valid
= TRUE
;
1304 normalize_date (edt
);
1307 /* Parse the current time entry and normalize the time. */
1309 parse_time (EggDateTime
*edt
)
1313 unsigned int hour
, minute
, second
= 0;
1314 size_t len1
, len2
, len3
;
1316 /* Retrieve and Parse String */
1318 s
= gtk_entry_get_text (GTK_ENTRY (edt
->priv
->time_entry
));
1320 /* Translators: This is hh:mm:ss AM/PM. */
1321 if (sscanf (s
, _("%u:%u:%u"), &hour
, &minute
, &second
) < 2) {
1322 if (sscanf (s
, "%u:%u:%u", &hour
, &minute
, &second
) < 2) {
1323 if (edt
->priv
->lazy
)
1324 edt
->priv
->time_valid
= FALSE
;
1329 if (hour
> 23 || minute
> 59 || second
> 59) {
1330 if (edt
->priv
->lazy
)
1331 edt
->priv
->time_valid
= FALSE
;
1335 /* AM/PM Handling */
1338 scp
= g_strchomp (scp
);
1340 len1
= strlen (_("AM"));
1341 len2
= strlen (_("PM"));
1342 len3
= strlen (scp
);
1344 if (len1
< len3
&& !strcasecmp (scp
+ len3
- len1
, _("AM"))) {
1348 if (len2
< len3
&& !strcasecmp (scp
+ len3
- len2
, _("PM"))) {
1356 edt
->priv
->hour
= hour
;
1357 edt
->priv
->minute
= minute
;
1358 edt
->priv
->second
= second
;
1359 edt
->priv
->time_valid
= TRUE
;
1365 normalize_time (edt
);
1368 /* Clamp the current date to the date clamp range if lazy is turned off. */
1370 normalize_date (EggDateTime
*edt
)
1372 GDate date
, min_date
, max_date
;
1374 if (edt
->priv
->lazy
)
1377 g_date_clear (&date
, 1);
1378 g_date_set_dmy (&date
, edt
->priv
->day
, edt
->priv
->month
, edt
->priv
->year
);
1379 g_date_clear (&min_date
, 1);
1380 g_date_set_dmy (&min_date
, edt
->priv
->clamp_minday
, edt
->priv
->clamp_minmonth
, edt
->priv
->clamp_minyear
);
1381 g_date_clear (&max_date
, 1);
1382 g_date_set_dmy (&max_date
, edt
->priv
->clamp_maxday
, edt
->priv
->clamp_maxmonth
, edt
->priv
->clamp_maxyear
);
1384 g_date_clamp (&date
, &min_date
, &max_date
);
1386 edt
->priv
->year
= date
.year
;
1387 edt
->priv
->month
= date
.month
;
1388 edt
->priv
->day
= date
.day
;
1389 edt
->priv
->date_valid
= TRUE
;
1392 /* Clamp the current time to the time clamp range if lazy is turned off. */
1394 normalize_time (EggDateTime
*edt
)
1396 if (edt
->priv
->lazy
)
1399 if (edt
->priv
->hour
< edt
->priv
->clamp_minhour
) {
1400 edt
->priv
->hour
= -1;;
1401 edt
->priv
->minute
= edt
->priv
->clamp_minminute
;
1402 edt
->priv
->second
= edt
->priv
->clamp_minsecond
;
1403 } else if (edt
->priv
->hour
== edt
->priv
->clamp_minhour
) {
1404 if (edt
->priv
->minute
< edt
->priv
->clamp_minminute
) {
1405 edt
->priv
->minute
= edt
->priv
->clamp_minminute
;
1406 edt
->priv
->second
= edt
->priv
->clamp_minsecond
;
1407 } else if (edt
->priv
->minute
== edt
->priv
->clamp_minminute
) {
1408 if (edt
->priv
->second
< edt
->priv
->clamp_minsecond
)
1409 edt
->priv
->second
= edt
->priv
->clamp_minsecond
;
1413 if (edt
->priv
->hour
> edt
->priv
->clamp_maxhour
) {
1414 edt
->priv
->hour
= edt
->priv
->clamp_maxhour
;
1415 edt
->priv
->minute
= edt
->priv
->clamp_maxminute
;
1416 edt
->priv
->second
= edt
->priv
->clamp_maxsecond
;
1417 } else if (edt
->priv
->hour
== edt
->priv
->clamp_maxhour
) {
1418 if (edt
->priv
->minute
> edt
->priv
->clamp_maxminute
) {
1419 edt
->priv
->minute
= edt
->priv
->clamp_maxminute
;
1420 edt
->priv
->second
= edt
->priv
->clamp_maxsecond
;
1421 } else if (edt
->priv
->minute
== edt
->priv
->clamp_maxminute
) {
1422 if (edt
->priv
->second
> edt
->priv
->clamp_maxsecond
)
1423 edt
->priv
->second
= edt
->priv
->clamp_maxsecond
;
1427 edt
->priv
->time_valid
= TRUE
;
1431 parse_and_update_date (EggDateTime
*edt
)
1433 if (edt
->priv
->lazy
)
1437 update_date_label (edt
);
1441 parse_and_update_time (EggDateTime
*edt
)
1443 if (edt
->priv
->lazy
)
1447 update_time_label (edt
);
1457 * Creates a new #EggDateTime widget. By default this widget will show
1458 * only the date component and is set to the current date and time.
1460 * Return value: a newly created #EggDateTime widget
1463 egg_datetime_new (void)
1467 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1468 egg_datetime_set_from_time_t (edt
, time (NULL
));
1470 return GTK_WIDGET (edt
);
1474 * egg_datetime_new_from_time_t:
1475 * @t: initial time and date
1477 * Creates a new #EggDateTime widget and sets it to the date and time
1478 * given as @t argument. This does also call egg_datetime_set_clamp_time_t().
1479 * By default this widget will show only the date component.
1481 * Return value: a newly created #EggDateTime widget
1484 egg_datetime_new_from_time_t (time_t t
)
1488 g_return_val_if_fail (t
>= 0, NULL
);
1490 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1491 egg_datetime_set_from_time_t (edt
, t
);
1492 egg_datetime_set_clamp_time_t (edt
);
1494 return GTK_WIDGET (edt
);
1498 * egg_datetime_new_from_struct_tm:
1499 * @tm: initial time and date
1501 * Creates a new #EggDateTime widget and sets it to the date and time
1502 * given as @tm argument. By default this widget will show only the date
1505 * Return value: a newly created #EggDateTime widget
1508 egg_datetime_new_from_struct_tm (struct tm
*tm
)
1512 g_return_val_if_fail (tm
!= NULL
, NULL
);
1514 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1515 egg_datetime_set_from_struct_tm (edt
, tm
);
1517 return GTK_WIDGET (edt
);
1521 * egg_datetime_new_from_gdate:
1522 * @date: initial time and date
1524 * Creates a new #EggDateTime widget and sets it to the date and time
1525 * given as @date argument. By default this widget will show only the
1528 * Return value: a newly created #EggDateTime widget
1531 egg_datetime_new_from_gdate (GDate
*date
)
1535 g_return_val_if_fail (date
!= NULL
, NULL
);
1537 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1538 egg_datetime_set_from_gdate (edt
, date
);
1540 return GTK_WIDGET (edt
);
1544 * egg_datetime_new_from_datetime:
1545 * @year: initial year
1546 * @month: initial month
1548 * @hour: initial hour
1549 * @minute: initial minute
1550 * @second: initial second
1552 * Creates a new #EggDateTime widget and sets it to the date and time
1553 * given as arguments.
1555 * Return value: a newly created #EggDateTime widget
1558 egg_datetime_new_from_datetime (GDateYear year
, GDateMonth month
, GDateDay day
, guint8 hour
, guint8 minute
, guint8 second
)
1562 edt
= g_object_new (EGG_TYPE_DATETIME
, NULL
);
1563 egg_datetime_set_date (edt
, year
, month
, day
);
1564 egg_datetime_set_time (edt
, hour
, minute
, second
);
1566 return GTK_WIDGET (edt
);
1570 * egg_datetime_set_none:
1571 * @edt: an #EggDateTime
1573 * Sets the date to an invalid value. If lazy mode is turned off the date
1574 * and time will be set to a random value.
1577 egg_datetime_set_none (EggDateTime
*edt
)
1579 g_return_if_fail (edt
!= NULL
);
1580 g_return_if_fail (EGG_IS_DATETIME (edt
));
1582 edt
->priv
->date_valid
= FALSE
;
1583 edt
->priv
->time_valid
= FALSE
;
1585 update_date_label (edt
);
1586 update_time_label (edt
);
1588 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1589 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1593 * egg_datetime_set_from_time_t:
1594 * @edt: an #EggDateTime
1595 * @t: date and time to set the widget to
1597 * Sets the date and time of the widget to @t.
1600 egg_datetime_set_from_time_t (EggDateTime
*edt
, time_t t
)
1604 g_return_if_fail (edt
!= NULL
);
1605 g_return_if_fail (EGG_IS_DATETIME (edt
));
1607 if (localtime_r (&t
, &tm
)) {
1608 egg_datetime_set_date (edt
, tm
.tm_year
+ 1900, tm
.tm_mon
+ 1, tm
.tm_mday
);
1609 egg_datetime_set_time (edt
, tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
);
1611 egg_datetime_set_none (edt
);
1615 * egg_datetime_get_as_time_t:
1616 * @edt: an #EggDateTime
1617 * @t: pointer to a %time_t value
1619 * Returns the current time as a %time_t value. If the currently entered
1620 * value is invalid and lazy mode is turned on or if the entered date
1621 * can't be represented as a %time_t value, the value is set to -1 and
1622 * FALSE is returned.
1624 * Return value: success indicator
1627 egg_datetime_get_as_time_t (EggDateTime
*edt
, time_t *t
)
1633 gint hour
, minute
, second
;
1635 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1636 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1641 if (!egg_datetime_get_date (edt
, &year
, &month
, &day
)) {
1645 if (!egg_datetime_get_time (edt
, &hour
, &minute
, &second
)) {
1650 memset (&tm
, 0, sizeof (struct tm
));
1651 tm
.tm_year
= year
- 1900;
1652 tm
.tm_mon
= month
- 1;
1669 * egg_datetime_set_from_struct_tm:
1670 * @edt: an #EggDateTime
1671 * @tm: date and time to set the widget to
1673 * Sets the date and time of the widget to @tm.
1676 egg_datetime_set_from_struct_tm (EggDateTime
*edt
, struct tm
*tm
)
1678 g_return_if_fail (edt
!= NULL
);
1679 g_return_if_fail (EGG_IS_DATETIME (edt
));
1680 g_return_if_fail (tm
!= NULL
);
1682 egg_datetime_set_date (edt
, tm
->tm_year
+ 1900, tm
->tm_mon
+ 1, tm
->tm_mday
);
1683 egg_datetime_set_time (edt
, tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
1687 * egg_datetime_get_as_struct_tm:
1688 * @edt: an #EggDateTime
1689 * @tm: pointer to an allocated struct tm
1691 * Fill the supplied struct tm with the widget's current date and time.
1692 * If the currently entered value is invalid and lazy mode is turned
1693 * on or if the entered date can't be represented as a struct tm, the
1694 * struct is filled with invalid data and FALSE is returned.
1696 * Return value: success indicator
1699 egg_datetime_get_as_struct_tm (EggDateTime
*edt
, struct tm
*tm
)
1704 gint hour
, minute
, second
;
1706 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1707 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1712 memset (tm
, 0, sizeof (struct tm
));
1714 if (!egg_datetime_get_date (edt
, &year
, &month
, &day
))
1716 if (!egg_datetime_get_time (edt
, &hour
, &minute
, &second
))
1719 tm
->tm_year
= year
- 1900;
1720 tm
->tm_mon
= month
- 1;
1723 tm
->tm_min
= minute
;
1724 tm
->tm_sec
= second
;
1732 * egg_datetime_set_from_gdate:
1733 * @edt: an #EggDateTime
1734 * @date: date to set the widget to
1736 * Sets the date of the widget to @date. The time will remain unchanged.
1739 egg_datetime_set_from_gdate (EggDateTime
*edt
, GDate
*date
)
1745 g_return_if_fail (edt
!= NULL
);
1746 g_return_if_fail (EGG_IS_DATETIME (edt
));
1747 g_return_if_fail (date
!= NULL
);
1749 year
= g_date_get_year(date
);
1750 month
= g_date_get_month(date
);
1751 day
= g_date_get_day(date
);
1752 g_return_if_fail(g_date_valid_dmy(day
, month
, year
));
1754 if (g_date_valid (date
))
1755 egg_datetime_set_date (edt
, year
, month
, day
);
1757 egg_datetime_set_none (edt
);
1761 * egg_datetime_get_as_gdate:
1762 * @edt: an #EggDateTime
1763 * @date: pointer to an allocated #GDate
1765 * Fills the supplied #GDate with the widget's current date. If the
1766 * currently entered date value is invalid and lazy mode is turned
1767 * on or if the entered date can't be represented as a #GDate, the
1768 * @date is set to an invalid value and FALSE is returned.
1770 * Return value: success indicator
1773 egg_datetime_get_as_gdate (EggDateTime
*edt
, GDate
*date
)
1779 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1780 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1785 g_date_clear (date
, 1);
1787 if (!egg_datetime_get_date (edt
, &year
, &month
, &day
))
1790 g_date_set_dmy (date
, day
, month
, year
);
1796 * egg_datetime_set_date:
1797 * @edt: an #EggDateTime
1798 * @year: a #guint16 between 1 and 9999
1799 * @month: a #guint8 between 1 and 12
1800 * @day: a #guint8 between 1 and 28-31 (depending on @month)
1802 * Sets the date of the widget. The time will remain unchanged.
1805 egg_datetime_set_date (EggDateTime
*edt
, GDateYear year
, GDateMonth month
, GDateDay day
)
1807 g_return_if_fail (edt
!= NULL
);
1808 g_return_if_fail (EGG_IS_DATETIME (edt
));
1809 g_return_if_fail (year
>= 1 && year
<= 9999);
1810 g_return_if_fail (month
>= 1 && month
<= 12);
1811 g_return_if_fail (day
>= 1 && day
<= g_date_get_days_in_month (month
, year
));
1813 edt
->priv
->year
= year
;
1814 edt
->priv
->month
= month
;
1815 edt
->priv
->day
= day
;
1816 edt
->priv
->date_valid
= TRUE
;
1817 gtk_calendar_select_month(GTK_CALENDAR(edt
->priv
->calendar
), month
-1, year
);
1818 gtk_calendar_select_day(GTK_CALENDAR(edt
->priv
->calendar
), day
);
1820 normalize_date (edt
);
1821 update_date_label (edt
);
1823 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1827 * egg_datetime_get_date:
1828 * @edt: an #EggDateTime
1829 * @year: a pointer to a #guint16 or %NULL
1830 * @month: a pointer to #guint8 or %NULL
1831 * @day: a pointer to a #guint8 or %NULL
1833 * Fills the supplied arguments with the widget's current date. If the
1834 * currently entered date value is invalid and lazy mode is turned
1835 * on, the arguments are set to %EGG_DATETIME_INVALID_DATE and FALSE
1838 * Return value: success indicator
1841 egg_datetime_get_date (EggDateTime
*edt
, GDateYear
*year
, GDateMonth
*month
, GDateDay
*day
)
1843 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1844 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1848 if (!edt
->priv
->date_valid
) {
1859 *year
= edt
->priv
->year
;
1861 *month
= edt
->priv
->month
;
1863 *day
= edt
->priv
->day
;
1869 * egg_datetime_set_time:
1870 * @edt: an #EggDateTime
1871 * @hour: a #guint8 between 0 and 23
1872 * @minute: a #guint8 between 0 and 59
1873 * @second: a #guint8 between 0 and 59
1875 * Sets the time of the widget. The date will remain unchanged.
1878 egg_datetime_set_time (EggDateTime
*edt
, gint hour
, gint minute
, guint8 second
)
1880 g_return_if_fail (edt
!= NULL
);
1881 g_return_if_fail (EGG_IS_DATETIME (edt
));
1882 g_return_if_fail (hour
<= 23);
1883 g_return_if_fail (minute
<= 59);
1884 g_return_if_fail (second
<= 59);
1886 edt
->priv
->hour
= hour
;
1887 edt
->priv
->minute
= minute
;
1888 edt
->priv
->second
= second
;
1889 edt
->priv
->time_valid
= TRUE
;
1891 normalize_time (edt
);
1892 update_time_label (edt
);
1894 timelist_set_time(edt->priv->timelist, hour, minute);
1896 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1900 * egg_datetime_get_date:
1901 * @edt: an #EggDateTime
1902 * @hour: a pointer to a #guint8 or %NULL
1903 * @minute: a pointer to #guint8 or %NULL
1904 * @second: a pointer to a #guint8 or %NULL
1906 * Fills the supplied arguments with the widget's current time. If the
1907 * currently entered time value is invalid and lazy mode is turned
1908 * on, the arguments are set to %EGG_DATETIME_INVALID_TIME and FALSE
1911 * Return value: success indicator
1914 egg_datetime_get_time (EggDateTime
*edt
, gint
*hour
, gint
*minute
, gint
*second
)
1916 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1917 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1921 if (!edt
->priv
->time_valid
) {
1932 *hour
= edt
->priv
->hour
;
1934 *minute
= edt
->priv
->minute
;
1936 *second
= edt
->priv
->second
;
1942 * egg_datetime_set_lazy:
1943 * @edt: an #EggDateTime
1944 * @lazy: a boolean value
1946 * Turns the widget's lazy mode on or off. In lazy mode the widget will
1947 * allow invalid values to be entered. If lazy mode is turned off the
1948 * widget will normalize all invalid values entered in the date and time
1949 * widgets to the nearest valid value. This guarantees that the get methods
1950 * will always return valid values.
1952 * Lazy mode defaults to %TRUE.
1955 egg_datetime_set_lazy (EggDateTime
*edt
, gboolean lazy
)
1957 g_return_if_fail (edt
!= NULL
);
1958 g_return_if_fail (EGG_IS_DATETIME (edt
));
1960 edt
->priv
->lazy
= lazy
? TRUE
: FALSE
;
1962 parse_and_update_date (edt
);
1963 parse_and_update_time (edt
);
1965 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
1966 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
1970 * egg_datetime_get_lazy:
1971 * @edt: an #EggDateTime
1973 * Returns whether the widget is in lazy mode.
1975 * Return value: a boolean value
1978 egg_datetime_get_lazy (EggDateTime
*edt
)
1980 g_return_val_if_fail (edt
!= NULL
, FALSE
);
1981 g_return_val_if_fail (EGG_IS_DATETIME (edt
), FALSE
);
1983 return edt
->priv
->lazy
;
1987 * egg_datetime_set_display_mode:
1988 * @edt: an #EggDateTime
1989 * @mode: new display mode
1991 * Sets the widget's new display mode to @mode. The display mode defaults
1992 * to %EGG_DATETIME_DISPLAY_DATE.
1995 egg_datetime_set_display_mode (EggDateTime
*edt
, EggDateTimeDisplayMode mode
)
1997 g_return_if_fail (edt
!= NULL
);
1998 g_return_if_fail (EGG_IS_DATETIME (edt
));
2000 edt
->priv
->display_mode
= mode
;
2002 apply_display_mode (edt
);
2006 * egg_datetime_get_display_mode:
2007 * @edt: an #EggDateTime
2009 * Returns the current display mode.
2011 * Return value: The current display mode.
2013 EggDateTimeDisplayMode
2014 egg_datetime_get_display_mode (EggDateTime
*edt
)
2016 g_return_val_if_fail (edt
!= NULL
, 0);
2017 g_return_val_if_fail (EGG_IS_DATETIME (edt
), 0);
2019 return edt
->priv
->display_mode
;
2023 * egg_datetime_set_clamp_date:
2024 * @edt: an #EggDateTime
2025 * @minyear: minimum year
2026 * @minmonth: minimum month
2027 * @minday: minimum day
2028 * @maxyear: maximum year
2029 * @maxmonth: maximum month
2030 * @maxday: maximum day
2032 * Limits the allowed dates to the range given. If lazy mode is
2033 * turned off, dates that are outside of this range are snapped to the
2034 * minimum or maximum date. Otherwise such dates return an invalid value.
2036 * This defaults to the minimum date 1-1-1 and maximum date 9999-12-31.
2037 * The maximum year is always limited to 9999.
2040 egg_datetime_set_clamp_date (EggDateTime
*edt
,
2042 GDateMonth minmonth
,
2045 GDateMonth maxmonth
,
2051 g_return_if_fail (minyear
>= 1 && minyear
<= 9999 && maxyear
>= 1);
2052 g_return_if_fail (minmonth
>= 1 && minmonth
<= 12 && maxmonth
>= 1 && maxmonth
<= 12);
2053 g_return_if_fail (minday
>= 1 && minday
<= g_date_get_days_in_month (minmonth
, minyear
));
2054 g_return_if_fail (maxday
>= 1 && maxday
<= g_date_get_days_in_month (maxmonth
, maxyear
));
2055 g_return_if_fail (minyear
<= maxyear
);
2056 g_return_if_fail (minyear
< maxyear
|| minmonth
<= maxmonth
);
2057 g_return_if_fail (minyear
< maxyear
|| minmonth
< maxmonth
|| minday
<= maxday
);
2059 edt
->priv
->clamp_minyear
= minyear
;
2060 edt
->priv
->clamp_minmonth
= minmonth
;
2061 edt
->priv
->clamp_minday
= minday
;
2062 edt
->priv
->clamp_maxyear
= maxyear
;
2063 edt
->priv
->clamp_maxmonth
= maxmonth
;
2064 edt
->priv
->clamp_maxday
= maxday
;
2066 parse_and_update_date (edt
);
2068 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_DATE_CHANGED
], 0);
2072 * egg_datetime_set_clamp_time:
2073 * @edt: an #EggDateTime
2074 * @minhour: minimum hour
2075 * @minminute: minimum minute
2076 * @minsecond: minimum second
2077 * @maxhour: maximum hour
2078 * @maxminute: maximum minute
2079 * @maxsecond: maximum second
2081 * Limits the allowed times to the range given. If lazy mode is turned
2082 * off, times that are outside of this range are snapped to the minimum or
2083 * maximum time. Otherwise such times return an invalid value.
2086 egg_datetime_set_clamp_time (EggDateTime
*edt
, guint8 minhour
, guint8 minminute
, guint8 minsecond
, guint8 maxhour
, guint8 maxminute
, guint8 maxsecond
)
2088 g_return_if_fail (minhour
<= 23 && maxhour
<= 23);
2089 g_return_if_fail (minminute
<= 59 && maxminute
<= 59);
2090 g_return_if_fail (minsecond
<= 59 && maxsecond
<= 59);
2091 g_return_if_fail (minhour
<= maxhour
);
2092 g_return_if_fail (minhour
< maxhour
|| minminute
<= maxminute
);
2093 g_return_if_fail (minhour
< maxhour
|| minminute
< maxminute
|| minsecond
<= maxsecond
);
2095 edt
->priv
->clamp_minhour
= minhour
;
2096 edt
->priv
->clamp_minminute
= minminute
;
2097 edt
->priv
->clamp_minsecond
= minsecond
;
2098 edt
->priv
->clamp_maxhour
= maxhour
;
2099 edt
->priv
->clamp_maxminute
= maxminute
;
2100 edt
->priv
->clamp_maxsecond
= maxsecond
;
2102 clamp_time_labels (edt
);
2103 parse_and_update_time (edt
);
2105 g_signal_emit (G_OBJECT (edt
), egg_datetime_signals
[SIGNAL_TIME_CHANGED
], 0);
2109 * egg_datetime_set_clamp_time_t:
2110 * @edt: an #EggDateTime
2112 * Clamps the allowed dates of the widget to valid #time_t values.
2113 * The time clamp settings are not changed.
2116 egg_datetime_set_clamp_time_t (EggDateTime
*edt
)
2119 struct tm start_tm
, end_tm
;
2124 g_return_if_fail (edt
!= NULL
);
2125 g_return_if_fail (EGG_IS_DATETIME (edt
));
2128 gmtime_r (&t
, &start_tm
);
2131 bits
= time_t_bits ();
2133 t
&= ~(1 << (bits
- 1));
2135 gmtime_r (&t
, &end_tm
);
2137 /* Subtract one day from the end date, since not all times of
2138 * the last day can be represented.
2141 year
= end_tm
.tm_year
+ 1900;
2142 month
= end_tm
.tm_mon
+ 1;
2143 day
= end_tm
.tm_mday
;
2151 day
= g_date_get_days_in_month (month
, year
);
2154 egg_datetime_set_clamp_date (edt
, start_tm
.tm_year
+ 1900, start_tm
.tm_mon
+ 1, start_tm
.tm_mday
, year
, month
, day
);
2158 * egg_datetime_get_clamp_date:
2159 * @edt: an #EggDateTime
2160 * @minyear: #guint16 pointer or %NULL
2161 * @minmonth: #guint8 pointer or %NULL
2162 * @minday: #guint8 pointer or %NULL
2163 * @maxyear: #guint16 pointer or %NULL
2164 * @maxmonth: #guint8 pointer or %NULL
2165 * @maxday: #guint8 pointer or %NULL
2167 * Returns the current date limit settings.
2170 egg_datetime_get_clamp_date (EggDateTime
*edt
,
2172 GDateMonth
*minmonth
,
2175 GDateMonth
*maxmonth
,
2178 g_return_if_fail (edt
!= NULL
);
2179 g_return_if_fail (EGG_IS_DATETIME (edt
));
2182 *minyear
= edt
->priv
->clamp_minyear
;
2184 *minmonth
= edt
->priv
->clamp_minmonth
;
2186 *minday
= edt
->priv
->clamp_minday
;
2188 *maxyear
= edt
->priv
->clamp_maxyear
;
2190 *maxmonth
= edt
->priv
->clamp_maxmonth
;
2192 *maxday
= edt
->priv
->clamp_maxday
;
2196 * egg_datetime_get_clamp_time:
2197 * @edt: an #EggDateTime
2198 * @minhour: #guint8 pointer or %NULL
2199 * @minminute: #guint8 pointer or %NULL
2200 * @minsecond: #guint8 pointer or %NULL
2201 * @maxhour: #guint8 pointer or %NULL
2202 * @maxminute: #guint8 pointer or %NULL
2203 * @maxsecond: #guint8 pointer or %NULL
2205 * Returns the current time limit settings.
2208 egg_datetime_get_clamp_time (EggDateTime
*edt
, guint8
*minhour
, guint8
*minminute
, guint8
*minsecond
, guint8
*maxhour
, guint8
*maxminute
, guint8
*maxsecond
)
2210 g_return_if_fail (edt
!= NULL
);
2211 g_return_if_fail (EGG_IS_DATETIME (edt
));
2214 *minhour
= edt
->priv
->clamp_minhour
;
2216 *minminute
= edt
->priv
->clamp_minminute
;
2218 *minsecond
= edt
->priv
->clamp_minsecond
;
2220 *maxhour
= edt
->priv
->clamp_maxhour
;
2222 *maxminute
= edt
->priv
->clamp_maxminute
;
2224 *maxsecond
= edt
->priv
->clamp_maxsecond
;
2228 * egg_datetime_get_date_layout:
2229 * @edt: an #EggDateTime
2231 * Gets the PangoLayout used to display the date. See gtk_entry_get_layout()
2232 * for more information. The returned layout is owned by the date/time
2233 * widget so need not be freed by the caller.
2235 * Return value: the #PangoLayout for this widget's date part
2238 egg_datetime_get_date_layout (EggDateTime
*edt
)
2240 g_return_val_if_fail (edt
!= NULL
, NULL
);
2241 g_return_val_if_fail (EGG_IS_DATETIME (edt
), NULL
);
2243 return gtk_entry_get_layout (GTK_ENTRY (edt
->priv
->date_entry
));
2247 * egg_datetime_get_time_layout:
2248 * @edt: an #EggDateTime
2250 * Gets the PangoLayout used to display the time. See gtk_entry_get_layout()
2251 * for more information. The returned layout is owned by the date/time
2252 * widget so need not be freed by the caller.
2254 * Return value: the #PangoLayout for this widget's time part
2257 egg_datetime_get_time_layout (EggDateTime
*edt
)
2259 g_return_val_if_fail (edt
!= NULL
, NULL
);
2260 g_return_val_if_fail (EGG_IS_DATETIME (edt
), NULL
);
2262 return gtk_entry_get_layout (GTK_ENTRY (edt
->priv
->time_entry
));
2265 /**************************************************************************/
2267 /* This is a private time list widget implementation for use as time popup.
2271 timelist_new (EggDateTime
*edt
)
2273 GtkWidget
*timelist
;
2275 GtkListStore
*model
;
2276 GtkTreeSelection
*selection
;
2277 GtkCellRenderer
*renderer
;
2279 timelist
= gtk_scrolled_window_new (NULL
, NULL
);
2280 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (timelist
),
2284 model
= gtk_list_store_new (2, G_TYPE_STRING
, G_TYPE_UINT
);
2285 list
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (model
));
2286 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list
), FALSE
);
2287 gtk_widget_show (list
);
2289 renderer
= gtk_cell_renderer_text_new ();
2290 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (list
),
2297 gtk_container_add (GTK_CONTAINER (timelist
), list
);
2299 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (list
));
2300 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
2301 g_signal_connect_swapped(G_OBJECT(list
), "row-activated", G_CALLBACK(time_popup_hide
), edt
);
2302 timelist_set_list (TIMELIST (timelist
), 00, 00, 23, 59);
2308 timelist_set_list (Timelist
*timelist
,
2309 guint8 minhour
, guint8 minminute
,
2310 guint8 maxhour
, guint8 maxminute
)
2312 GtkWidget
*tree
= gtk_bin_get_child (GTK_BIN (timelist
));
2313 GtkTreeModel
*model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
));
2314 gint minidx
, maxidx
;
2318 minidx
= minhour
* 2 + (minminute
+ 29) / 30;
2319 maxidx
= maxhour
* 2 + (maxminute
+ 29) / 30;
2321 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
2322 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
2323 0, _("no end time"),
2327 for (i
= minidx
; i
< maxidx
; i
++) {
2332 minute
= (i
% 2) * 30;
2334 s
= get_time_string (hour
, minute
, 0xff);
2336 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
2337 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
2339 1, hour
* 100 + minute
,
2347 timelist_set_time (Timelist
*timelist
, gint hour
, gint minute
)
2349 GtkWidget
*tree
= gtk_bin_get_child (GTK_BIN (timelist
));
2350 GtkTreeModel
*model
;
2351 GtkTreeSelection
*selection
;
2354 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
));
2355 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
2357 if (!gtk_tree_model_get_iter_first (model
, &iter
))
2364 gtk_tree_model_get (model
, &iter
, 1, &time
, -1);
2366 if (time
/ 100 == hour
&& time
% 100 == minute
) {
2367 gtk_tree_selection_select_iter (selection
, &iter
);
2371 } while (gtk_tree_model_iter_next (model
, &iter
));
2373 gtk_tree_selection_unselect_all (selection
);
2377 timelist_get_time (Timelist
*timelist
, gint
*hour
, gint
*minute
)
2379 GtkWidget
*tree
= gtk_bin_get_child (GTK_BIN (timelist
));
2380 GtkTreeSelection
*selection
;
2381 GtkTreeModel
*model
;
2385 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
2387 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
2392 gtk_tree_model_get (model
, &iter
, 1, &time
, -1);
2404 *minute
= time
% 100;
2410 timelist_clamp (Timelist
*timelist
,
2411 guint8 minhour
, guint8 minminute
,
2412 guint8 maxhour
, guint8 maxminute
)
2414 timelist_set_list (timelist
, minhour
, minminute
, maxhour
, maxminute
);
2418 timelist_selection_cb (Timelist
*timelist
, GtkTreeSelection
*selection
)
2420 void (*cb
)(gpointer
, Timelist
*);
2423 cb
= g_object_get_data (G_OBJECT (selection
), "cb");
2424 data
= g_object_get_data (G_OBJECT (selection
), "data");
2426 cb (data
, timelist
);
2430 timelist_set_selection_callback (Timelist
*timelist
, void (*cb
)(void), gpointer data
)
2432 GtkWidget
*tree
= gtk_bin_get_child (GTK_BIN (timelist
));
2433 GtkTreeSelection
*selection
;
2435 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
2437 g_object_set_data (G_OBJECT (selection
), "cb", cb
);
2438 g_object_set_data (G_OBJECT (selection
), "data", data
);
2439 g_signal_connect_swapped (G_OBJECT (selection
), "changed",
2440 G_CALLBACK (timelist_selection_cb
), timelist
);