|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * datecell-gnome.c -- implement date cell handler in gnome * 00003 * * 00004 * This program is free software; you can redistribute it and/or * 00005 * modify it under the terms of the GNU General Public License as * 00006 * published by the Free Software Foundation; either version 2 of * 00007 * the License, or (at your option) any later version. * 00008 * * 00009 * This program is distributed in the hope that it will be useful, * 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00012 * GNU General Public License for more details. * 00013 * * 00014 * You should have received a copy of the GNU General Public License* 00015 * along with this program; if not, contact: * 00016 * * 00017 * Free Software Foundation Voice: +1-617-542-5942 * 00018 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00019 * Boston, MA 02110-1301, USA gnu@gnu.org * 00020 * * 00021 \********************************************************************/ 00022 00023 /* 00024 * FILE: datecell-gnome.c 00025 * 00026 * FUNCTION: Implement gnome portion of datecell widget 00027 * embedded in a table cell. 00028 * 00029 * HISTORY: 00030 * Copyright (c) 2000 Dave Peticolas <dave@krondo.com> 00031 */ 00032 00033 #include "config.h" 00034 00035 #include <gnome.h> 00036 #include <stdio.h> 00037 #include <stdlib.h> 00038 #include <string.h> 00039 #include <time.h> 00040 00041 #include "datecell.h" 00042 #include "dialog-utils.h" 00043 #include "gnc-ui-util.h" 00044 #include "gnucash-date-picker.h" 00045 #include "gnucash-item-edit.h" 00046 #include "gnucash-sheet.h" 00047 00048 00049 #define DATE_BUF (MAX_DATE_LENGTH+1) 00050 00051 typedef struct _PopBox 00052 { 00053 GnucashSheet *sheet; 00054 GncItemEdit *item_edit; 00055 GNCDatePicker *date_picker; 00056 00057 gboolean signals_connected; /* date picker signals connected? */ 00058 gboolean calendar_popped; /* calendar is popped up? */ 00059 gboolean in_date_select; 00060 00061 struct tm date; 00062 } PopBox; 00063 00064 00065 static void block_picker_signals (DateCell *cell); 00066 static void unblock_picker_signals (DateCell *cell); 00067 static void gnc_date_cell_realize (BasicCell *bcell, gpointer w); 00068 static void gnc_date_cell_set_value_internal (BasicCell *bcell, 00069 const char *value); 00070 static void gnc_date_cell_move (BasicCell *bcell); 00071 static void gnc_date_cell_gui_destroy (BasicCell *bcell); 00072 static void gnc_date_cell_destroy (BasicCell *bcell); 00073 static void gnc_date_cell_modify_verify (BasicCell *_cell, 00074 const char *change, 00075 int change_len, 00076 const char *newval, 00077 int newval_len, 00078 int *cursor_position, 00079 int *start_selection, 00080 int *end_selection); 00081 static gboolean gnc_date_cell_direct_update (BasicCell *bcell, 00082 int *cursor_position, 00083 int *start_selection, 00084 int *end_selection, 00085 void *gui_data); 00086 static gboolean gnc_date_cell_enter (BasicCell *bcell, 00087 int *cursor_position, 00088 int *start_selection, 00089 int *end_selection); 00090 static void gnc_date_cell_leave (BasicCell *bcell); 00091 00092 00093 static void 00094 gnc_parse_date (struct tm *parsed, const char * datestr) 00095 { 00096 int day, month, year; 00097 gboolean use_autoreadonly = qof_book_uses_autoreadonly(gnc_get_current_book()); 00098 00099 if (!parsed) return; 00100 if (!datestr) return; 00101 00102 qof_scan_date (datestr, &day, &month, &year); 00103 00104 // If we have an auto-read-only threshold, do not accept a date that is 00105 // older than the threshold. 00106 if (use_autoreadonly) 00107 { 00108 GDate *d = g_date_new_dmy(day, month, year); 00109 GDate *readonly_threshold = qof_book_get_autoreadonly_gdate(gnc_get_current_book()); 00110 if (g_date_compare(d, readonly_threshold) < 0) 00111 { 00112 g_warning("Entered date %s is before the \"auto-read-only threshold\"; resetting to the threshold.", datestr); 00113 #if 0 00114 GtkWidget *dialog = gtk_message_dialog_new(NULL, 00115 0, 00116 GTK_MESSAGE_ERROR, 00117 GTK_BUTTONS_OK, 00118 "%s", _("Cannot store a transaction at this date")); 00119 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), 00120 "%s", _("The entered date of the new transaction is older than the \"Read-Only Threshold\" set for this book. " 00121 "This setting can be changed in File -> Properties -> Accounts.")); 00122 gtk_dialog_run(GTK_DIALOG(dialog)); 00123 gtk_widget_destroy(dialog); 00124 #endif 00125 00126 // Reset the date to the threshold date 00127 day = g_date_get_day(readonly_threshold); 00128 month = g_date_get_month(readonly_threshold); 00129 year = g_date_get_year(readonly_threshold); 00130 } 00131 g_date_free(d); 00132 g_date_free(readonly_threshold); 00133 } 00134 00135 parsed->tm_mday = day; 00136 parsed->tm_mon = month - 1; 00137 parsed->tm_year = year - 1900; 00138 00139 gnc_tm_set_day_start(parsed); 00140 if (mktime (parsed) == -1) 00141 gnc_tm_get_today_start (parsed); 00142 mktime (parsed); 00143 } 00144 00145 static void 00146 gnc_date_cell_print_date (DateCell *cell, char *buff) 00147 { 00148 PopBox *box = cell->cell.gui_private; 00149 00150 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH, 00151 box->date.tm_mday, 00152 box->date.tm_mon + 1, 00153 box->date.tm_year + 1900); 00154 } 00155 00156 static void 00157 gnc_date_cell_init (DateCell *cell) 00158 { 00159 PopBox *box; 00160 time_t secs; 00161 char buff[DATE_BUF]; 00162 00163 gnc_basic_cell_init (&(cell->cell)); 00164 00165 cell->cell.is_popup = TRUE; 00166 00167 cell->cell.destroy = gnc_date_cell_destroy; 00168 00169 cell->cell.gui_realize = gnc_date_cell_realize; 00170 cell->cell.gui_destroy = gnc_date_cell_gui_destroy; 00171 cell->cell.modify_verify = gnc_date_cell_modify_verify; 00172 cell->cell.direct_update = gnc_date_cell_direct_update; 00173 cell->cell.set_value = gnc_date_cell_set_value_internal; 00174 00175 box = g_new0 (PopBox, 1); 00176 00177 box->sheet = NULL; 00178 box->item_edit = NULL; 00179 box->date_picker = NULL; 00180 00181 box->signals_connected = FALSE; 00182 box->calendar_popped = FALSE; 00183 box->in_date_select = FALSE; 00184 00185 cell->cell.gui_private = box; 00186 00187 /* default value is today's date */ 00188 time (&secs); 00189 box->date = *localtime (&secs); 00190 gnc_date_cell_print_date (cell, buff); 00191 00192 gnc_basic_cell_set_value_internal (&cell->cell, buff); 00193 } 00194 00195 BasicCell * 00196 gnc_date_cell_new (void) 00197 { 00198 DateCell *cell; 00199 00200 cell = g_new0 (DateCell, 1); 00201 00202 gnc_date_cell_init (cell); 00203 00204 return &cell->cell; 00205 } 00206 00207 static void 00208 date_picked_cb (GNCDatePicker *gdp, gpointer data) 00209 { 00210 DateCell *cell = data; 00211 PopBox *box = cell->cell.gui_private; 00212 guint day, month, year; 00213 char buffer[DATE_BUF]; 00214 00215 gtk_calendar_get_date (gdp->calendar, &year, &month, &day); 00216 00217 qof_print_date_dmy_buff (buffer, MAX_DATE_LENGTH, day, month + 1, year); 00218 00219 box->in_date_select = TRUE; 00220 gnucash_sheet_modify_current_cell (box->sheet, buffer); 00221 box->in_date_select = FALSE; 00222 00223 gnc_item_edit_hide_popup (box->item_edit); 00224 box->calendar_popped = FALSE; 00225 } 00226 00227 static void 00228 date_selected_cb (GNCDatePicker *gdp, gpointer data) 00229 { 00230 DateCell *cell = data; 00231 PopBox *box = cell->cell.gui_private; 00232 guint day, month, year; 00233 char buffer[DATE_BUF]; 00234 00235 gtk_calendar_get_date (gdp->calendar, &year, &month, &day); 00236 00237 qof_print_date_dmy_buff (buffer, MAX_DATE_LENGTH, day, month + 1, year); 00238 00239 box->in_date_select = TRUE; 00240 gnucash_sheet_modify_current_cell (box->sheet, buffer); 00241 box->in_date_select = FALSE; 00242 } 00243 00244 static void 00245 key_press_item_cb (GNCDatePicker *gdp, GdkEventKey *event, gpointer data) 00246 { 00247 DateCell *cell = data; 00248 PopBox *box = cell->cell.gui_private; 00249 00250 switch (event->keyval) 00251 { 00252 case GDK_Escape: 00253 gnc_item_edit_hide_popup (box->item_edit); 00254 box->calendar_popped = FALSE; 00255 break; 00256 00257 default: 00258 gtk_widget_event(GTK_WIDGET (box->sheet), (GdkEvent *) event); 00259 break; 00260 } 00261 } 00262 00263 static void 00264 date_picker_disconnect_signals (DateCell *cell) 00265 { 00266 PopBox *box = cell->cell.gui_private; 00267 00268 if (!box->signals_connected) 00269 return; 00270 00271 g_signal_handlers_disconnect_matched (box->date_picker, G_SIGNAL_MATCH_DATA, 00272 0, 0, NULL, NULL, cell); 00273 00274 box->signals_connected = FALSE; 00275 } 00276 00277 static void 00278 date_picker_connect_signals (DateCell *cell) 00279 { 00280 PopBox *box = cell->cell.gui_private; 00281 00282 if (box->signals_connected) 00283 return; 00284 00285 g_signal_connect (box->date_picker, "date_selected", 00286 G_CALLBACK(date_selected_cb), cell); 00287 00288 g_signal_connect(box->date_picker, "date_picked", 00289 G_CALLBACK(date_picked_cb), cell); 00290 00291 g_signal_connect(box->date_picker, "key_press_event", 00292 G_CALLBACK(key_press_item_cb), cell); 00293 00294 box->signals_connected = TRUE; 00295 } 00296 00297 static void 00298 block_picker_signals (DateCell *cell) 00299 { 00300 PopBox *box = cell->cell.gui_private; 00301 00302 if (!box->signals_connected) 00303 return; 00304 00305 g_signal_handlers_block_matched (box->date_picker, G_SIGNAL_MATCH_DATA, 00306 0, 0, NULL, NULL, cell); 00307 } 00308 00309 static void 00310 unblock_picker_signals (DateCell *cell) 00311 { 00312 PopBox *box = cell->cell.gui_private; 00313 00314 if (!box->signals_connected) 00315 return; 00316 00317 g_signal_handlers_unblock_matched (box->date_picker, G_SIGNAL_MATCH_DATA, 00318 0, 0, NULL, NULL, cell); 00319 } 00320 00321 static void 00322 gnc_date_cell_gui_destroy (BasicCell *bcell) 00323 { 00324 PopBox *box = bcell->gui_private; 00325 DateCell *cell = (DateCell *) bcell; 00326 00327 if (cell->cell.gui_realize == NULL) 00328 { 00329 if (box != NULL && box->date_picker != NULL) 00330 { 00331 date_picker_disconnect_signals (cell); 00332 g_object_unref (box->date_picker); 00333 box->date_picker = NULL; 00334 } 00335 00336 /* allow the widget to be shown again */ 00337 cell->cell.gui_realize = gnc_date_cell_realize; 00338 cell->cell.gui_move = NULL; 00339 cell->cell.enter_cell = NULL; 00340 cell->cell.leave_cell = NULL; 00341 cell->cell.gui_destroy = NULL; 00342 } 00343 } 00344 00345 static void 00346 gnc_date_cell_destroy (BasicCell *bcell) 00347 { 00348 DateCell *cell = (DateCell *) bcell; 00349 PopBox *box = cell->cell.gui_private; 00350 00351 gnc_date_cell_gui_destroy (&(cell->cell)); 00352 00353 g_free (box); 00354 00355 cell->cell.gui_private = NULL; 00356 cell->cell.gui_realize = NULL; 00357 } 00358 00359 void 00360 gnc_date_cell_set_value (DateCell *cell, int day, int mon, int year) 00361 { 00362 PopBox *box = cell->cell.gui_private; 00363 struct tm dada; 00364 char buff[DATE_BUF]; 00365 00366 dada.tm_mday = day; 00367 dada.tm_mon = mon - 1; 00368 dada.tm_year = year - 1900; 00369 00370 gnc_tm_set_day_start(&dada); 00371 mktime (&dada); 00372 00373 box->date.tm_mday = dada.tm_mday; 00374 box->date.tm_mon = dada.tm_mon; 00375 box->date.tm_year = dada.tm_year; 00376 00377 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH, dada.tm_mday, dada.tm_mon + 1, dada.tm_year + 1900); 00378 00379 gnc_basic_cell_set_value_internal (&cell->cell, buff); 00380 00381 if (!box->date_picker) 00382 return; 00383 00384 block_picker_signals (cell); 00385 gnc_date_picker_set_date (box->date_picker, day, mon - 1, year); 00386 unblock_picker_signals (cell); 00387 } 00388 00389 void 00390 gnc_date_cell_set_value_secs (DateCell *cell, time_t secs) 00391 { 00392 PopBox *box = cell->cell.gui_private; 00393 char buff[DATE_BUF]; 00394 struct tm * stm; 00395 00396 stm = localtime (&secs); 00397 box->date = *stm; 00398 00399 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH, 00400 box->date.tm_mday, 00401 box->date.tm_mon + 1, 00402 box->date.tm_year + 1900); 00403 00404 gnc_basic_cell_set_value_internal (&cell->cell, buff); 00405 00406 if (!box->date_picker) 00407 return; 00408 00409 block_picker_signals (cell); 00410 gnc_date_picker_set_date (box->date_picker, 00411 box->date.tm_mday, 00412 box->date.tm_mon, 00413 box->date.tm_year + 1900); 00414 unblock_picker_signals (cell); 00415 } 00416 00417 void 00418 gnc_date_cell_commit (DateCell *cell) 00419 { 00420 PopBox *box = cell->cell.gui_private; 00421 char buff[DATE_BUF]; 00422 00423 if (!cell) 00424 return; 00425 00426 gnc_parse_date (&(box->date), cell->cell.value); 00427 00428 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH, 00429 box->date.tm_mday, 00430 box->date.tm_mon + 1, 00431 box->date.tm_year + 1900); 00432 00433 gnc_basic_cell_set_value_internal (&cell->cell, buff); 00434 00435 if (!box->date_picker) 00436 return; 00437 00438 block_picker_signals (cell); 00439 gnc_date_picker_set_date (box->date_picker, 00440 box->date.tm_mday, 00441 box->date.tm_mon, 00442 box->date.tm_year + 1900); 00443 unblock_picker_signals (cell); 00444 } 00445 00446 static gboolean 00447 gnc_date_cell_direct_update (BasicCell *bcell, 00448 int *cursor_position, 00449 int *start_selection, 00450 int *end_selection, 00451 void *gui_data) 00452 { 00453 DateCell *cell = (DateCell *) bcell; 00454 PopBox *box = cell->cell.gui_private; 00455 GdkEventKey *event = gui_data; 00456 char buff[DATE_BUF]; 00457 00458 if (!gnc_handle_date_accelerator (event, &(box->date), bcell->value)) 00459 return FALSE; 00460 00461 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH, 00462 box->date.tm_mday, 00463 box->date.tm_mon + 1, 00464 box->date.tm_year + 1900); 00465 00466 gnc_basic_cell_set_value_internal (&cell->cell, buff); 00467 00468 *start_selection = 0; 00469 *end_selection = -1; 00470 00471 if (!box->date_picker) 00472 return TRUE; 00473 00474 block_picker_signals (cell); 00475 gnc_date_picker_set_date (box->date_picker, 00476 box->date.tm_mday, 00477 box->date.tm_mon, 00478 box->date.tm_year + 1900); 00479 unblock_picker_signals (cell); 00480 00481 return TRUE; 00482 } 00483 00484 static void 00485 gnc_date_cell_modify_verify (BasicCell *_cell, 00486 const char *change, 00487 int change_len, 00488 const char *newval, 00489 int newval_len, 00490 int *cursor_position, 00491 int *start_selection, 00492 int *end_selection) 00493 { 00494 DateCell *cell = (DateCell *) _cell; 00495 PopBox *box = cell->cell.gui_private; 00496 gboolean accept = FALSE; 00497 00498 if (box->in_date_select) 00499 { 00500 gnc_basic_cell_set_value (_cell, newval); 00501 return; 00502 } 00503 00504 /* if user hit backspace, accept the change */ 00505 if (change == NULL) 00506 accept = TRUE; 00507 else if (change_len == 0) 00508 accept = TRUE; 00509 else 00510 { 00511 int count = 0; 00512 unsigned char separator = dateSeparator (); 00513 gboolean ok = TRUE; 00514 const gchar *c; 00515 gunichar uc; 00516 00517 /* accept only numbers or a date separator. Note that the 00518 * separator of '-' (for DATE_FORMAT_ISO) takes precedence 00519 * over the accelerator below! */ 00520 c = change; 00521 while (*c) 00522 { 00523 uc = g_utf8_get_char (c); 00524 00525 if (!g_unichar_isdigit (uc) && (separator != uc)) 00526 ok = FALSE; 00527 00528 if (separator == uc) 00529 count++; 00530 00531 c = g_utf8_next_char (c); 00532 } 00533 00534 c = _cell->value; 00535 while (*c) 00536 { 00537 uc = g_utf8_get_char (c); 00538 00539 if (separator == uc) 00540 count++; 00541 00542 c = g_utf8_next_char (c); 00543 } 00544 00545 if (2 < count) 00546 ok = FALSE; 00547 00548 if (ok) 00549 accept = TRUE; 00550 } 00551 00552 /* keep a copy of the new value */ 00553 if (accept) 00554 { 00555 00556 gnc_basic_cell_set_value_internal (&cell->cell, newval); 00557 gnc_parse_date (&(box->date), newval); 00558 00559 if (!box->date_picker) 00560 return; 00561 00562 block_picker_signals (cell); 00563 gnc_date_picker_set_date (box->date_picker, 00564 box->date.tm_mday, 00565 box->date.tm_mon, 00566 box->date.tm_year + 1900); 00567 unblock_picker_signals (cell); 00568 } 00569 } 00570 00571 static void 00572 gnc_date_cell_realize (BasicCell *bcell, gpointer data) 00573 { 00574 GnucashSheet *sheet = data; 00575 GnomeCanvasItem *item = sheet->item_editor; 00576 GncItemEdit *item_edit = GNC_ITEM_EDIT (item); 00577 DateCell *cell = (DateCell *) bcell; 00578 PopBox *box = cell->cell.gui_private; 00579 00580 /* initialize gui-specific, private data */ 00581 box->sheet = sheet; 00582 box->item_edit = item_edit; 00583 box->date_picker = gnc_item_edit_new_date_picker (box->item_edit); 00584 g_object_ref_sink(box->date_picker); 00585 00586 /* to mark cell as realized, remove the realize method */ 00587 cell->cell.gui_realize = NULL; 00588 cell->cell.gui_move = gnc_date_cell_move; 00589 cell->cell.enter_cell = gnc_date_cell_enter; 00590 cell->cell.leave_cell = gnc_date_cell_leave; 00591 } 00592 00593 static void 00594 gnc_date_cell_move (BasicCell *bcell) 00595 { 00596 PopBox *box = bcell->gui_private; 00597 00598 date_picker_disconnect_signals ((DateCell *) bcell); 00599 00600 gnc_item_edit_set_popup (box->item_edit, NULL, NULL, 00601 NULL, NULL, NULL, NULL, NULL); 00602 00603 box->calendar_popped = FALSE; 00604 } 00605 00606 static int 00607 get_popup_height (GnomeCanvasItem *item, 00608 int space_available, 00609 int row_height, 00610 gpointer user_data) 00611 { 00612 GtkWidget *cal = GTK_WIDGET (GNC_DATE_PICKER (item)->calendar); 00613 GtkRequisition req; 00614 00615 req.height = 0; 00616 req.width = 0; 00617 00618 gtk_widget_size_request (cal, &req); 00619 00620 return req.height; 00621 } 00622 00623 static void 00624 popup_set_focus (GnomeCanvasItem *item, 00625 gpointer user_data) 00626 { 00627 gtk_widget_grab_focus (GTK_WIDGET (GNC_DATE_PICKER (item)->calendar)); 00628 } 00629 00630 static gboolean 00631 gnc_date_cell_enter (BasicCell *bcell, 00632 int *cursor_position, 00633 int *start_selection, 00634 int *end_selection) 00635 { 00636 DateCell *cell = (DateCell *) bcell; 00637 PopBox *box = bcell->gui_private; 00638 00639 gnc_item_edit_set_popup (box->item_edit, GNOME_CANVAS_ITEM (box->date_picker), 00640 get_popup_height, NULL, popup_set_focus, 00641 NULL, NULL, NULL); 00642 00643 block_picker_signals (cell); 00644 gnc_date_picker_set_date (box->date_picker, 00645 box->date.tm_mday, 00646 box->date.tm_mon, 00647 box->date.tm_year + 1900); 00648 unblock_picker_signals (cell); 00649 00650 date_picker_connect_signals ((DateCell *) bcell); 00651 00652 *start_selection = 0; 00653 *end_selection = -1; 00654 00655 return TRUE; 00656 } 00657 00658 static void 00659 gnc_date_cell_leave (BasicCell *bcell) 00660 { 00661 Timespec ts; 00662 PopBox *box = bcell->gui_private; 00663 00664 date_picker_disconnect_signals ((DateCell *) bcell); 00665 00666 gnc_item_edit_set_popup (box->item_edit, NULL, NULL, 00667 NULL, NULL, NULL, NULL, NULL); 00668 00669 box->calendar_popped = FALSE; 00670 00671 /* Refresh the date to expand any shortcuts. */ 00672 gnc_date_cell_get_date ((DateCell *)bcell, &ts); 00673 gnc_date_cell_set_value_secs ((DateCell *)bcell, ts.tv_sec); 00674 } 00675 00676 void 00677 gnc_date_cell_get_date_gdate (DateCell *cell, GDate *date) 00678 { 00679 PopBox *box = cell->cell.gui_private; 00680 00681 if (!cell || !date) 00682 return; 00683 00684 gnc_parse_date (&(box->date), cell->cell.value); 00685 00686 g_date_set_dmy(date, 00687 box->date.tm_mday, 00688 box->date.tm_mon + 1, 00689 box->date.tm_year + 1900); 00690 } 00691 00692 void 00693 gnc_date_cell_get_date (DateCell *cell, Timespec *ts) 00694 { 00695 PopBox *box = cell->cell.gui_private; 00696 00697 if (!cell || !ts) 00698 return; 00699 00700 gnc_parse_date (&(box->date), cell->cell.value); 00701 00702 ts->tv_sec = mktime (&box->date); 00703 ts->tv_nsec = 0; 00704 } 00705 00706 static void 00707 gnc_date_cell_set_value_internal (BasicCell *_cell, const char *str) 00708 { 00709 DateCell *cell = (DateCell *) _cell; 00710 PopBox *box = cell->cell.gui_private; 00711 char buff[DATE_BUF]; 00712 00713 gnc_parse_date (&(box->date), str); 00714 00715 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH, 00716 box->date.tm_mday, 00717 box->date.tm_mon + 1, 00718 box->date.tm_year + 1900); 00719 00720 gnc_basic_cell_set_value_internal (_cell, buff); 00721 00722 if (!box->date_picker) 00723 return; 00724 00725 block_picker_signals (cell); 00726 gnc_date_picker_set_date (box->date_picker, 00727 box->date.tm_mday, 00728 box->date.tm_mon, 00729 box->date.tm_year + 1900); 00730 unblock_picker_signals (cell); 00731 }
1.7.4