GnuCash c935c2f+
Loading...
Searching...
No Matches
datecell-gnome.c
1/********************************************************************\
2 * datecell-gnome.c -- implement date cell handler in gnome *
3 * *
4 * This program is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU General Public License as *
6 * published by the Free Software Foundation; either version 2 of *
7 * the License, or (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License*
15 * along with this program; if not, contact: *
16 * *
17 * Free Software Foundation Voice: +1-617-542-5942 *
18 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19 * Boston, MA 02110-1301, USA gnu@gnu.org *
20 * *
21\********************************************************************/
22
23/*
24 * FILE: datecell-gnome.c
25 *
26 * FUNCTION: Implement gnome portion of datecell widget
27 * embedded in a table cell.
28 *
29 * HISTORY:
30 * Copyright (c) 2000 Dave Peticolas <dave@krondo.com>
31 * Copyright (c) 2017 Aaron Laws
32 */
33
34#include <config.h>
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <time.h>
40#include <glib/gi18n.h>
41#include <gdk/gdkkeysyms.h>
42
43#include "datecell.h"
44#include "dialog-utils.h"
45#include "gnc-ui.h"
46#include "gnc-ui-util.h"
47#include "gnucash-date-picker.h"
48#include "gnucash-item-edit.h"
49#include "gnucash-sheet.h"
50#include "gnucash-sheetP.h"
51
52
53#define DATE_BUF (MAX_DATE_LENGTH+1)
54
55typedef struct _PopBox
56{
57 GnucashSheet *sheet;
58 GncItemEdit *item_edit;
59 GNCDatePicker *date_picker;
60
61 gboolean signals_connected; /* date picker signals connected? */
62 gboolean calendar_popped; /* calendar is popped up? */
63 gboolean in_date_select;
64
65 struct tm date;
66} PopBox;
67
68
69static void block_picker_signals (DateCell *cell);
70static void unblock_picker_signals (DateCell *cell);
71static void gnc_date_cell_realize (BasicCell *bcell, gpointer w);
72static void gnc_date_cell_set_value_internal (BasicCell *bcell,
73 const char *value);
74static void gnc_date_cell_move (BasicCell *bcell);
75static void gnc_date_cell_gui_destroy (BasicCell *bcell);
76static void gnc_date_cell_destroy (BasicCell *bcell);
77static void gnc_date_cell_modify_verify (BasicCell *_cell,
78 const char *change,
79 int change_len,
80 const char *newval,
81 int newval_len,
82 int *cursor_position,
83 int *start_selection,
84 int *end_selection);
85static gboolean gnc_date_cell_direct_update (BasicCell *bcell,
86 int *cursor_position,
87 int *start_selection,
88 int *end_selection,
89 void *gui_data);
90static gboolean gnc_date_cell_enter (BasicCell *bcell,
91 int *cursor_position,
92 int *start_selection,
93 int *end_selection);
94static void gnc_date_cell_leave (BasicCell *bcell);
95
96static gboolean
97check_readonly_threshold (const gchar *datestr, GDate *d, gboolean warn)
98{
99 GDate *readonly_threshold = qof_book_get_autoreadonly_gdate(gnc_get_current_book());
100 if (g_date_compare(d, readonly_threshold) < 0)
101 {
102 if (warn)
103 {
104 gchar *dialog_msg = _("The entered date of the transaction is "
105 "older than the \"Read-Only Threshold\" set for "
106 "this book. This setting can be changed in "
107 "File->Properties->Accounts, resetting to the threshold.");
108 gchar *dialog_title = _("Cannot store a transaction at this date");
109 GtkWidget *dialog = gtk_message_dialog_new(gnc_ui_get_main_window (NULL),
110 0,
111 GTK_MESSAGE_ERROR,
112 GTK_BUTTONS_OK,
113 "%s", dialog_title);
114 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
115 "%s", dialog_msg);
116 gtk_dialog_run (GTK_DIALOG(dialog));
117 gtk_widget_destroy (dialog);
118
119// g_warning("Entered date %s is before the \"auto-read-only threshold\";"
120// " resetting to the threshold.", datestr);
121 }
122 // Reset the date to the threshold date
123 g_date_set_julian (d, g_date_get_julian (readonly_threshold));
124 g_date_free (readonly_threshold);
125 return TRUE;
126 }
127 g_date_free (readonly_threshold);
128 return FALSE;
129}
130
131static void
132gnc_parse_date (struct tm *parsed, const char * datestr, gboolean warn)
133{
134 int day, month, year;
135 gboolean use_autoreadonly = qof_book_uses_autoreadonly(gnc_get_current_book());
136 GDate *test_date;
137
138 if (!parsed) return;
139 if (!datestr) return;
140
141 if (!qof_scan_date (datestr, &day, &month, &year))
142 {
143 // Couldn't parse date, use today
144 struct tm tm_today;
145
146 memset (&tm_today, 0, sizeof (struct tm));
147 gnc_tm_get_today_start (&tm_today);
148 day = tm_today.tm_mday;
149 month = tm_today.tm_mon + 1;
150 year = tm_today.tm_year + 1900;
151 }
152
153 test_date = g_date_new_dmy (day, month, year);
154
155 if (!gnc_gdate_in_valid_range (test_date, warn))
156 {
157 struct tm tm_today;
158 memset (&tm_today, 0, sizeof (struct tm));
159 gnc_tm_get_today_start (&tm_today);
160 year = tm_today.tm_year + 1900;
161 }
162
163 // If we have an auto-read-only threshold, do not accept a date that is
164 // older than the threshold.
165 if (use_autoreadonly)
166 {
167 g_date_set_dmy (test_date, day, month, year);
168 if (check_readonly_threshold (datestr, test_date, warn))
169 {
170 day = g_date_get_day (test_date);
171 month = g_date_get_month (test_date);
172 year = g_date_get_year (test_date);
173 }
174 }
175 g_date_free (test_date);
176
177 parsed->tm_mday = day;
178 parsed->tm_mon = month - 1;
179 parsed->tm_year = year - 1900;
180
181 gnc_tm_set_day_start(parsed);
182 /* Using gnc_mktime purely for its side effect of filling in the
183 * rest of parsed and to check that it's valid.
184 */
185 if (gnc_mktime (parsed) == -1)
186 gnc_tm_get_today_start (parsed);
187 gnc_mktime (parsed);
188}
189
190static void
191gnc_date_cell_print_date (DateCell *cell, char *buff)
192{
193 PopBox *box = cell->cell.gui_private;
194
195 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH,
196 box->date.tm_mday,
197 box->date.tm_mon + 1,
198 box->date.tm_year + 1900);
199}
200
201static void
202gnc_date_cell_init (DateCell *cell)
203{
204 PopBox *box;
205 time64 secs;
206 char buff[DATE_BUF];
207
208 gnc_basic_cell_init (&(cell->cell));
209
210 cell->cell.is_popup = TRUE;
211
212 cell->cell.destroy = gnc_date_cell_destroy;
213
214 cell->cell.gui_realize = gnc_date_cell_realize;
215 cell->cell.gui_destroy = gnc_date_cell_gui_destroy;
216 cell->cell.modify_verify = gnc_date_cell_modify_verify;
217 cell->cell.direct_update = gnc_date_cell_direct_update;
218 cell->cell.set_value = gnc_date_cell_set_value_internal;
219
220 box = g_new0 (PopBox, 1);
221
222 box->sheet = NULL;
223 box->item_edit = NULL;
224 box->date_picker = NULL;
225
226 box->signals_connected = FALSE;
227 box->calendar_popped = FALSE;
228 box->in_date_select = FALSE;
229
230 cell->cell.gui_private = box;
231
232 /* default value is today's date */
233 gnc_time (&secs);
234 gnc_localtime_r (&secs, &(box->date));
235 gnc_date_cell_print_date (cell, buff);
236
237 gnc_basic_cell_set_value_internal (&cell->cell, buff);
238}
239
240BasicCell *
242{
243 DateCell *cell;
244
245 cell = g_new0 (DateCell, 1);
246
247 gnc_date_cell_init (cell);
248
249 return &cell->cell;
250}
251
252static void
253date_picked_cb (GNCDatePicker *gdp, gpointer data)
254{
255 DateCell *cell = data;
256 PopBox *box = cell->cell.gui_private;
257 guint day, month, year;
258 char buffer[DATE_BUF];
259
260 gtk_calendar_get_date (gdp->calendar, &year, &month, &day);
261
262 qof_print_date_dmy_buff (buffer, MAX_DATE_LENGTH, day, month + 1, year);
263
264 box->in_date_select = TRUE;
265 gnucash_sheet_modify_current_cell (box->sheet, buffer);
266 box->in_date_select = FALSE;
267
268 gnc_item_edit_hide_popup (box->item_edit);
269 box->calendar_popped = FALSE;
270}
271
272static void
273date_selected_cb (GNCDatePicker *gdp, gpointer data)
274{
275 DateCell *cell = data;
276 PopBox *box = cell->cell.gui_private;
277 guint day, month, year;
278 char buffer[DATE_BUF];
279
280 gtk_calendar_get_date (gdp->calendar, &year, &month, &day);
281
282 qof_print_date_dmy_buff (buffer, MAX_DATE_LENGTH, day, month + 1, year);
283
284 box->in_date_select = TRUE;
285 gnucash_sheet_modify_current_cell (box->sheet, buffer);
286 box->in_date_select = FALSE;
287}
288
289static gboolean
290key_press_item_cb (GNCDatePicker *gdp, GdkEventKey *event, gpointer data)
291{
292 DateCell *cell = data;
293 PopBox *box = cell->cell.gui_private;
294
295 switch (event->keyval)
296 {
297 case GDK_KEY_Escape:
298 gnc_item_edit_hide_popup (box->item_edit);
299 box->calendar_popped = FALSE;
300 break;
301
302 default:
303 gtk_widget_event(GTK_WIDGET (box->sheet), (GdkEvent *) event);
304 break;
305 }
306 return TRUE;
307}
308
309static void
310date_picker_disconnect_signals (DateCell *cell)
311{
312 PopBox *box = cell->cell.gui_private;
313
314 if (!box->signals_connected)
315 return;
316
317 g_signal_handlers_disconnect_matched (box->date_picker, G_SIGNAL_MATCH_DATA,
318 0, 0, NULL, NULL, cell);
319
320 box->signals_connected = FALSE;
321}
322
323static void
324date_picker_connect_signals (DateCell *cell)
325{
326 PopBox *box = cell->cell.gui_private;
327
328 if (box->signals_connected)
329 return;
330
331 g_signal_connect (box->date_picker, "date_selected",
332 G_CALLBACK(date_selected_cb), cell);
333
334 g_signal_connect(box->date_picker, "date_picked",
335 G_CALLBACK(date_picked_cb), cell);
336
337 g_signal_connect(box->date_picker, "key_press_event",
338 G_CALLBACK(key_press_item_cb), cell);
339
340 box->signals_connected = TRUE;
341}
342
343static void
344block_picker_signals (DateCell *cell)
345{
346 PopBox *box = cell->cell.gui_private;
347
348 if (!box->signals_connected)
349 return;
350
351 g_signal_handlers_block_matched (box->date_picker, G_SIGNAL_MATCH_DATA,
352 0, 0, NULL, NULL, cell);
353}
354
355static void
356unblock_picker_signals (DateCell *cell)
357{
358 PopBox *box = cell->cell.gui_private;
359
360 if (!box->signals_connected)
361 return;
362
363 g_signal_handlers_unblock_matched (box->date_picker, G_SIGNAL_MATCH_DATA,
364 0, 0, NULL, NULL, cell);
365}
366
367static void
368gnc_date_cell_gui_destroy (BasicCell *bcell)
369{
370 PopBox *box = bcell->gui_private;
371 DateCell *cell = (DateCell *) bcell;
372
373 if (cell->cell.gui_realize == NULL)
374 {
375 if (box != NULL && box->date_picker != NULL)
376 {
377 date_picker_disconnect_signals (cell);
378 g_object_unref (box->date_picker);
379 box->date_picker = NULL;
380 }
381
382 /* allow the widget to be shown again */
383 cell->cell.gui_realize = gnc_date_cell_realize;
384 cell->cell.gui_move = NULL;
385 cell->cell.enter_cell = NULL;
386 cell->cell.leave_cell = NULL;
387 cell->cell.gui_destroy = NULL;
388 }
389}
390
391static void
392gnc_date_cell_destroy (BasicCell *bcell)
393{
394 DateCell *cell = (DateCell *) bcell;
395 PopBox *box = cell->cell.gui_private;
396
397 gnc_date_cell_gui_destroy (&(cell->cell));
398
399 g_free (box);
400
401 cell->cell.gui_private = NULL;
402 cell->cell.gui_realize = NULL;
403}
404
405void
406gnc_date_cell_set_value (DateCell *cell, int day, int mon, int year)
407{
408 PopBox *box = cell->cell.gui_private;
409 struct tm dada;
410 char buff[DATE_BUF];
411
412 dada.tm_mday = day;
413 dada.tm_mon = mon - 1;
414 dada.tm_year = year - 1900;
415
416 gnc_tm_set_day_start(&dada);
417 gnc_mktime (&dada);
418
419 box->date.tm_mday = dada.tm_mday;
420 box->date.tm_mon = dada.tm_mon;
421 box->date.tm_year = dada.tm_year;
422
423 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH, dada.tm_mday, dada.tm_mon + 1, dada.tm_year + 1900);
424
425 gnc_basic_cell_set_value_internal (&cell->cell, buff);
426
427 if (!box->date_picker)
428 return;
429
430 block_picker_signals (cell);
431 gnc_date_picker_set_date (box->date_picker, day, mon - 1, year);
432 unblock_picker_signals (cell);
433}
434
435void
437{
438 PopBox *box = cell->cell.gui_private;
439 char buff[DATE_BUF];
440
441 gnc_localtime_r (&secs, &(box->date));
442
443 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH,
444 box->date.tm_mday,
445 box->date.tm_mon + 1,
446 box->date.tm_year + 1900);
447
448 gnc_basic_cell_set_value_internal (&cell->cell, buff);
449
450 if (!box->date_picker)
451 return;
452
453 block_picker_signals (cell);
454 gnc_date_picker_set_date (box->date_picker,
455 box->date.tm_mday,
456 box->date.tm_mon,
457 box->date.tm_year + 1900);
458 unblock_picker_signals (cell);
459}
460
461void
463{
464 PopBox *box = cell->cell.gui_private;
465 char buff[DATE_BUF];
466
467 if (!cell)
468 return;
469
470 gnc_parse_date (&(box->date), cell->cell.value, FALSE);
471
472 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH,
473 box->date.tm_mday,
474 box->date.tm_mon + 1,
475 box->date.tm_year + 1900);
476
477 gnc_basic_cell_set_value_internal (&cell->cell, buff);
478
479 if (!box->date_picker)
480 return;
481
482 block_picker_signals (cell);
483 gnc_date_picker_set_date (box->date_picker,
484 box->date.tm_mday,
485 box->date.tm_mon,
486 box->date.tm_year + 1900);
487 unblock_picker_signals (cell);
488}
489
490static gboolean
491gnc_date_cell_direct_update (BasicCell *bcell,
492 int *cursor_position,
493 int *start_selection,
494 int *end_selection,
495 void *gui_data)
496{
497 DateCell *cell = (DateCell *) bcell;
498 PopBox *box = cell->cell.gui_private;
499 GdkEventKey *event = gui_data;
500 char buff[DATE_BUF];
501
502 if (event->keyval == GDK_KEY_Escape)
503 {
504 if (bcell->changed)
505 {
506 const char *value = gnc_table_get_model_entry (box->sheet->table, bcell->cell_name);
507
508 gnc_basic_cell_set_value_internal (bcell, value);
509 bcell->changed = FALSE;
510 *cursor_position = 0;
511 *start_selection = 0;
512 *end_selection = -1;
513 return TRUE;
514 }
515 return FALSE;
516 }
517
518 if (!gnc_handle_date_accelerator (event, &(box->date), bcell->value))
519 return FALSE;
520
521 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH,
522 box->date.tm_mday,
523 box->date.tm_mon + 1,
524 box->date.tm_year + 1900);
525
526 gnc_basic_cell_set_value_internal (&cell->cell, buff);
527
528 *start_selection = 0;
529 *end_selection = -1;
530
531 if (!box->date_picker)
532 return TRUE;
533
534 block_picker_signals (cell);
535 gnc_date_picker_set_date (box->date_picker,
536 box->date.tm_mday,
537 box->date.tm_mon,
538 box->date.tm_year + 1900);
539 unblock_picker_signals (cell);
540
541 return TRUE;
542}
543
544static void
545gnc_date_cell_modify_verify (BasicCell *_cell,
546 const char *change,
547 int change_len,
548 const char *newval,
549 int newval_len,
550 int *cursor_position,
551 int *start_selection,
552 int *end_selection)
553{
554 DateCell *cell = (DateCell *) _cell;
555 PopBox *box = cell->cell.gui_private;
556 gboolean accept = FALSE;
557
558 if (box->in_date_select)
559 {
560 gnc_basic_cell_set_value (_cell, newval);
561 return;
562 }
563
564 /* if user hit backspace, accept the change */
565 if (change == NULL)
566 accept = TRUE;
567 else if (change_len == 0)
568 accept = TRUE;
569 else
570 {
571 int count = 0;
572 unsigned char separator = dateSeparator ();
573 gboolean ok = TRUE;
574 const gchar *c;
575 gunichar uc;
576
577 /* accept only numbers or a date separator. Note that the
578 * separator of '-' (for DATE_FORMAT_ISO) takes precedence
579 * over the accelerator below! */
580 c = change;
581 while (*c)
582 {
583 uc = g_utf8_get_char (c);
584
585 if (!g_unichar_isdigit (uc) && (separator != uc))
586 ok = FALSE;
587
588 if (separator == uc)
589 count++;
590
591 c = g_utf8_next_char (c);
592 }
593
594 c = _cell->value;
595 while (*c)
596 {
597 uc = g_utf8_get_char (c);
598
599 if (separator == uc)
600 count++;
601
602 c = g_utf8_next_char (c);
603 }
604
605 if (2 < count)
606 ok = FALSE;
607
608 if (ok)
609 accept = TRUE;
610 }
611
612 /* keep a copy of the new value */
613 if (accept)
614 {
615 gnc_basic_cell_set_value_internal (&cell->cell, newval);
616 gnc_parse_date (&(box->date), newval, FALSE);
617 *end_selection = *start_selection = *cursor_position;
618
619 if (!box->date_picker)
620 return;
621
622 block_picker_signals (cell);
623 gnc_date_picker_set_date (box->date_picker,
624 box->date.tm_mday,
625 box->date.tm_mon,
626 box->date.tm_year + 1900);
627 unblock_picker_signals (cell);
628 }
629}
630
631static void
632gnc_date_cell_realize (BasicCell *bcell, gpointer data)
633{
634 GnucashSheet *sheet = data;
635 GncItemEdit *item_edit = gnucash_sheet_get_item_edit (sheet);
636 DateCell *cell = (DateCell *) bcell;
637 PopBox *box = cell->cell.gui_private;
638
639 /* initialize gui-specific, private data */
640 box->sheet = sheet;
641 box->item_edit = item_edit;
642 box->date_picker = GNC_DATE_PICKER (gnc_date_picker_new ());
643 gtk_widget_show_all (GTK_WIDGET(box->date_picker));
644 g_object_ref_sink(box->date_picker);
645
646 /* to mark cell as realized, remove the realize method */
647 cell->cell.gui_realize = NULL;
648 cell->cell.gui_move = gnc_date_cell_move;
649 cell->cell.enter_cell = gnc_date_cell_enter;
650 cell->cell.leave_cell = gnc_date_cell_leave;
651}
652
653static void
654gnc_date_cell_move (BasicCell *bcell)
655{
656 PopBox *box = bcell->gui_private;
657
658 date_picker_disconnect_signals ((DateCell *) bcell);
659
660 gnc_item_edit_set_popup (box->item_edit, NULL, NULL,
661 NULL, NULL, NULL, NULL, NULL);
662
663 box->calendar_popped = FALSE;
664}
665
666static int
667popup_get_height (GtkWidget *widget,
668 G_GNUC_UNUSED int space_available,
669 G_GNUC_UNUSED int row_height,
670 G_GNUC_UNUSED gpointer user_data)
671{
672 GtkWidget *cal = GTK_WIDGET (GNC_DATE_PICKER (widget)->calendar);
673 GtkRequisition req;
674
675 req.height = 0;
676 req.width = 0;
677
678 gtk_widget_get_preferred_size (cal, &req, NULL);
679
680 return req.height;
681}
682
683static void
684popup_set_focus (GtkWidget *widget,
685 G_GNUC_UNUSED gpointer user_data)
686{
687 gtk_widget_grab_focus (GTK_WIDGET (GNC_DATE_PICKER (widget)->calendar));
688}
689
690static gboolean
691gnc_date_cell_enter (BasicCell *bcell,
692 G_GNUC_UNUSED int *cursor_position,
693 int *start_selection,
694 int *end_selection)
695{
696 DateCell *cell = (DateCell *) bcell;
697 PopBox *box = bcell->gui_private;
698
699 gnc_item_edit_set_popup (box->item_edit, GTK_WIDGET (box->date_picker),
700 popup_get_height, NULL, popup_set_focus,
701 NULL, NULL, NULL);
702
703 block_picker_signals (cell);
704 gnc_date_picker_set_date (box->date_picker,
705 box->date.tm_mday,
706 box->date.tm_mon,
707 box->date.tm_year + 1900);
708 unblock_picker_signals (cell);
709
710 date_picker_connect_signals ((DateCell *) bcell);
711
712 *start_selection = 0;
713 *end_selection = -1;
714
715 return TRUE;
716}
717
718static void
719gnc_date_cell_leave (BasicCell *bcell)
720{
721 time64 time;
722 PopBox *box = bcell->gui_private;
723
724 date_picker_disconnect_signals ((DateCell *) bcell);
725
726 gnc_item_edit_set_popup (box->item_edit, NULL, NULL,
727 NULL, NULL, NULL, NULL, NULL);
728
729 box->calendar_popped = FALSE;
730
731 /* Refresh the date to expand any shortcuts. */
732 gnc_date_cell_get_date ((DateCell *)bcell, &time, TRUE);
733 gnc_date_cell_set_value_secs ((DateCell *)bcell, time);
734}
735
736void
737gnc_date_cell_get_date (DateCell *cell, time64 *time, gboolean warn)
738{
739 PopBox *box = cell->cell.gui_private;
740 if (!cell || !time)
741 return;
742
743 gnc_parse_date (&(box->date), cell->cell.value, warn);
744 *time = gnc_mktime (&box->date);
745}
746
747static void
748gnc_date_cell_set_value_internal (BasicCell *_cell, const char *str)
749{
750 DateCell *cell = (DateCell *) _cell;
751 PopBox *box = cell->cell.gui_private;
752 char buff[DATE_BUF];
753
754 gnc_parse_date (&(box->date), str, FALSE);
755
756 qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH,
757 box->date.tm_mday,
758 box->date.tm_mon + 1,
759 box->date.tm_year + 1900);
760
761 gnc_basic_cell_set_value_internal (_cell, buff);
762
763 if (!box->date_picker)
764 return;
765
766 block_picker_signals (cell);
767 gnc_date_picker_set_date (box->date_picker,
768 box->date.tm_mday,
769 box->date.tm_mon,
770 box->date.tm_year + 1900);
771 unblock_picker_signals (cell);
772}
utility functions for the GnuCash UI
Public declarations for GncDatePicker class.
Public declarations for GncItemEdit class.
Private declarations for GnucashSheet class.
Public declarations of GnucashRegister class.
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
Returns the GDate that is the threshold for auto-read-only.
Definition qofbook.cpp:1006
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Returns TRUE if the auto-read-only feature should be used, otherwise FALSE.
Definition qofbook.cpp:974
BasicCell * gnc_date_cell_new(void)
installs a callback to handle date recording
void gnc_date_cell_commit(DateCell *cell)
Commits any pending changes to the value of the cell.
void gnc_date_cell_set_value(DateCell *cell, int day, int mon, int year)
Accepts a numeric date and sets the contents of the date cell to that value.
void gnc_date_cell_get_date(DateCell *cell, time64 *time, gboolean warn)
Set a time64 to the value in the DateCell.
void gnc_date_cell_set_value_secs(DateCell *cell, time64 secs)
Sets the contents of the cell with seconds before or since the Unix epoch.
time64 gnc_mktime(struct tm *time)
calculate seconds from the epoch given a time struct
Definition gnc-date.cpp:219
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
Definition gnc-date.h:108
struct tm * gnc_localtime_r(const time64 *secs, struct tm *time)
fill out a time struct from a 64-bit time value adjusted for the current time zone.
Definition gnc-date.cpp:115
char dateSeparator(void)
dateSeparator Return the field separator for the current date format
Definition gnc-date.cpp:999
gboolean qof_scan_date(const char *buff, int *day, int *month, int *year)
qof_scan_date Convert a string into day / month / year integers according to the current dateFormat v...
Definition gnc-date.cpp:991
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
void gnc_tm_get_today_start(struct tm *tm)
The gnc_tm_get_today_start() routine takes a pointer to a struct tm and fills it in with the first se...
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
The DateCell object implements a date handling cell.
Definition datecell.h:92