2006-08-30 Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
[hildon] / hildon-widgets / hildon-calendar-popup.c
index ee1d6dd..c365164 100644 (file)
@@ -1,14 +1,14 @@
 /*
  * This file is part of hildon-libs
  *
- * Copyright (C) 2005 Nokia Corporation.
+ * Copyright (C) 2005, 2006 Nokia Corporation.
  *
- * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
  *
  * This library is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  */
 
-/* HILDON DOC
+/**
+ * SECTION:hildon-calendar-popup
  * @shortdesc: CalendarPopup allows choosing a date from a popup calendar.
  * @longdesc: The Calendar popup is a dialog that contains a GtkCalendar 
- * widget. The pop-up is cancelled by
- * either a mouse click outside of the dialog or pressing the ESC
- * key.
+ * widget. The pop-up is cancelled by pressing the ESC key.
  * </para><para>
  * 
  * @seealso: #HildonDateEditor, #HildonTimeEditor
+ * 
+ * HildonCalendarPopup is a dialog which contains a GtkCalendar.  It
+ * also contains arrow buttons for changing the month/year. If an
+ * entered date is invalid, an information message will be shown.
  */
 
 #ifdef HAVE_CONFIG_H
 #include <time.h>
 #include <libintl.h>
 #include <hildon-widgets/hildon-calendar-popup.h>
-#include <hildon-widgets/gtk-infoprint.h>
 
 #define _(String) dgettext(PACKAGE, String)
 
 #define HILDON_CALENDAR_POPUP_GET_PRIVATE(obj) \
         (G_TYPE_INSTANCE_GET_PRIVATE\
-        ((obj), HILDON_CALENDAR_POPUP_TYPE, HildonCalendarPopupPrivate));
+        ((obj), HILDON_TYPE_CALENDAR_POPUP, HildonCalendarPopupPrivate));
 
 static GtkDialog *parent_class;
 
@@ -65,29 +67,27 @@ hildon_calendar_popup_class_init(HildonCalendarPopupClass * cal_class);
 
 static void hildon_calendar_popup_init(HildonCalendarPopup * cal);
 
-static void hildon_calendar_popup_set_property(GObject *object, guint param_id,
-                                               const GValue *value,
-                                               GParamSpec *pspec);
-
-static gboolean hildon_calendar_day_selected(GtkWidget * widget,
-                                             gpointer data);
-
-static void hildon_calendar_allow_exit(GtkWidget * self, gpointer data);
-
-static gboolean hildon_calendar_deny_exit(GtkWidget * self);
+static void hildon_calendar_selected_date(GtkWidget * self, gpointer cal_popup);
 
 static gboolean hildon_key_pressed(GtkWidget * widget, GdkEventKey * event,
-                                   gpointer data);
-
-enum
-{
-  PROP_MIN_YEAR = 1,
+                                   gpointer cal_popup);
+
+static void hildon_calendar_popup_set_property(GObject * object, guint property_id,
+                                    const GValue * value, GParamSpec * pspec);
+static void hildon_calendar_popup_get_property(GObject * object, guint property_id,
+                                    GValue * value, GParamSpec * pspec);
+
+enum {
+  PROP_0,
+  PROP_DAY,
+  PROP_MONTH,
+  PROP_YEAR,
+  PROP_MIN_YEAR,
   PROP_MAX_YEAR
 };
 
 struct _HildonCalendarPopupPrivate {
     GtkWidget *cal;
-    gboolean can_exit;
 };
 
 GType hildon_calendar_popup_get_type(void)
@@ -125,29 +125,22 @@ GType hildon_calendar_popup_get_type(void)
  * selected date is specified by the parameters (year, month, day).
  * If the specified date is invalid, the current date is used. 
  *
- * Return value: Pointer to a new @HildonCalendarPopup widget.
- **/
+ * Returns: new @HildonCalendarPopup widget
+ */
 GtkWidget *hildon_calendar_popup_new(GtkWindow * parent, guint year,
                                      guint month, guint day)
 {
     HildonCalendarPopup *cal = NULL;
-    HildonCalendarPopupPrivate *priv;
-    guint dtmp, mtmp, ytmp;
 
-    init_dmy(year, month, day, &dtmp, &mtmp, &ytmp);
-
-    cal = HILDON_CALENDAR_POPUP(g_object_new(HILDON_CALENDAR_POPUP_TYPE,
-                                             NULL));
-    priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
+    /* Create new HildonCalendarPopup */
+    cal = HILDON_CALENDAR_POPUP(g_object_new(HILDON_TYPE_CALENDAR_POPUP,
+                                             "year", year, "month", month, "day", day,
+                                            NULL));
 
     if (parent) {
         gtk_window_set_transient_for(GTK_WINDOW(cal), parent);
     }
 
-    /* Select day, month, year */
-    gtk_calendar_select_month(GTK_CALENDAR(priv->cal), mtmp - 1, ytmp);
-    gtk_calendar_select_day(GTK_CALENDAR(priv->cal), dtmp);
-
     return GTK_WIDGET(cal);
 }
 
@@ -158,23 +151,29 @@ GtkWidget *hildon_calendar_popup_new(GtkWindow * parent, guint year,
  * @month: month
  * @day: day
  *
- * This function activates a new date on the calendar popup.
+ * activates a new date on the calendar popup.
  **/
-
-
 void
 hildon_calendar_popup_set_date(HildonCalendarPopup * cal,
                                guint year, guint month, guint day)
 {
+    guint dtmp, mtmp, ytmp = 0;
     HildonCalendarPopupPrivate *priv;
 
     g_return_if_fail(HILDON_IS_CALENDAR_POPUP(cal));
 
     priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
+
+    /* Choose current date if the date is invalid: 
+     */
+    init_dmy(year, month, day, &dtmp, &mtmp, &ytmp);
+
+    /* Remove all visual markers */
     gtk_calendar_clear_marks(GTK_CALENDAR(priv->cal));
 
-    gtk_calendar_select_month(GTK_CALENDAR(priv->cal), month - 1, year);
-    gtk_calendar_select_day(GTK_CALENDAR(priv->cal), day);
+    /* Set a new date */
+    gtk_calendar_select_month(GTK_CALENDAR(priv->cal), mtmp - 1, ytmp);
+    gtk_calendar_select_day(GTK_CALENDAR(priv->cal), dtmp);
 }
 
 /**
@@ -184,10 +183,8 @@ hildon_calendar_popup_set_date(HildonCalendarPopup * cal,
  * @month: month
  * @day: day
  *
- * This function is used to get the currently selected year, month,
- * and day. 
- **/
-
+ * Gets the currently selected year, month, and day. 
+ */
 void
 hildon_calendar_popup_get_date(HildonCalendarPopup * cal,
                                guint * year, guint * month, guint * day)
@@ -208,28 +205,59 @@ hildon_calendar_popup_get_date(HildonCalendarPopup * cal,
 static void
 hildon_calendar_popup_class_init(HildonCalendarPopupClass * cal_class)
 {
-    GObjectClass *gobject_class = G_OBJECT_CLASS(cal_class);
+    GObjectClass *object_class = G_OBJECT_CLASS(cal_class);
     parent_class = g_type_class_peek_parent(cal_class);
+    
+    object_class->set_property = hildon_calendar_popup_set_property;
+    object_class->get_property = hildon_calendar_popup_get_property;
 
     g_type_class_add_private(cal_class,
                              sizeof(HildonCalendarPopupPrivate));
 
-    gobject_class->set_property = hildon_calendar_popup_set_property;
-
-    g_object_class_install_property(gobject_class, PROP_MIN_YEAR,
+    /* Install new properties for the GObject_class */
+    g_object_class_install_property(object_class, PROP_MIN_YEAR,
                                     g_param_spec_uint("min-year",
                                                       "Minimum valid year",
                                                       "Minimum valid year",
                                                       1, 2100,
                                                       1970,
                                                       G_PARAM_WRITABLE));
-    g_object_class_install_property(gobject_class, PROP_MAX_YEAR,
+
+    g_object_class_install_property(object_class, PROP_MAX_YEAR,
                                     g_param_spec_uint("max-year",
                                                       "Maximum valid year",
                                                       "Maximum valid year",
                                                       1, 2100,
                                                       2037,
                                                       G_PARAM_WRITABLE));
+
+    g_object_class_install_property(object_class, PROP_DAY,
+                                   g_param_spec_int ("day",
+                                                     "Day",
+                                                     "currently selected day",
+                                                     G_MININT,
+                                                     G_MAXINT,
+                                                     0,
+                                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property(object_class, PROP_MONTH,
+                                   g_param_spec_int ("month",
+                                                     "Month",
+                                                     "currently selected month",
+                                                     G_MININT,
+                                                     G_MAXINT,
+                                                     0,
+                                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property(object_class, PROP_YEAR,
+                                   g_param_spec_int ("year",
+                                                     "Year",
+                                                     "the currently selected year",
+                                                     G_MININT,
+                                                     G_MAXINT,
+                                                     0,
+                                                     G_PARAM_READWRITE));
+
 }
 
 static void hildon_calendar_popup_init(HildonCalendarPopup * cal)
@@ -239,14 +267,15 @@ static void hildon_calendar_popup_init(HildonCalendarPopup * cal)
 
     priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
 
+    /* set the domain directory for different language */
     if (set_domain) {
         (void) bindtextdomain(PACKAGE, LOCALEDIR);
         set_domain = 0;
     }
 
-    priv->can_exit = FALSE;
     priv->cal = gtk_calendar_new();
 
+    /* dialog options and packing */
     gtk_calendar_set_display_options(GTK_CALENDAR(priv->cal),
                                      GTK_CALENDAR_SHOW_HEADING |
                                      GTK_CALENDAR_SHOW_DAY_NAMES |
@@ -255,107 +284,67 @@ static void hildon_calendar_popup_init(HildonCalendarPopup * cal)
     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cal)->vbox), priv->cal,
                        TRUE, TRUE, 0);
     gtk_dialog_set_has_separator(GTK_DIALOG(cal), FALSE);
-    gtk_dialog_add_button(GTK_DIALOG(cal), _("Ecdg_bd_calendar_popout_done"),
+    gtk_dialog_add_button(GTK_DIALOG(cal), _("ecdg_bd_calendar_popout_done"),
                             GTK_RESPONSE_OK);
     gtk_widget_show(priv->cal);
 
     /* Connect signals */
-    g_signal_connect(G_OBJECT(priv->cal), "day-selected",
-                     G_CALLBACK(hildon_calendar_day_selected), cal);
-
     g_signal_connect(G_OBJECT(priv->cal), "key-press-event",
                      G_CALLBACK(hildon_key_pressed), cal);
-    g_signal_connect_swapped(G_OBJECT(priv->cal), "button-release-event",
-                             G_CALLBACK(hildon_calendar_deny_exit), cal);
-    g_signal_connect_swapped(G_OBJECT(priv->cal), "month-changed",
-                             G_CALLBACK(hildon_calendar_deny_exit), cal);
-    g_signal_connect_swapped(G_OBJECT(priv->cal), "button-press-event",
-                             G_CALLBACK(hildon_calendar_deny_exit), cal);
 
     g_signal_connect(G_OBJECT(priv->cal), "selected_date",
-                     G_CALLBACK(hildon_calendar_allow_exit), cal);
+                     G_CALLBACK(hildon_calendar_selected_date), cal);
 
+    /* set decorations, needs realizing first*/
     gtk_widget_realize(GTK_WIDGET(cal));
     gdk_window_set_decorations(GTK_WIDGET(cal)->window, GDK_DECOR_BORDER);
-    gtk_widget_grab_focus(priv->cal);
-}
-
-static void hildon_calendar_popup_set_property(GObject *object, guint param_id,
-                                               const GValue *value,
-                                               GParamSpec *pspec)
-{
-  HildonCalendarPopupPrivate *priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(object);
 
-  switch (param_id)
-  {
-    case PROP_MIN_YEAR:
-      g_object_set_property(G_OBJECT(priv->cal), "min-year", value);
-      break;
-    case PROP_MAX_YEAR:
-      g_object_set_property(G_OBJECT(priv->cal), "max-year", value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
-      break;
-  }
 }
 
-static gboolean
-hildon_calendar_day_selected(GtkWidget * widget, gpointer data)
-{
-    HildonCalendarPopup *cal;
-    HildonCalendarPopupPrivate *priv;
-
-    cal = HILDON_CALENDAR_POPUP(data);
-    priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
-
-    if (priv->can_exit) {
-        gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_ACCEPT);
-        return TRUE;
-    }
-    return FALSE;
-}
 
+/*
+ * Signal handler for key-press-event. Closes the dialog for some
+ * special keys.
+ */
 static gboolean
-hildon_key_pressed(GtkWidget * widget, GdkEventKey * event, gpointer data)
+hildon_key_pressed(GtkWidget * widget, GdkEventKey * event, gpointer cal_popup)
 {
-    HildonCalendarPopup *cal;
-    HildonCalendarPopupPrivate *priv;
-
-    g_return_val_if_fail(data, FALSE);
+    g_assert(HILDON_IS_CALENDAR_POPUP(cal_popup));
 
-    cal = HILDON_CALENDAR_POPUP(data);
-    priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
-
-    if (event->keyval == GDK_Return) {
-        priv->can_exit = TRUE;
-        gtk_dialog_response(GTK_DIALOG(cal), GTK_RESPONSE_OK);
+    /* Handle Return key press as OK response */
+    if (event->keyval == GDK_Return)
+    {
+        gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_OK);
         return TRUE;
     }
 
-    if ((event->keyval == GDK_Escape) || (event->keyval == GDK_F1) ||
-        (event->keyval == GDK_F2) || (event->keyval == GDK_F3) ||
-        (event->keyval == GDK_F4) || (event->keyval == GDK_F5) ||
-        (event->keyval == GDK_F6) || (event->keyval == GDK_F7) ||
-        (event->keyval == GDK_F8)) {
-        gtk_dialog_response(GTK_DIALOG(cal), GTK_RESPONSE_CANCEL);
+    /* Handle Esc key press as CANCEL response */
+    if ((event->keyval == GDK_Escape))
+    {
+        gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_CANCEL);
         return TRUE;
     }
 
     return FALSE;
 }
 
+
+/*
+ * Validates the given date or initializes it with the current date
+ */
 static void
-init_dmy(guint year, guint month, guint day, guint * d, guint * m,
-         guint * y)
+init_dmy(guint year, guint month, guint day, guint *d, guint *m, guint *y)
 {
     GDate date;
 
+    /* Initialize the date with a valid selected date */ 
     if (g_date_valid_dmy(day, month, year)) {
         *d = day;
         *m = month;
         *y = year;
-    } else {
+    } else { 
+
+      /* If selected date is invalid initialize the date with current date */ 
         g_date_clear(&date, 1);
         g_date_set_time(&date, time(NULL));
 
@@ -365,29 +354,86 @@ init_dmy(guint year, guint month, guint day, guint * d, guint * m,
     }
 }
 
+/*
+ * Exits the dialog when "selected_date" signal is emmited. The
+ * "selected_date" signal is a Hildon addition to GtkCalendar and is
+ * emitted on button-release.
+ */
 static void
-hildon_calendar_allow_exit(GtkWidget * self, gpointer data)
+hildon_calendar_selected_date(GtkWidget * self, gpointer cal_popup)
 {
-    HildonCalendarPopup *cal;
-    HildonCalendarPopupPrivate *priv;
-
-    g_return_if_fail (GTK_IS_WIDGET (self));
-    g_return_if_fail (HILDON_IS_CALENDAR_POPUP (data)); 
-    
-    cal = HILDON_CALENDAR_POPUP(data);
-    priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
-  
-    gtk_dialog_response(GTK_DIALOG(cal), GTK_RESPONSE_OK);
+    g_assert(GTK_IS_WIDGET (self));
+    g_assert(HILDON_IS_CALENDAR_POPUP (cal_popup));
+    gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_OK);
 }
 
-static gboolean hildon_calendar_deny_exit(GtkWidget * self)
-{
-    HildonCalendarPopup *cal;
-    HildonCalendarPopupPrivate *priv;
 
-    cal = HILDON_CALENDAR_POPUP(self);
-    priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
+static void hildon_calendar_popup_set_property(GObject * object, guint property_id,
+                                    const GValue * value, GParamSpec * pspec)
+{
+    HildonCalendarPopup *popup = HILDON_CALENDAR_POPUP (object);
+    HildonCalendarPopupPrivate *priv = 
+       HILDON_CALENDAR_POPUP_GET_PRIVATE(HILDON_CALENDAR_POPUP (object));
+
+    switch (property_id) {
+    case PROP_DAY:
+    {
+        guint year, month, day = 0;
+        hildon_calendar_popup_get_date(popup, &year, &month, &day);
+
+        /*Verifies that the date is valid: */
+        hildon_calendar_popup_set_date(popup, year, month, g_value_get_int(value));
+        break;
+    }
+    case PROP_MONTH:
+    {
+        guint year, month, day = 0;
+        hildon_calendar_popup_get_date(popup, &year, &month, &day);
+
+        /*Verifies that the date is valid: */
+        hildon_calendar_popup_set_date(popup, year, g_value_get_int(value), day);
+        break;
+    }
+    case PROP_YEAR:
+    {
+        guint year, month, day = 0;
+        hildon_calendar_popup_get_date(popup, &year, &month, &day);
+
+        /*Verifies that the date is valid: */
+        hildon_calendar_popup_set_date(popup, g_value_get_int(value), month, day);
+        break;
+    }
+    case PROP_MIN_YEAR:
+        g_object_set_property(G_OBJECT(priv->cal), "min-year", value);
+        break;
+    case PROP_MAX_YEAR:
+        g_object_set_property(G_OBJECT(priv->cal), "max-year", value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+        break;
+    }
+}
 
-    priv->can_exit = FALSE;
-    return FALSE;
+static void hildon_calendar_popup_get_property(GObject * object, guint property_id,
+                                    GValue * value, GParamSpec * pspec)
+{
+    HildonCalendarPopupPrivate *priv = 
+       HILDON_CALENDAR_POPUP_GET_PRIVATE(HILDON_CALENDAR_POPUP (object));
+
+    switch (property_id) {
+    case PROP_DAY:
+        g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
+        break;
+    case PROP_MONTH:
+        g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
+        break;
+    case PROP_YEAR:
+        g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+        break;
+    }
 }