GnuCash c935c2f+
Loading...
Searching...
No Matches
gnc-date-format.c
1/********************************************************************
2 * gnc-date-format.c -- Date formator widget *
3 * (GnuCash) *
4 * Copyright (C) 2003 Derek Atkins <derek@ihtfp.com> *
5 * *
6 * This program is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU General Public License as *
8 * published by the Free Software Foundation; either version 2 of *
9 * the License, or (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License*
17 * along with this program; if not, contact: *
18 * *
19 * Free Software Foundation Voice: +1-617-542-5942 *
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21 * Boston, MA 02110-1301, USA gnu@gnu.org *
22 ********************************************************************/
23
24/*
25 @NOTATION@
26*/
27
28/*
29 * Date format widget
30 *
31 * Authors: Derek Atkins <derek@ihtfp.com>
32 */
33
34#include <config.h>
35
36#include <gtk/gtk.h>
37#include <string.h>
38#include <stdio.h>
39
40#include "gnc-date-format.h"
41#include "dialog-utils.h"
42#include "gnc-engine.h"
43
44/* Perhaps it's better just to use MAX_DATE_LENGTH defined in gnc-date.h */
45#define MAX_DATE_LEN 80
46
47/* This static indicates the debugging module that this .o belongs to. */
48G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_GUI;
49
50enum
51{
52 FORMAT_CHANGED,
53 LAST_SIGNAL
54};
55
59{
60 GtkBox hbox;
61
62 GtkWidget* format_combobox;
63
64 GtkWidget* label;
65 GtkWidget* table;
66
67 GtkWidget* months_label;
68 GtkWidget* months_number;
69 GtkWidget* months_abbrev;
70 GtkWidget* months_name;
71
72 GtkWidget* years_label;
73 GtkWidget* years_button;
74
75 GtkWidget* custom_label;
76 GtkWidget* custom_entry;
77
78 GtkWidget* sample_label;
79};
80
81static guint date_format_signals [LAST_SIGNAL] = { 0 };
82
83static void gnc_date_format_finalize (GObject *object);
84static void gnc_date_format_compute_format(GNCDateFormat *gdf);
85
86void gnc_ui_date_format_changed_cb(GtkWidget *unused, gpointer user_data);
87
88G_DEFINE_TYPE(GNCDateFormat, gnc_date_format, GTK_TYPE_BOX)
89
90static void
91gnc_date_format_class_init (GNCDateFormatClass *klass)
92{
93 GObjectClass *gobject_class = (GObjectClass *) klass;
94
95 gobject_class->finalize = gnc_date_format_finalize;
96
97 date_format_signals [FORMAT_CHANGED] =
98 g_signal_new ("format_changed",
99 G_OBJECT_CLASS_TYPE (gobject_class),
100 G_SIGNAL_RUN_FIRST,
101 0,
102 NULL,
103 NULL,
104 g_cclosure_marshal_VOID__VOID,
105 G_TYPE_NONE,
106 0);
107}
108
109
110static void
111gnc_date_format_init (GNCDateFormat *gdf)
112{
113 GtkBuilder *builder;
114 GtkWidget *dialog;
115
116 g_return_if_fail(gdf);
117 g_return_if_fail(GNC_IS_DATE_FORMAT(gdf));
118
119 gtk_orientable_set_orientation (GTK_ORIENTABLE(gdf), GTK_ORIENTATION_HORIZONTAL);
120
121 // Set the name for this widget so it can be easily manipulated with css
122 gtk_widget_set_name (GTK_WIDGET(gdf), "gnc-id-date-format");
123
124 /* Open up the Glade and set the signals */
125 builder = gtk_builder_new();
126 gnc_builder_add_from_file (builder, "gnc-date-format.glade", "format-liststore");
127 gnc_builder_add_from_file (builder, "gnc-date-format.glade", "gnc_date_format_window");
128
129 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, gdf);
130
131 /* pull in all the child widgets */
132 gdf->label = GTK_WIDGET(gtk_builder_get_object (builder, "widget_label"));
133 gdf->format_combobox = GTK_WIDGET(gtk_builder_get_object (builder, "format_combobox"));
134
135 gdf->months_label = GTK_WIDGET(gtk_builder_get_object (builder, "months_label"));
136 gdf->months_number = GTK_WIDGET(gtk_builder_get_object (builder, "month_number_button"));
137 gdf->months_abbrev = GTK_WIDGET(gtk_builder_get_object (builder, "month_abbrev_button"));
138 gdf->months_name = GTK_WIDGET(gtk_builder_get_object (builder, "month_name_button"));
139
140 gdf->years_label = GTK_WIDGET(gtk_builder_get_object (builder, "years_label"));
141 gdf->years_button = GTK_WIDGET(gtk_builder_get_object (builder, "years_button"));
142
143 gdf->custom_label = GTK_WIDGET(gtk_builder_get_object (builder, "format_label"));
144 gdf->custom_entry = GTK_WIDGET(gtk_builder_get_object (builder, "format_entry"));
145
146 gdf->sample_label = GTK_WIDGET(gtk_builder_get_object (builder, "sample_label"));
147
148 /* Set initial format to gnucash default */
149 gnc_date_format_set_format(gdf, QOF_DATE_FORMAT_UNSET);
150
151 /* pull in the dialog and table widgets and play the reconnect game */
152 dialog = GTK_WIDGET(gtk_builder_get_object (builder, "gnc_date_format_window"));
153
154 gdf->table = GTK_WIDGET(gtk_builder_get_object (builder, "date_format_table"));
155 g_object_ref (G_OBJECT(gdf->table));
156 gtk_container_remove (GTK_CONTAINER(dialog), gdf->table);
157 gtk_container_add (GTK_CONTAINER(gdf), gdf->table);
158 g_object_unref (G_OBJECT(gdf->table));
159
160 g_object_unref(G_OBJECT(builder));
161
162 /* Destroy the now empty window */
163 gtk_widget_destroy(dialog);
164}
165
166
167static void
168gnc_date_format_finalize (GObject *object)
169{
170 g_return_if_fail(object != NULL);
171 g_return_if_fail(GNC_IS_DATE_FORMAT(object));
172
173 G_OBJECT_CLASS(gnc_date_format_parent_class)->finalize (object);
174}
175
176
185GtkWidget *
186gnc_date_format_new (void)
187{
188 return gnc_date_format_new_with_label (NULL);
189}
190
191
192GtkWidget *
193gnc_date_format_new_without_label (void)
194{
195 GtkWidget *widget = gnc_date_format_new_with_label(NULL);
196 GNCDateFormat *gdf = GNC_DATE_FORMAT(widget);
197
198 // remove the first column which has the label
199 gtk_grid_remove_column (GTK_GRID(gdf->table), 0);
200 gdf->label = NULL;
201 return widget;
202}
203
204
214GtkWidget *
215gnc_date_format_new_with_label (const char *label)
216{
217 GNCDateFormat *gdf;
218
219 gdf = g_object_new(GNC_TYPE_DATE_FORMAT, NULL);
220
221 if (label)
222 gtk_label_set_text(GTK_LABEL(gdf->label), label);
223
224 gnc_date_format_compute_format(gdf);
225 return GTK_WIDGET(gdf);
226}
227
228
229void
230gnc_date_format_set_format (GNCDateFormat *gdf, QofDateFormat format)
231{
232 g_return_if_fail(gdf);
233 g_return_if_fail(GNC_IS_DATE_FORMAT(gdf));
234
235 gtk_combo_box_set_active(GTK_COMBO_BOX(gdf->format_combobox), format);
236 gnc_date_format_compute_format(gdf);
237}
238
239
241gnc_date_format_get_format (GNCDateFormat *gdf)
242{
243 g_return_val_if_fail (gdf, QOF_DATE_FORMAT_LOCALE);
244 g_return_val_if_fail (GNC_IS_DATE_FORMAT(gdf), QOF_DATE_FORMAT_LOCALE);
245
246 return gtk_combo_box_get_active(GTK_COMBO_BOX(gdf->format_combobox));
247}
248
249
250void
251gnc_date_format_set_months (GNCDateFormat *gdf, GNCDateMonthFormat months)
252{
253 GtkWidget *button = NULL;
254
255 g_return_if_fail(gdf);
256 g_return_if_fail(GNC_IS_DATE_FORMAT(gdf));
257
258 switch (months)
259 {
260 case GNCDATE_MONTH_NUMBER:
261 button = gdf->months_number;
262 break;
263 case GNCDATE_MONTH_ABBREV:
264 button = gdf->months_abbrev;
265 break;
266 case GNCDATE_MONTH_NAME:
267 button = gdf->months_name;
268 break;
269 default:
270 break;
271 }
272
273 g_return_if_fail(button);
274
275 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
276 gnc_date_format_compute_format(gdf);
277}
278
279
281gnc_date_format_get_months (GNCDateFormat *gdf)
282{
283 g_return_val_if_fail(gdf, GNCDATE_MONTH_NUMBER);
284 g_return_val_if_fail(GNC_IS_DATE_FORMAT(gdf), GNCDATE_MONTH_NUMBER);
285
286 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gdf->months_number)))
287 return GNCDATE_MONTH_NUMBER;
288 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gdf->months_abbrev)))
289 return GNCDATE_MONTH_ABBREV;
290 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gdf->months_name)))
291 return GNCDATE_MONTH_NAME;
292
293 /* We should never reach this point */
294 g_assert(FALSE);
295 return GNCDATE_MONTH_NUMBER;
296}
297
298
299void
300gnc_date_format_set_years (GNCDateFormat *gdf, gboolean include_century)
301{
302 g_return_if_fail(gdf);
303 g_return_if_fail(GNC_IS_DATE_FORMAT(gdf));
304
305 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdf->years_button),
306 include_century);
307 gnc_date_format_compute_format(gdf);
308}
309
310
311gboolean
312gnc_date_format_get_years (GNCDateFormat *gdf)
313{
314 g_return_val_if_fail(gdf, FALSE);
315 g_return_val_if_fail(GNC_IS_DATE_FORMAT(gdf), FALSE);
316
317 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gdf->years_button));
318}
319
320
321void
322gnc_date_format_set_custom (GNCDateFormat *gdf, const char *format)
323{
324 g_return_if_fail(gdf);
325 g_return_if_fail(GNC_IS_DATE_FORMAT(gdf));
326
327 if (format == NULL || *format == '\0')
328 return;
329
330 gtk_entry_set_text(GTK_ENTRY(gdf->custom_entry), format);
331 gnc_date_format_compute_format(gdf);
332}
333
334
335const char *
336gnc_date_format_get_custom (GNCDateFormat *gdf)
337{
338 g_return_val_if_fail(gdf, "");
339 g_return_val_if_fail(GNC_IS_DATE_FORMAT(gdf), "");
340
341 return gtk_entry_get_text(GTK_ENTRY(gdf->custom_entry));
342}
343
344
345void
346gnc_ui_date_format_changed_cb(GtkWidget *unused, gpointer user_data)
347{
348 GNCDateFormat * gdf = user_data;
349
350 gnc_date_format_compute_format(gdf);
351}
352
353
354static void
355gnc_date_format_enable_month (GNCDateFormat *gdf, gboolean sensitive)
356{
357 gtk_widget_set_sensitive(gdf->months_label, sensitive);
358 gtk_widget_set_sensitive(gdf->months_number, sensitive);
359 gtk_widget_set_sensitive(gdf->months_abbrev, sensitive);
360 gtk_widget_set_sensitive(gdf->months_name, sensitive);
361}
362
363
364static void
365gnc_date_format_enable_year (GNCDateFormat *gdf, gboolean sensitive)
366{
367 gtk_widget_set_sensitive(gdf->years_label, sensitive);
368 gtk_widget_set_sensitive(gdf->years_button, sensitive);
369}
370
371
372static void
373gnc_date_format_enable_format (GNCDateFormat *gdf, gboolean sensitive)
374{
375 gtk_widget_set_sensitive(gdf->custom_label, sensitive);
376 gtk_widget_set_sensitive(gdf->custom_entry, sensitive);
377}
378
379
380void
381gnc_date_format_refresh (GNCDateFormat *gdf)
382{
383 int sel_option;
384 gboolean enable_year, enable_month, enable_custom, check_modifiers;
385 static gchar *format, *c;
386 gchar date_string[MAX_DATE_LEN];
387 time64 secs_now;
388 struct tm today;
389
390 g_return_if_fail(gdf);
391 g_return_if_fail(GNC_IS_DATE_FORMAT(gdf));
392
393 sel_option =
394 gtk_combo_box_get_active(GTK_COMBO_BOX(gdf->format_combobox));
395
396 switch (sel_option)
397 {
399 format = g_strdup(gtk_entry_get_text(GTK_ENTRY(gdf->custom_entry)));
400 enable_year = enable_month = check_modifiers = FALSE;
401 enable_custom = TRUE;
402 break;
403
407 format = g_strdup(qof_date_format_get_string(sel_option));
408 enable_year = enable_month = check_modifiers = enable_custom = FALSE;
409 break;
410
412 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdf->months_number), TRUE);
413 enable_year = check_modifiers = TRUE;
414 enable_month = enable_custom = FALSE;
415 break;
416
417 default:
418 enable_year = enable_month = check_modifiers = TRUE;
419 enable_custom = FALSE;
420 break;
421 }
422
423 /* Tweak widget sensitivities, as appropriate. */
424 gnc_date_format_enable_year(gdf, enable_year);
425 gnc_date_format_enable_month(gdf, enable_month);
426 gnc_date_format_enable_format(gdf, enable_custom);
427
428 /* Update the format string based upon the user's preferences */
429 if (check_modifiers)
430 {
431 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gdf->months_number)))
432 {
433 format = g_strdup(qof_date_format_get_string(sel_option));
434 }
435 else
436 {
437 format = g_strdup(qof_date_text_format_get_string(sel_option));
438 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gdf->months_name)))
439 {
440 c = strchr(format, 'b');
441 if (c)
442 *c = 'B';
443 }
444 }
445 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gdf->years_button)))
446 {
447 c = strchr(format, 'y');
448 if (c)
449 *c = 'Y';
450 }
451 }
452
453 /*
454 * Give feedback on the format string so users can see how it works
455 * without having to read the strftime man page. Prevent recursive
456 * signals.
457 */
458 g_signal_handlers_block_matched(gdf->custom_entry, G_SIGNAL_MATCH_DATA,
459 0, 0, NULL, NULL, gdf);
460 gtk_entry_set_text(GTK_ENTRY(gdf->custom_entry), format);
461 g_signal_handlers_unblock_matched(gdf->custom_entry, G_SIGNAL_MATCH_DATA,
462 0, 0, NULL, NULL, gdf);
463
464 /* Visual feedback on what the date will look like. */
465 secs_now = gnc_time (NULL);
466 gnc_localtime_r (&secs_now, &today);
467 qof_strftime(date_string, MAX_DATE_LEN, format, &today);
468 gtk_label_set_text(GTK_LABEL(gdf->sample_label), date_string);
469 g_free(format);
470}
471
472
473static void
474gnc_date_format_compute_format(GNCDateFormat *gdf)
475{
476 g_return_if_fail(gdf);
477 g_return_if_fail(GNC_IS_DATE_FORMAT(gdf));
478
479 /* refresh the widget */
480 gnc_date_format_refresh(gdf);
481
482 /* Emit a signal that we've changed */
483 g_signal_emit(G_OBJECT(gdf), date_format_signals[FORMAT_CHANGED], 0);
484}
All type declarations for the whole Gnucash engine.
const gchar * qof_date_text_format_get_string(QofDateFormat df)
This function returns a strftime formatting string for printing a date using words and numbers (e....
Definition gnc-date.cpp:525
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
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
GNCDateMonthFormat
This is how to format the month, as a number, an abbreviated string, or the full name.
Definition gnc-date.h:149
QofDateFormat
Enum for determining a date format.
Definition gnc-date.h:123
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
const gchar * qof_date_format_get_string(QofDateFormat df)
This function returns a strftime formatting string for printing an all numeric date (e....
Definition gnc-date.cpp:502
gsize qof_strftime(gchar *buf, gsize max, const gchar *format, const struct tm *tm)
qof_strftime calls qof_format_time to print a given time and afterwards tries to put the result into ...
@ QOF_DATE_FORMAT_LOCALE
Take from locale information.
Definition gnc-date.h:128
@ QOF_DATE_FORMAT_UNSET
No Fancy Date Format, use Global.
Definition gnc-date.h:131
@ QOF_DATE_FORMAT_UTC
UTC: 2004-12-12T23:39:11Z.
Definition gnc-date.h:129
@ QOF_DATE_FORMAT_CUSTOM
Used by the check printing code.
Definition gnc-date.h:130
@ QOF_DATE_FORMAT_ISO
ISO: yyyy-mm-dd.
Definition gnc-date.h:127