datetime_base.c

Go to the documentation of this file.
00001 /*
00002  * File Name: datetime_base.c
00003  */
00004 
00005 /*
00006  * This file is part of settings.
00007  *
00008  * settings is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * settings is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /**
00023  * Copyright (C) 2009 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 //----------------------------------------------------------------------------
00028 // Include Files
00029 //----------------------------------------------------------------------------
00030 
00031 #include "config.h"
00032 
00033 #include <gtk/gtk.h>
00034 #include <gdk/gdk.h>
00035 #include <gdk/gdkkeysyms.h>
00036 
00037 #include <liberutilstime/time_utils.h>
00038 
00039 #include "i18n.h"
00040 #include "log.h"
00041 #include "ipc.h"
00042 #include "settings.h"
00043 #include "settings_utils.h"
00044 #include "settings_style.h"
00045 #include "datetime_base.h"
00046 
00047 //----------------------------------------------------------------------------
00048 // Global Constants
00049 //----------------------------------------------------------------------------
00050 
00051 #define BUF_LEN            256
00052 
00053 //----------------------------------------------------------------------------
00054 // Static Variables
00055 //----------------------------------------------------------------------------
00056 
00057 static const GdkColor grey =  {0, 0x5500, 0x5500, 0x5500};
00058 static const GdkColor white = {0, 0xFF00, 0xFF00, 0xFF00};
00059 
00060 
00061 //============================================================================
00062 // Local Function Definitions
00063 //============================================================================
00064 
00065 // Functions of creating widgets.
00066 static void create_timezone_widget(DateTimeWidgets * widgets);
00067 static void create_time_widget(DateTimeWidgets * widgets);
00068 static void create_date_widget(DateTimeWidgets * widgets);
00069 
00070 static void init_widgets (DateTimeWidgets * widgets, DateTimeSettings * data);
00071 
00072 // Signal handlers.
00073 
00074 // 
00075 static void install_spinbutton_keypress_handler(DateTimeWidgets * widgets);
00076 
00077 // The 'input' and 'output' signal handlers of spin buttons.
00078 static gint on_timezone_input(GtkSpinButton* spin, gdouble* new_val);
00079 static gint on_timezone_output(GtkSpinButton* spin);
00080 
00081 static gint on_minutes_output(GtkSpinButton* spin);
00082 
00083 static gint on_am_pm_input(GtkSpinButton* spin, gdouble* new_val);
00084 static gint on_am_pm_output(GtkSpinButton* spin);
00085 
00086 static gint on_month_input(GtkSpinButton* spin, gdouble* new_val);
00087 static gint on_month_output(GtkSpinButton* spin, DateTimeWidgets* widgets);
00088 static gint on_date_change(GtkSpinButton* spin, DateTimeWidgets* widgets);
00089 
00090 static gboolean on_key_pressed(GtkWidget* widget, 
00091                                GdkEventKey *event, 
00092                                gpointer user_data);
00093 
00094 static void check_clock(DateTimeWidgets * widgets);
00095 static void check_orientation(DateTimeWidgets * widgets);
00096 
00097 // Get the datetime user set in the widgets. 
00098 static time_t get_time_from_dialog(DateTimeWidgets * widgets);
00099 static int get_days_of_month(int year, int month);
00100 
00101 
00102 //============================================================================
00103 // Functions Implementation
00104 //============================================================================
00105 
00106 void datetime_base_load_datetime(DateTimeSettings * data)
00107 {
00108     LOGPRINTF("entry");
00109     if (data)
00110     {
00111         time_t curtime = time(NULL);
00112         curtime -= curtime % 60; // datetime in minutes
00113 
00114         data->orig_datetime = curtime;
00115         data->cur_datetime = curtime;
00116     }
00117 }
00118 
00119 gboolean datetime_base_save_datetime(DateTimeWidgets * widgets, 
00120                                      DateTimeSettings * data)
00121 {
00122     gboolean ret = FALSE;
00123     LOGPRINTF("entry");
00124     
00125     if (widgets && data)
00126     {
00127         // Set timezone and DST.
00128         gboolean is_dst = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->dst_button));
00129         GtkAdjustment* adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(widgets->timezone_button));
00130         int tzindex = (int)gtk_adjustment_get_value(adj);
00131         set_timezone(timezones[tzindex].tzname, is_dst);
00132 
00133         // Set time if necessary.
00134         data->cur_datetime = get_time_from_dialog(widgets);
00135         if (data->cur_datetime != data->orig_datetime)
00136         {
00137             ret = set_date_time(data->cur_datetime);
00138         }
00139         else
00140         {
00141             ret = TRUE; // nothing to do.
00142         }
00143     }
00144     return ret;
00145 }
00146 
00147 // Widget Hierarchy
00148 //    |--vbox
00149 //       |--time
00150 //       |--date
00151 void datetime_base_create_widgets(DateTimeWidgets * widgets,
00152                                   DateTimeSettings * data)
00153 {
00154     LOGPRINTF("entry");
00155 
00156     if (widgets && data)
00157     {
00158         check_clock(widgets);
00159 
00160         // check the current orientation of the device. 
00161         // Adjust key behavior accordingly
00162         check_orientation(widgets);
00163 
00164         // Create widgets.
00165         widgets->parent = gtk_vbox_new(FALSE, 0);
00166         create_timezone_widget(widgets);
00167         create_time_widget(widgets);
00168         create_date_widget(widgets);
00169 
00170         // Install handlers.
00171         install_spinbutton_keypress_handler(widgets);
00172         
00173         // Init widgets with settings.
00174         init_widgets(widgets, data);
00175     }
00176 }
00177 
00178 void datetime_base_locale_changed(DateTimeWidgets * widgets, 
00179         DateTimeSettings * data)
00180 {
00181     LOGPRINTF("entry");
00182 
00183     struct tm* local_time = localtime(&data->cur_datetime);
00184 
00185     if (widgets->twelve_clock)
00186     {
00187         if (local_time->tm_hour < 12)
00188         {
00189             gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->am_pm_button), 0);
00190         }
00191         else
00192         {
00193             gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->am_pm_button), 1);
00194         }
00195     }
00196 
00197     gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->month_button), 
00198                               local_time->tm_mon + 1);
00199 } 
00200 
00201 //============================================================================
00202 // Local Functions Implementation
00203 //============================================================================
00204 
00205 static void check_orientation(DateTimeWidgets * widgets)
00206 {
00207     LOGPRINTF("entry");
00208 
00209     // use sync ipc call to check orientation of device
00210     widgets->is_portrait = ipc_sys_is_in_portrait_mode();
00211 }
00212 
00213 static void check_clock(DateTimeWidgets * widgets)
00214 {
00215     LOGPRINTF("entry");
00216 
00217     // Set the default value.
00218     widgets->twelve_clock = FALSE;
00219 
00220     // Construct the list of locales which use 12h clock.
00221     GList *list = NULL;
00222     list = g_list_append (list, "en_US");
00223     list = g_list_append (list, "en_CA");
00224     list = g_list_append (list, "en_IN");
00225    
00226     // Get the current locale.
00227     const gchar * locale = g_getenv("LANG");
00228     LOGPRINTF("locale %s", locale);
00229     if (locale)
00230     {
00231         unsigned int i = 0;
00232         for (i = 0; i < g_list_length(list); i++)
00233         {
00234             GList * ptr = g_list_nth(list, i);
00235             if (g_strncasecmp(ptr->data, locale, strlen(ptr->data)) == 0)
00236             {
00237                 widgets->twelve_clock = TRUE;
00238                 break;
00239             }
00240         }
00241     }
00242 
00243     g_list_free(list);
00244 }
00245 
00246 
00247 // Widget Hierarchy
00248 // |--vbox (frame)
00249 //    |--label ("Timezone")
00250 //    |--label (description)
00251 //    |--alignment
00252 //       |--hbox
00253 //          |--widgets->timezone_button
00254 //          |--widgets->dst_button
00255 static void create_timezone_widget(DateTimeWidgets * widgets) 
00256 {
00257     LOGPRINTF("entry");
00258 
00259     GtkVBox* frame = create_frame(GTK_VBOX(widgets->parent));
00260 
00261     // The label "Timezone".
00262     widgets->label_timezone = subject_create();
00263     gtk_box_pack_start(GTK_BOX(frame), widgets->label_timezone, FALSE, FALSE, 0);
00264 
00265     // The label "description".
00266     widgets->label_timezone_desc = description_create();
00267     gtk_box_pack_start(GTK_BOX(frame), widgets->label_timezone_desc, FALSE, FALSE, 0);
00268 
00269     // timezone
00270     widgets->timezone_button = NULL;
00271     GtkAdjustment* adj;
00272     adj = (GtkAdjustment *)gtk_adjustment_new(0, 0, TOTAL_TIMEZONES-1, 1.0, 5.0, 0.0);
00273     widgets->timezone_button = gtk_spin_button_new (adj, 4, 0);
00274     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(widgets->timezone_button), TRUE);
00275     gtk_entry_set_editable (GTK_ENTRY(widgets->timezone_button), FALSE);
00276     gtk_entry_set_width_chars(GTK_ENTRY(widgets->timezone_button), 40);
00277     gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(widgets->timezone_button), 
00278                                      GTK_UPDATE_ALWAYS);
00279     gtk_widget_modify_text(widgets->timezone_button, GTK_STATE_NORMAL, &grey); 
00280     gtk_widget_modify_font (widgets->timezone_button, 
00281             pango_font_description_from_string ("Normal italic 9"));
00282     g_signal_connect(widgets->timezone_button, "input", 
00283                     G_CALLBACK(on_timezone_input), NULL) ;
00284     g_signal_connect(widgets->timezone_button, "output", 
00285                     G_CALLBACK(on_timezone_output), NULL) ;
00286     gtk_box_pack_start(GTK_BOX(frame), widgets->timezone_button, FALSE, FALSE, 0);
00287 
00288     // separator
00289     GtkWidget* separator = create_separator_widgets();
00290     gtk_widget_set_name(separator, "irex-separator-invisible");
00291     gtk_box_pack_start(GTK_BOX(frame), separator, FALSE, FALSE, 0);
00292     
00293     // dst description
00294     widgets->label_dst_desc = description_create();
00295     gtk_box_pack_start(GTK_BOX(frame), widgets->label_dst_desc, TRUE, TRUE, 0);    
00296     
00297     // dst checkbox
00298     widgets->dst_button = gtk_check_button_new_with_label(_("Daylight Savings Time is in effect"));
00299     gtk_box_pack_start(GTK_BOX(frame), widgets->dst_button, FALSE, FALSE, 0);    
00300 }
00301 
00302 
00303 // Widget Hierarchy
00304 // |--vbox (frame)
00305 //    |--label ("Time")
00306 //    |--label (description)
00307 //    |--alignment
00308 //       |--hbox
00309 //          |--widgets->hour_button
00310 //          |--widgets->minute_button
00311 //          |--widgets->am_pm_button
00312 static void create_time_widget(DateTimeWidgets * widgets) 
00313 {
00314     LOGPRINTF("entry");
00315 
00316     GtkVBox* frame = create_frame(GTK_VBOX(widgets->parent));
00317 
00318     // The label "Time".
00319     widgets->label_time = subject_create();
00320     gtk_box_pack_start(GTK_BOX(frame), widgets->label_time, FALSE, FALSE, 0);
00321 
00322     // The label "description".
00323     widgets->label_time_desc = description_create();
00324     gtk_box_pack_start(GTK_BOX(frame), widgets->label_time_desc, FALSE, FALSE, 0);
00325 
00326     // alignment
00327     GtkWidget * alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
00328     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 
00329                               WINDOW_TOP_ALT_PADDING,
00330                               WINDOW_BOTTOM_PADDING,
00331                               0,
00332                               0);
00333     gtk_box_pack_start(GTK_BOX(frame), alignment, FALSE, FALSE, 0);
00334 
00335     // hbox
00336     GtkWidget * hbox = gtk_hbox_new(FALSE, SMALL_SPACING * 3);
00337     gtk_container_add(GTK_CONTAINER(alignment), hbox);
00338 
00339     // hour
00340     gdouble lower = 0.0;
00341     gdouble upper = 23.0;
00342     if (widgets->twelve_clock)
00343     {
00344         lower = 1.0;
00345         upper = 12.0;
00346     }
00347     GtkAdjustment* adj;
00348     adj = (GtkAdjustment *)gtk_adjustment_new(lower, lower, upper, 1.0, 5.0, 0.0);
00349     widgets->hour_button = gtk_spin_button_new(adj, 4, 0);
00350     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(widgets->hour_button), TRUE);
00351     gtk_entry_set_editable (GTK_ENTRY(widgets->hour_button), FALSE);
00352     gtk_widget_modify_text(widgets->hour_button, GTK_STATE_NORMAL, &grey); 
00353     gtk_widget_modify_font(widgets->hour_button, 
00354                             pango_font_description_from_string ("Normal italic 9"));
00355     gtk_box_pack_start(GTK_BOX(hbox), widgets->hour_button, FALSE, FALSE, 0);
00356 
00357     // minute
00358     adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 59.0, 1.0, 5.0, 0.0);
00359     widgets->minute_button = gtk_spin_button_new (adj, 4, 0);
00360     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(widgets->minute_button), TRUE);
00361     gtk_entry_set_editable(GTK_ENTRY(widgets->minute_button), FALSE);
00362     gtk_widget_modify_text(widgets->minute_button, GTK_STATE_NORMAL, &grey); 
00363     gtk_widget_modify_font(widgets->minute_button, 
00364                            pango_font_description_from_string ("Normal italic 9"));
00365                                 
00366     g_signal_connect(widgets->minute_button, "output", G_CALLBACK(on_minutes_output), NULL);
00367     gtk_box_pack_start(GTK_BOX(hbox), widgets->minute_button, FALSE, FALSE, 0);
00368 
00369     // am_pm 
00370     widgets->am_pm_button = NULL;
00371     if (widgets->twelve_clock)
00372     {
00373         adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 1.0, 1.0, 1.0, 0.0);
00374         widgets->am_pm_button = gtk_spin_button_new (adj, 4, 0);
00375         gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(widgets->am_pm_button), TRUE);
00376         gtk_entry_set_editable (GTK_ENTRY(widgets->am_pm_button), FALSE);
00377         gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(widgets->am_pm_button), 
00378                                          GTK_UPDATE_ALWAYS);
00379         gtk_widget_modify_text(widgets->am_pm_button, GTK_STATE_NORMAL, &grey); 
00380         gtk_widget_modify_font (widgets->am_pm_button, 
00381                 pango_font_description_from_string ("Normal italic 9"));
00382         g_signal_connect(widgets->am_pm_button, "input", 
00383                         G_CALLBACK(on_am_pm_input), NULL) ;
00384         g_signal_connect(widgets->am_pm_button, "output", 
00385                         G_CALLBACK(on_am_pm_output), NULL) ;
00386         gtk_box_pack_start(GTK_BOX(hbox), widgets->am_pm_button, FALSE, FALSE, 0);
00387     }
00388 }
00389 
00390 
00391 // Widget Hierarchy
00392 // |--vbox (frame)
00393 //    |--label ("Date")
00394 //    |--label (description)
00395 //    |--alignment
00396 //       |--hbox
00397 //          |--widgets->day_button
00398 //          |--widgets->month_button
00399 //          |--widgets->year_button
00400 static void create_date_widget(DateTimeWidgets * widgets)
00401 {
00402     LOGPRINTF("entry");
00403     
00404     GtkVBox* frame = create_frame(GTK_VBOX(widgets->parent));
00405 
00406     // The label "Date".
00407     widgets->label_date = subject_create();
00408     gtk_box_pack_start(GTK_BOX(frame), widgets->label_date, FALSE, FALSE, 0);
00409 
00410     // The label "description".
00411     widgets->label_date_desc = description_create();
00412     gtk_box_pack_start(GTK_BOX(frame), widgets->label_date_desc, FALSE, FALSE, 0);
00413 
00414     // alignment
00415     GtkWidget * alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
00416     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 
00417                               WINDOW_TOP_ALT_PADDING,
00418                               WINDOW_BOTTOM_PADDING,
00419                               0,
00420                               0);
00421     gtk_box_pack_start(GTK_BOX(frame), alignment, FALSE, FALSE, 0);
00422 
00423     // hbox
00424     GtkWidget * hbox = gtk_hbox_new(FALSE, SMALL_SPACING * 3);
00425     gtk_container_add(GTK_CONTAINER(alignment), hbox);
00426 
00427     // day
00428     GtkAdjustment* adj = 
00429         (GtkAdjustment *) gtk_adjustment_new(0.0, 1.0, 31.0, 1.0, 5.0, 0.0);
00430     widgets->day_button = gtk_spin_button_new(adj, 4, 0);
00431     gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(widgets->day_button), TRUE);
00432     gtk_entry_set_editable(GTK_ENTRY(widgets->day_button), FALSE);
00433     gtk_widget_modify_text(widgets->day_button, GTK_STATE_NORMAL, &grey); 
00434     gtk_widget_modify_font (widgets->day_button, 
00435                             pango_font_description_from_string ("Normal italic 9"));
00436     gtk_box_pack_start(GTK_BOX(hbox), widgets->day_button, FALSE, FALSE, 0);
00437 
00438     // month
00439     adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0, 5.0, 0.0);
00440     widgets->month_button = gtk_spin_button_new (adj, 4, 0);
00441     gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON(widgets->month_button), 
00442                                        GTK_UPDATE_IF_VALID);
00443     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(widgets->month_button), TRUE);
00444     gtk_entry_set_editable (GTK_ENTRY(widgets->month_button), FALSE);
00445     gtk_widget_modify_text(widgets->month_button, GTK_STATE_NORMAL, &grey); 
00446     gtk_widget_modify_font (widgets->month_button, 
00447             pango_font_description_from_string ("Normal italic 9"));
00448                 
00449     g_signal_connect(G_OBJECT(widgets->month_button), "input", 
00450                      G_CALLBACK(on_month_input), NULL);
00451     g_signal_connect(G_OBJECT(widgets->month_button), "output", 
00452                      G_CALLBACK(on_month_output), widgets);
00453     gtk_box_pack_start(GTK_BOX(hbox), widgets->month_button, FALSE, FALSE, 0);
00454 
00455     // year
00456     adj=(GtkAdjustment*)gtk_adjustment_new(0.0, 1900.0, 9999.0, 1.0, 5.0, 0.0);
00457     widgets->year_button = gtk_spin_button_new (adj, 4, 0);
00458     gtk_spin_button_set_wrap (GTK_SPIN_BUTTON(widgets->year_button), TRUE);
00459     gtk_entry_set_editable (GTK_ENTRY(widgets->year_button), FALSE);
00460     gtk_widget_modify_text(widgets->year_button, GTK_STATE_NORMAL, &grey); 
00461     gtk_widget_modify_font(widgets->year_button, 
00462                             pango_font_description_from_string ("Normal italic 9"));
00463     g_signal_connect(G_OBJECT(widgets->year_button), "changed", 
00464                      G_CALLBACK(on_date_change), widgets);
00465     gtk_box_pack_start(GTK_BOX(hbox), widgets->year_button, FALSE, FALSE, 0);
00466 
00467 
00468     // Add hidden button and signal handler.
00469     // 0003462: firstboot - Initial time & date setting page not full screen
00470     // This is a workaround for solving the problem of the cursor 
00471     // on year spinbutton doesn't update when focus out.
00472     widgets->hidden_button = gtk_button_new();
00473     gtk_widget_set_size_request(widgets->hidden_button, -1, -1);
00474     g_object_set(G_OBJECT(widgets->hidden_button), 
00475                  "focus-on-click", FALSE, NULL);
00476     gtk_widget_modify_fg(widgets->hidden_button, GTK_STATE_NORMAL, &white); //invisable
00477     gtk_widget_modify_fg(widgets->hidden_button, GTK_STATE_ACTIVE, &white); //invisable
00478     gtk_widget_modify_fg(widgets->hidden_button, GTK_STATE_SELECTED, &white); //invisable
00479     gtk_box_pack_start(GTK_BOX(hbox), widgets->hidden_button, FALSE, FALSE, 0);
00480 }
00481 
00482 static void init_widgets(DateTimeWidgets * widgets, DateTimeSettings * data)
00483 {
00484     LOGPRINTF("entry");
00485 
00486     // Set current timezone and DST.
00487     gboolean is_dst = FALSE;
00488     gchar *tzname = get_timezone();
00489     gint tzindex = get_timezone_index(tzname, &is_dst);
00490     LOGPRINTF("tzname [%s] tzindex [%d] is_dst [%d]", tzname, tzindex, is_dst);
00491     g_free(tzname);
00492     
00493     gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->timezone_button), tzindex);
00494     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widgets->dst_button), is_dst);
00495 
00496     // Set current time.
00497     struct tm* local_time = localtime(&data->cur_datetime);
00498     if (widgets->twelve_clock)
00499     {
00500         if (local_time->tm_hour == 0)
00501         {
00502             gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->hour_button), 12);
00503         }
00504         else if (local_time->tm_hour <= 12)
00505         {
00506             gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->hour_button), 
00507                                       local_time->tm_hour);
00508         }
00509         else
00510         {
00511             gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->hour_button), 
00512                                       local_time->tm_hour - 12); 
00513         }
00514 
00515         gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->minute_button), 
00516                                   local_time->tm_min);
00517 
00518         if (local_time->tm_hour < 12)
00519         {
00520             gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->am_pm_button), 0);
00521         }
00522         else
00523         {
00524             gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->am_pm_button), 1);
00525         }
00526     }
00527     else
00528     {
00529         gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->hour_button), 
00530                                   local_time->tm_hour);
00531         gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->minute_button), 
00532                                   local_time->tm_min);
00533     }
00534 
00535     // Set current date.
00536     gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->day_button), 
00537                               local_time->tm_mday);
00538     gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->month_button), 
00539                               local_time->tm_mon + 1);
00540     gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->year_button), 
00541                               local_time->tm_year + 1900);
00542 
00543 }
00544 
00545 static void install_spinbutton_keypress_handler(DateTimeWidgets * widgets)
00546 {
00547     LOGPRINTF("entry");
00548 
00549     // Translate the behaviour of 'enter' key as 'Tab'.
00550     GList * list = NULL;
00551     list = g_list_append(list, widgets->timezone_button);
00552     // DST button is added to the list for navigation but it does not connect to 
00553     // "activate" and "key-press-event" as these are handled by the checkbutton widget
00554     list = g_list_append(list, widgets->dst_button);
00555     list = g_list_append(list, widgets->hour_button);
00556     list = g_list_append(list, widgets->minute_button); 
00557     if (widgets->twelve_clock)
00558     {
00559        list = g_list_append(list, widgets->am_pm_button);
00560     }
00561     list = g_list_append(list, widgets->day_button);
00562     list = g_list_append(list, widgets->month_button); 
00563     list = g_list_append(list, widgets->year_button);
00564     
00565     int spinbuttons_number = g_list_length(list);
00566     int i = 0;
00567     for (i = 0; i < (spinbuttons_number - 1); i++)
00568     {
00569         GList * spin1 = g_list_nth(list, i);
00570         GList * spin2 = g_list_nth(list, i + 1);
00571         
00572         if (spin1->data != widgets->dst_button)
00573         {
00574             g_signal_connect_swapped(spin1->data, "activate",
00575                 G_CALLBACK (gtk_widget_grab_focus), spin2->data);
00576         }
00577     }
00578 
00579     GList * spin = g_list_nth(list, spinbuttons_number - 1);
00580     g_signal_connect_swapped(spin->data, "activate",
00581                 G_CALLBACK (gtk_widget_grab_focus), widgets->hidden_button);
00582 
00583     // Install 'key-press-event' handler.
00584     for ( i = 0 ; i < spinbuttons_number; i++ )
00585     {
00586         spin = g_list_nth(list, i);
00587         if (spin->data != widgets->dst_button)
00588         {
00589             g_signal_connect(spin->data, "key-press-event", 
00590                 G_CALLBACK(on_key_pressed), (gpointer) &widgets->is_portrait); 
00591         }
00592     }
00593 
00594     g_list_free(list);
00595 }
00596 
00597 static gboolean on_key_pressed(GtkWidget * widget, 
00598                                GdkEventKey * event, 
00599                                gpointer user_data)
00600 {
00601     LOGPRINTF("entry");
00602 
00603     g_assert ( NULL != user_data);
00604 
00605     int keyval = event->keyval ; 
00606     gboolean in_portrait_mode = *(gboolean*) user_data;
00607 
00608     if ( in_portrait_mode == TRUE)
00609     {
00610         switch (keyval)
00611         {
00612 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00613             case GDK_Up:
00614                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00615                         GTK_SPIN_STEP_FORWARD, 1.0 );
00616                 break;
00617             case GDK_Down:
00618 
00619                 gtk_spin_button_spin((GtkSpinButton*) widget,
00620                         GTK_SPIN_STEP_BACKWARD, 1.0 );
00621                 break;
00622             case GDK_Page_Up:
00623                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00624                         GTK_SPIN_STEP_FORWARD, 5.0 );
00625                 break;
00626             case GDK_Page_Down:
00627                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00628                         GTK_SPIN_STEP_BACKWARD, 5.0 );
00629                 break;
00630 #elif MACHINE_IS_DR800S || MACHINE_IS_DR800SG || MACHINE_IS_DR800SW
00631             // NOTE the logic here is paradoxal:
00632             //      Up key is mapped to left flip; left flip is "back/previous/down"
00633             //      Down key is mapped right flip; right flip is "advance/next/up"
00634             case GDK_Up:
00635                 gtk_spin_button_spin((GtkSpinButton*) widget,
00636                         GTK_SPIN_STEP_BACKWARD, 1.0 );
00637                 break;
00638             case GDK_Down:
00639                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00640                         GTK_SPIN_STEP_FORWARD, 1.0 );
00641                 break;
00642             case GDK_Page_Up:
00643                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00644                         GTK_SPIN_STEP_BACKWARD, 5.0 );
00645                 break;
00646             case GDK_Page_Down:
00647                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00648                         GTK_SPIN_STEP_FORWARD, 5.0 );
00649 #else
00650 #error Unhandled machine type
00651 #endif
00652             default:
00653                 return FALSE;
00654         }
00655     }
00656     else  // landscape mode  -> normal operation
00657     {
00658         switch (keyval)
00659         {
00660             case GDK_Up:
00661                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00662                         GTK_SPIN_STEP_FORWARD, 1.0 );
00663                 break;
00664             case GDK_Down:
00665                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00666                         GTK_SPIN_STEP_BACKWARD, 1.0 );
00667                 break;
00668             case GDK_Page_Up:
00669                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00670                         GTK_SPIN_STEP_FORWARD, 5.0 );
00671                 break;
00672             case GDK_Page_Down:
00673                 gtk_spin_button_spin((GtkSpinButton*) widget, 
00674                         GTK_SPIN_STEP_BACKWARD, 5.0 );
00675                 break;
00676             default:
00677                 return FALSE;
00678         }
00679     }
00680     return TRUE;
00681 }
00682 
00683 static gint on_timezone_input(GtkSpinButton* spin, gdouble* new_val)
00684 {
00685     LOGPRINTF("entry");
00686     const gchar*   text = gtk_entry_get_text(GTK_ENTRY(spin));
00687     gboolean found = FALSE;
00688 
00689     gint i;
00690     for (i = 0; i < TOTAL_TIMEZONES; i++)
00691     {
00692         if (g_strcasecmp(text, timezones[i].description) == 0)
00693         {
00694             found = TRUE;
00695             break;
00696         }
00697     }
00698 
00699     if (!found)
00700     {
00701         *new_val = 0.0;
00702         return GTK_INPUT_ERROR;
00703     }
00704     
00705     *new_val = (gdouble) i + 1;
00706     return TRUE;
00707 }
00708 
00709 static gint on_timezone_output(GtkSpinButton* spin)
00710 {
00711     LOGPRINTF("entry");
00712     GtkAdjustment* adj = gtk_spin_button_get_adjustment (spin);
00713     int value = (int)gtk_adjustment_get_value (adj);
00714     gtk_entry_set_text(GTK_ENTRY(spin), timezones[value].description);
00715     
00716     return TRUE;
00717 }
00718 
00719 static gint on_minutes_output (GtkSpinButton *spin)
00720 {
00721     GtkAdjustment *adj = gtk_spin_button_get_adjustment (spin);
00722     int value = (int)gtk_adjustment_get_value (adj);
00723 
00724     gchar* text = g_strdup_printf ("%02d", value);
00725     gtk_entry_set_text(GTK_ENTRY(spin), text);
00726     g_free(text);
00727 
00728     return TRUE;
00729 }
00730 
00731 static gint on_am_pm_input(GtkSpinButton* spin, gdouble* new_val)
00732 {
00733    const gchar* text = gtk_entry_get_text(GTK_ENTRY(spin));
00734    if (g_strncasecmp(text, _("AM"), strlen(_("AM"))) == 0)
00735    {
00736        *new_val = 0.0;
00737    }
00738    else if (g_strncasecmp(text, _("PM"), strlen(_("PM"))) == 0)
00739    {
00740        *new_val = 1.0;
00741    }
00742    else
00743    {
00744        return GTK_INPUT_ERROR;
00745    }
00746    return TRUE;
00747 }
00748 
00749 static gint on_am_pm_output(GtkSpinButton* spin)
00750 {
00751     GtkAdjustment* adj = gtk_spin_button_get_adjustment (spin);
00752     int value = (int)gtk_adjustment_get_value (adj);
00753     if (value == 0)
00754     {
00755         gtk_entry_set_text(GTK_ENTRY(spin), _("AM"));
00756     }
00757     else
00758     {
00759         gtk_entry_set_text(GTK_ENTRY(spin), _("PM"));
00760     }
00761     return TRUE;
00762 }
00763 
00764 
00765 static gint on_month_input(GtkSpinButton* spin, gdouble* new_val)
00766 {
00767     gint     i;
00768     char     buf[BUF_LEN];
00769     struct   tm t;
00770     const gchar*   text = gtk_entry_get_text(GTK_ENTRY(spin));
00771     gboolean found = FALSE;
00772 
00773     for (i = 0; i < 12; i++)
00774     {
00775         t.tm_mon = i;
00776         strftime(buf, BUF_LEN, "%b", &t);
00777         if (g_strncasecmp(text, buf, strlen(buf)) == 0)
00778         {
00779             found = TRUE;
00780             break;
00781         }
00782     }
00783 
00784     if (!found)
00785     {
00786         *new_val = 0.0;
00787         return GTK_INPUT_ERROR;
00788     }
00789 
00790     *new_val = (gdouble) i + 1;
00791 
00792     return TRUE;
00793 }
00794 
00795 static gint on_month_output(GtkSpinButton* spin, DateTimeWidgets* widgets)
00796 {
00797     char buf[BUF_LEN];
00798     struct tm t;
00799 
00800     GtkAdjustment* adj = gtk_spin_button_get_adjustment (spin);
00801     int value = (int)gtk_adjustment_get_value (adj);
00802  
00803     memset(&t, 0, sizeof(struct tm));
00804     t.tm_mon = value - 1;
00805     strftime(buf, BUF_LEN, "%b", &t);
00806     
00807     if (g_strncasecmp(gtk_entry_get_text(GTK_ENTRY(spin)), buf, strlen(buf)))
00808     {
00809         gtk_entry_set_text(GTK_ENTRY(spin), buf);
00810         gtk_entry_set_width_chars(GTK_ENTRY(spin), strlen(buf));
00811     } 
00812 
00813     // limit max day according to get_days_of_month
00814     (void) on_date_change(spin, widgets);
00815     
00816     return TRUE;
00817 }
00818 
00819 static gint on_date_change(GtkSpinButton* spin, DateTimeWidgets* widgets)
00820 {
00821     LOGPRINTF("entry");
00822 
00823     // limit max day according to get_days_of_month
00824     int year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->year_button));
00825     int month = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->month_button));
00826     int ndays = get_days_of_month(year, month);
00827     gtk_spin_button_set_range( GTK_SPIN_BUTTON(widgets->day_button), 1, (gdouble) ndays );
00828     
00829     return TRUE;
00830 }
00831 
00832 static time_t get_time_from_dialog(DateTimeWidgets * widgets)
00833 {
00834     LOGPRINTF("entry");
00835 
00836     int year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->year_button)) - 1900;
00837     int month = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->month_button)) - 1;
00838     int day = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->day_button));
00839     int hour = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->hour_button));
00840     if (widgets->twelve_clock)
00841     {
00842         if (hour == 12)
00843         {
00844             hour = 0;
00845         }
00846         int value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->am_pm_button));
00847         gboolean is_am = (value == 0);
00848         if (!is_am)
00849         {
00850             hour += 12;
00851         }
00852     }
00853     int minute = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->minute_button));
00854 
00855     struct tm tm_sel;
00856     memset(&tm_sel, 0, sizeof(struct tm));
00857     tm_sel.tm_year = year;
00858     tm_sel.tm_mon  = month;
00859     tm_sel.tm_mday = day;
00860     tm_sel.tm_hour = hour;
00861     tm_sel.tm_min  = minute;
00862 
00863     time_t time = mktime(&tm_sel);
00864     
00865     return time;
00866 }
00867 
00868 static int get_days_of_month(int year, int month)
00869 {
00870     LOGPRINTF("entry");
00871     int day = 0;
00872 
00873     switch (month)
00874     {
00875         case 1:
00876         case 3:
00877         case 5:
00878         case 7:
00879         case 8:
00880         case 10:
00881         case 12:
00882             day = 31; 
00883             break;
00884         case 4:
00885         case 6:
00886         case 9:
00887         case 11:
00888             day = 30;
00889             break;
00890         case 2:
00891             if ((year % 400 == 0) || ((year % 100 != 0) && (year % 4 ==0)))
00892             {
00893                 day = 29;
00894             }
00895             else
00896             {
00897                 day = 28;
00898             }
00899             break;
00900         default:
00901             break;
00902     }
00903 
00904     return day;
00905 }
00906 
Generated by  doxygen 1.6.2-20100208