]>
Dogcows Code - chaz/homebank/blob - src/hb-misc.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2014 Maxime DOYEN
4 * This file is part of HomeBank.
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * HomeBank 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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 /* our global datas */
32 extern struct HomeBank
*GLOBALS
;
33 extern struct Preferences
*PREFS
;
35 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
37 static gdouble
fint(gdouble amount
)
45 static unsigned dix_puissance_n(unsigned n
)
47 unsigned i
, retval
= 1;
49 for(i
= 0; i
< n
; i
++)
55 double arrondi(const double x
, unsigned n
)
57 unsigned N
= dix_puissance_n(n
);
58 return floor((x
* N
) + 0.5) / N
;
64 * convert an amount in base currency
67 gdouble
to_base_amount(gdouble value
, guint32 kcur
)
73 if(kcur == GLOBALS->kcur)
76 cur = da_cur_get(kcur);
79 newvalue = value * cur->rate;
87 static gint real_mystrfmoncurr(gchar *outstr, gint outlen, gchar *buf1, Currency *cur)
90 gchar groupbuf[G_ASCII_DTOSTR_BUF_SIZE];
95 str_array = g_strsplit(buf1, ".", 2);
98 length = strlen(str_array[0]);
100 if( cur->grouping_char == NULL || !strlen(cur->grouping_char) )
102 monstr = g_strjoinv(cur->decimal_char, str_array);
106 gchar *s = str_array[0];
110 // avoid the - for negative amount
120 if( i!=0 && (length % 3) == 0 )
122 gchar *gc = cur->grouping_char;
132 while (length && *s++ != '\0');
135 monstr = g_strjoin(cur->decimal_char, groupbuf, str_array[1], NULL);
140 //g_print("**\nmystrfmon %.2f\n 0=%s\n 1=%s\n [%d]\n", value, str_array[0], str_array[1], length );
141 //g_print(" => %s :: %s\n", monstr, groupbuf);
143 g_strfreev(str_array);
145 // insert our formated number with symbol
146 g_snprintf(outstr, outlen, cur->monfmt, monstr);
154 static Currency *hb_strfmon_check(gchar *outstr, guint32 kcur)
156 Currency *cur = da_cur_get(kcur);
159 g_stpcpy(outstr, "error");
164 void hb_strfmon(gchar *outstr, gint outlen, gdouble value, guint32 kcur)
166 gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
170 cur = hb_strfmon_check(outstr, kcur);
173 monval = arrondi(value, cur->frac_digits);
174 g_ascii_formatd(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, cur->format, monval);
175 real_mystrfmoncurr(outstr, outlen, formatd_buf, cur);
180 void hb_strfmon_int(gchar *outstr, gint outlen, gdouble value, guint32 kcur)
182 gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
186 cur = hb_strfmon_check(outstr, kcur);
189 monval = arrondi(value, cur->frac_digits);
190 g_ascii_formatd(formatd_buf, sizeof (formatd_buf), "%0.f", monval);
191 real_mystrfmoncurr(outstr, outlen, formatd_buf, cur);
196 // test for currecny choose dialog
197 void mystrfmoncurrcurr(gchar *outstr, gint outlen, gdouble value, Currency *cur)
199 gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
202 monval = arrondi(value, cur->frac_digits);
203 g_ascii_formatd(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, cur->format, monval);
204 real_mystrfmoncurr(outstr, outlen, formatd_buf, cur);
211 /* obsolete before currencies */
212 gint
real_mystrfmon(gchar
*outstr
, gint outlen
, gchar
*buf1
, struct CurrencyFmt
*cur
)
215 gchar groupbuf
[G_ASCII_DTOSTR_BUF_SIZE
];
220 str_array
= g_strsplit(buf1
, ".", 2);
223 length
= strlen(str_array
[0]);
225 if( cur
->grouping_char
== NULL
|| !strlen(cur
->grouping_char
) )
227 monstr
= g_strjoinv(cur
->decimal_char
, str_array
);
231 gchar
*s
= str_array
[0];
235 // avoid the - for negative amount
245 if( i
!=0 && (length
% 3) == 0 )
247 gchar
*gc
= cur
->grouping_char
;
257 while (length
&& *s
++ != '\0');
260 monstr
= g_strjoin(cur
->decimal_char
, groupbuf
, str_array
[1], NULL
);
265 //g_print("**\nmystrfmon %.2f\n 0=%s\n 1=%s\n [%d]\n", value, str_array[0], str_array[1], length );
266 //g_print(" => %s :: %s\n", monstr, groupbuf);
268 g_strfreev(str_array
);
270 // insert our formated number with symbol
271 g_snprintf(outstr
, outlen
, cur
->monfmt
, monstr
);
279 gint
mystrfmon(gchar
*outstr
, gint outlen
, gdouble value
, gboolean minor
)
281 struct CurrencyFmt
*cur
;
282 gchar formatd_buf
[G_ASCII_DTOSTR_BUF_SIZE
];
286 cur
= minor
? &PREFS
->minor_cur
: &PREFS
->base_cur
;
288 monval
= arrondi(value
, cur
->frac_digits
);
292 monval
= (value
* PREFS
->euro_value
);
293 monval
+= (monval
> 0.0) ? 0.005 : -0.005;
294 monval
= (fint(monval
* 100) / 100);
297 //DB( g_print("fmt = %s\n", cur->format) );
299 g_ascii_formatd(formatd_buf
, sizeof (formatd_buf
), cur
->format
, monval
);
301 size
= real_mystrfmon(outstr
, outlen
, formatd_buf
, cur
);
310 gint
mystrfmon_int(gchar
*outstr
, gint outlen
, gdouble value
, gboolean minor
)
312 struct CurrencyFmt
*cur
;
313 gchar formatd_buf
[G_ASCII_DTOSTR_BUF_SIZE
];
314 gdouble monval
= value
;
317 cur
= minor
? &PREFS
->minor_cur
: &PREFS
->base_cur
;
321 monval
= (value
* PREFS
->euro_value
);
322 monval
+= (monval
> 0.0) ? 0.005 : -0.005;
323 monval
= (fint(monval
* 100) / 100);
326 g_ascii_formatd(formatd_buf
, sizeof (formatd_buf
), "%0.f", monval
);
328 size
= real_mystrfmon(outstr
, outlen
, formatd_buf
, cur
);
336 /* end obsolete call */
339 gchar
*get_normal_color_amount(gdouble value
)
344 value
= arrondi(value
, 2);
346 if(value
!= 0.0 && PREFS
->custom_colors
== TRUE
)
348 color
= (value
> 0.0) ? PREFS
->color_inc
: PREFS
->color_exp
;
354 gchar
*get_minimum_color_amount(gdouble value
, gdouble minvalue
)
359 value
= arrondi(value
, 2);
360 if(value
!= 0.0 && PREFS
->custom_colors
== TRUE
)
362 color
= (value
> 0.0) ? PREFS
->color_inc
: PREFS
->color_exp
;
363 if( value
< minvalue
)
364 color
= PREFS
->color_warn
;
369 void hb_label_set_amount(GtkLabel
*label
, gdouble value
, gboolean minor
)
371 gchar strbuffer
[G_ASCII_DTOSTR_BUF_SIZE
];
373 mystrfmon(strbuffer
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, minor
);
374 gtk_label_set_text(GTK_LABEL(label
), strbuffer
);
380 ** format/color and set a label text with a amount value
382 void hb_label_set_colvalue(GtkLabel
*label
, gdouble value
, gboolean minor
)
384 gchar strbuffer
[G_ASCII_DTOSTR_BUF_SIZE
];
388 mystrfmon(strbuffer
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, minor
);
390 if(value
!= 0.0 && PREFS
->custom_colors
== TRUE
)
392 color
= get_normal_color_amount(value
);
394 //g_print("color: %s\n", color);
398 markuptxt
= g_strdup_printf("<span color='%s'>%s</span>", color
, strbuffer
);
399 gtk_label_set_markup(GTK_LABEL(label
), markuptxt
);
405 gtk_label_set_text(GTK_LABEL(label
), strbuffer
);
410 void hb_label_set_colvaluecurr(GtkLabel *label, gdouble value, guint32 currkey)
412 gchar strbuffer[G_ASCII_DTOSTR_BUF_SIZE];
416 hb_strfmon(strbuffer, G_ASCII_DTOSTR_BUF_SIZE-1, value, currkey);
418 if(value != 0.0 && PREFS->custom_colors == TRUE)
420 color = get_normal_color_amount(value);
424 markuptxt = g_strdup_printf("<span color='%s'>%s</span>", color, strbuffer);
425 gtk_label_set_markup(GTK_LABEL(label), markuptxt);
431 gtk_label_set_text(GTK_LABEL(label), strbuffer);
438 void get_range_minmax(guint32 refdate, gint range, guint32 *mindate, guint32 *maxdate)
441 guint month, year, qnum;
443 if(refdate > *maxdate)
446 date = g_date_new_julian(refdate);
447 month = g_date_get_month(date);
448 year = g_date_get_year(date);
449 qnum = ((month-1)/3)+1;
451 DB( g_print("m=%d, y=%d, qnum=%d\n", month, year, qnum) );
455 case 0: // this month
456 g_date_set_day(date, 1);
457 *mindate = g_date_get_julian(date);
458 g_date_add_days(date, g_date_get_days_in_month(month, year)-1);
459 *maxdate = g_date_get_julian(date);
462 case 1: // last month
463 g_date_set_day(date, 1);
464 g_date_subtract_months(date, 1);
465 *mindate = g_date_get_julian(date);
466 month = g_date_get_month(date);
467 year = g_date_get_year(date);
468 g_date_add_days(date, g_date_get_days_in_month(month, year)-1);
469 *maxdate = g_date_get_julian(date);
472 case 2: // this quarter
473 g_date_set_day(date, 1);
474 g_date_set_month(date, (qnum-1)*3+1);
475 *mindate = g_date_get_julian(date);
476 g_date_add_months(date, 3);
477 g_date_subtract_days(date, 1);
478 *maxdate = g_date_get_julian(date);
481 case 3: // last quarter
482 g_date_set_day(date, 1);
483 g_date_set_month(date, (qnum-1)*3+1);
484 g_date_subtract_months(date, 3);
485 *mindate = g_date_get_julian(date);
486 g_date_add_months(date, 3);
487 g_date_subtract_days(date, 1);
488 *maxdate = g_date_get_julian(date);
492 g_date_set_dmy(date, 1, 1, year);
493 *mindate = g_date_get_julian(date);
494 g_date_set_dmy(date, 31, 12, year);
495 *maxdate = g_date_get_julian(date);
500 case 6: // last 30 days
501 *mindate = refdate - 30;
505 case 7: // last 60 days
506 *mindate = refdate - 60;
510 case 8: // last 90 days
511 *mindate = refdate - 90;
515 case 9: // last 12 months
516 g_date_subtract_months(date, 12);
517 *mindate = g_date_get_julian(date);
533 * compare 2 utf8 string
535 gint
hb_string_utf8_compare(gchar
*s1
, gchar
*s2
)
540 if (s1
== NULL
|| s2
== NULL
)
542 if (s1
== NULL
&& s2
== NULL
)
545 retval
= (s1
== NULL
) ? -1 : 1;
550 //retval = g_utf8_collate(s1 != NULL ? s1 : "", s2 != NULL ? s2 : "");
551 ns1
= g_utf8_normalize(s1
, -1, G_NORMALIZE_DEFAULT
);
552 ns2
= g_utf8_normalize(s2
, -1, G_NORMALIZE_DEFAULT
);
553 retval
= strcasecmp(ns1
, ns2
);
562 void hb_string_strip_crlf(gchar
*str
)
570 if( *p
== '\n' || *p
== '\r')
580 hb_strdup_nobrackets (const gchar
*str
)
588 length
= strlen (str
) + 1;
589 new_str
= g_new (char, length
);
594 if( *s
!= '[' && *s
!= ']' )
608 hb_date_parser_get_nums(gchar
*string
, gint
*n1
, gint
*n2
, gint
*n3
)
613 //DB( g_print("(qif) hb_qif_parser_get_dmy for '%s'\n", string) );
616 str_array
= g_strsplit (string
, "/", 3);
617 if( g_strv_length( str_array
) != 3 )
619 g_strfreev (str_array
);
620 str_array
= g_strsplit (string
, ".", 3);
623 if( g_strv_length( str_array
) != 3 )
625 g_strfreev (str_array
);
626 str_array
= g_strsplit (string
, "-", 3);
630 if( g_strv_length( str_array
) == 3 )
632 *n1
= atoi(str_array
[0]);
633 *n2
= atoi(str_array
[1]);
634 *n3
= atoi(str_array
[2]);
638 g_strfreev (str_array
);
644 guint32
hb_date_get_julian(gchar
*string
, gint datefmt
)
647 gint n1
, n2
, n3
, d
, m
, y
;
650 DB( g_print("hb_date_get_julian: %s, %d\n", string
, datefmt
) );
652 if( hb_date_parser_get_nums(string
, &n1
, &n2
, &n3
) )
654 DB( g_print("-> %d %d %d\n", n1
, n2
, n3
) );
658 case PRF_DATEFMT_MDY
:
663 case PRF_DATEFMT_DMY
:
669 case PRF_DATEFMT_YMD
:
676 //correct for 2 digits year
685 DB( g_print("-> %d %d %d\n", d
, m
, y
) );
687 if(d
<= 31 && m
<= 12)
690 g_date_set_dmy(date
, d
, m
, y
);
691 if( g_date_valid (date
) )
693 julian
= g_date_get_julian (date
);
703 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
706 gchar
*hb_filename_new_with_extention(gchar
*filename
, const gchar
*extension
)
714 dirname
= g_path_get_dirname (filename
);
715 basename
= g_path_get_basename(filename
);
716 str_array
= g_strsplit(basename
, ".", 0);
717 newbasename
= g_strdup_printf("%s.%s", str_array
[0], extension
);
718 newfilename
= g_build_filename(dirname
, newbasename
, NULL
);
720 g_strfreev(str_array
);
729 /* file backup, qif export */
732 /*gchar *homebank_filename_without_extention(gchar *path)
738 basename = g_path_get_basename(path);
740 str_array = g_strsplit(basename, ".", 0);
742 newname = g_strdup(str_array[0]);
744 g_strfreev(str_array);
750 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
753 static gboolean
hb_string_isdate(gchar
*str
)
757 return(hb_date_parser_get_nums(str
, &d
, &m
, &y
));
761 static gboolean
hb_string_isdigit(gchar
*str
)
763 gboolean valid
= TRUE
;
765 valid
= g_ascii_isdigit(*str
++);
770 static gboolean hb_string_isprint(gchar *str)
772 gboolean valid = TRUE;
774 valid = g_ascii_isprint(*str++);
781 static gboolean
hb_string_isprint(gchar
*str
)
783 gboolean valid
= TRUE
;
787 if(g_utf8_validate(str
, -1, NULL
))
792 c
= g_utf8_get_char(p
);
793 valid
= g_unichar_isprint(c
);
794 p
= g_utf8_next_char(p
);
801 gboolean
hb_string_csv_valid(gchar
*str
, guint nbcolumns
, gint
*csvtype
)
804 gboolean valid
= TRUE
;
809 gchar
*type
[5] = { "string", "date", "int", "double" };
813 DB( g_print("\n** hb_string_csv_valid: init %d\n", valid
) );
815 hb_string_strip_crlf(str
);
816 str_array
= g_strsplit (str
, ";", 0);
818 DB( g_print(" -> length %d, nbcolumns %d\n", g_strv_length( str_array
), nbcolumns
) );
820 if( g_strv_length( str_array
) != nbcolumns
)
826 for(i
=0;i
<nbcolumns
;i
++)
829 lasttype
= csvtype
[i
];
834 DB( g_print(" -> fail on column %d, type: %s\n", i
, type
[lasttype
]) );
838 DB( g_print(" -> control column %d, type: %d, valid: %d '%s'\n", i
, lasttype
, valid
, str_array
[i
]) );
843 valid
= hb_string_isdate(str_array
[i
]);
846 valid
= hb_string_isprint(str_array
[i
]);
849 valid
= hb_string_isdigit(str_array
[i
]);
852 g_ascii_strtod(str_array
[i
], NULL
);
853 //todo : see this errno
856 DB( g_print("errno: %d\n", errno
) );
864 g_strfreev (str_array
);
866 DB( g_print(" --> return %d\n", valid
) );
872 void hb_print_date(guint32 jdate
, gchar
*label
)
877 date
= g_date_new_julian(jdate
);
878 g_date_strftime (buffer1
, 128-1, "%x", date
);
880 g_print(" - %s %s\n", label
!= NULL
? label
:"date is", buffer1
);
886 ** parse a string an retrieve an iso date (dd-mm-yy(yy) or dd/mm/yy(yy))
890 guint32 hb_date_get_julian_parse(gchar *str)
892 gchar **str_array = NULL;
895 guint32 julian = GLOBALS->today;
897 // try with - separator
898 if( g_strrstr(str, "-") != NULL )
900 str_array = g_strsplit (str, "-", 3);
904 if( g_strrstr(str, "/") != NULL )
906 str_array = g_strsplit (str, "/", 3);
910 if( g_strv_length( str_array ) == 3 )
912 d = atoi(str_array[0]);
913 m = atoi(str_array[1]);
914 y = atoi(str_array[2]);
916 //correct for 2 digits year
925 //todo: here if month is > 12 then the format is probably mm/dd/yy(yy)
926 //or maybe check with g_date_valid_julian(julian)
931 g_date_set_dmy(date, d, m, y);
932 julian = g_date_get_julian (date);
935 DB( g_print("date: %s :: %d %d %d :: %d\n", str, d, m, y, julian ) );
939 g_strfreev (str_array);
945 /* -------------------- */
953 void hex_dump(guchar
*ptr
, guint length
)
955 guchar ascii
[MAX_DUMP
+4];
958 g_print("**hex_dump - %d bytes\n", length
);
962 g_print("%08x: ", (guint
)ptr
+i
);
964 for(j
=0;j
<MAX_DUMP
;j
++)
966 if(i
>= length
) break;
969 if(ptr
[i
] >= 32 && ptr
[i
] <= 126)
974 g_print("%02x ", ptr
[i
]);
979 g_print(" '%s'\n", ascii
);
This page took 0.075709 seconds and 4 git commands to generate.