]>
Dogcows Code - chaz/homebank/blob - src/hb-misc.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2016 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/>.
21 //nota: this file should be renamed hb-utils
34 /* our global datas */
35 extern struct HomeBank
*GLOBALS
;
36 extern struct Preferences
*PREFS
;
38 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
40 static const double fac
[7] = { 1, 10, 100, 1000, 10000, 100000, 1000000 };
42 double hb_amount_round(const double x
, unsigned int digits
)
44 digits
= MAX(digits
, 6);
45 return floor((x
* fac
[digits
]) + 0.5) / fac
[digits
];
49 // used to convert from national to euro currency
50 // used in hb_account.c :: only when convert account to euro
51 // round option is to 0.5 case so 1.32 is 1.3, but 1.35 is 1.4
53 gdouble
hb_amount_to_euro(gdouble amount
)
55 return hb_amount_round((amount
/ PREFS
->euro_value
), 2);
56 //return hb_amount_round((amount * PREFS->euro_value), PREFS.minor_cur->frac_digits);
60 /* new >5.1 currency fct
62 * convert an amount in base currency
65 gdouble
hb_amount_base(gdouble value
, guint32 kcur
)
70 if(kcur
== GLOBALS
->kcur
)
73 cur
= da_cur_get(kcur
);
74 if(cur
== NULL
|| cur
->rate
== 0.0)
77 newvalue
= value
/ cur
->rate
;
78 return hb_amount_round(newvalue
, cur
->frac_digits
);
82 static Currency
*hb_strfmon_check(gchar
*outstr
, guint32 kcur
)
84 Currency
*cur
= da_cur_get(kcur
);
87 g_stpcpy(outstr
, "nan");
92 gchar
*hb_str_rate(gchar
*outstr
, gint outlen
, gdouble rate
)
97 count
= g_snprintf(outstr
, outlen
, "%.6f", rate
);
98 //remove trailing 0 and decimal point
108 if(*p
== '.' || *p
== ',')
114 /* this function copy a number 99999.99 at s into d and count
115 * number of digits for integer part and decimal part
117 static gchar
* _strfnumcopycount(gchar
*s
, gchar
*d
, gchar
*decchar
, gint
*plen
, gint
*pnbint
, gint
*pnbdec
)
119 gint len
=0, nbint
=0, nbdec
=0;
127 while(*s
!= 0 && *s
!= '.') {
134 d
= g_stpcpy(d
, decchar
);
144 // end string | fill external count
153 //todo: used only in ui_prefs.c
154 gchar
*hb_str_formatd(gchar
*outstr
, gint outlen
, gchar
*buf1
, Currency
*cur
, gboolean showsymbol
)
160 if(showsymbol
&& cur
->sym_prefix
)
162 d
= g_stpcpy (d
, cur
->symbol
);
167 d
= _strfnumcopycount(buf1
, d
, cur
->decimal_char
, &len
, &nbi
, &nbd
);
169 if( cur
->grouping_char
!= NULL
&& strlen(cur
->grouping_char
) > 0 )
182 if( !(grpcnt
% 3) && i
<(nbi
-1))
184 d
= g_stpcpy(d
, cur
->grouping_char
);
191 d
= g_stpcpy(d
, cur
->decimal_char
);
192 d
= g_stpcpy(d
, s
+1);
197 if(showsymbol
&& !cur
->sym_prefix
)
200 d
= g_stpcpy (d
, cur
->symbol
);
209 void hb_strfmon(gchar
*outstr
, gint outlen
, gdouble value
, guint32 kcur
, gboolean minor
)
211 gchar formatd_buf
[outlen
];
217 cur
= hb_strfmon_check(outstr
, kcur
);
220 monval
= hb_amount_round(value
, cur
->frac_digits
);
221 g_ascii_formatd(formatd_buf
, outlen
, cur
->format
, monval
);
222 hb_str_formatd(outstr
, outlen
, formatd_buf
, cur
, TRUE
);
227 cur
= &PREFS
->minor_cur
;
228 monval
= hb_amount_to_euro(value
);
229 g_ascii_formatd(formatd_buf
, outlen
, cur
->format
, monval
);
230 hb_str_formatd(outstr
, outlen
, formatd_buf
, cur
, TRUE
);
235 void hb_strfmon_int(gchar
*outstr
, gint outlen
, gdouble value
, guint32 kcur
, gboolean minor
)
237 gchar formatd_buf
[outlen
];
243 cur
= hb_strfmon_check(outstr
, kcur
);
246 monval
= hb_amount_round(value
, cur
->frac_digits
);
247 g_ascii_formatd(formatd_buf
, outlen
, "%0.f", monval
);
248 hb_str_formatd(outstr
, outlen
, formatd_buf
, cur
, TRUE
);
253 cur
= &PREFS
->minor_cur
;
254 monval
= hb_amount_to_euro(value
);
255 g_ascii_formatd(formatd_buf
, outlen
, cur
->format
, monval
);
256 hb_str_formatd(outstr
, outlen
, formatd_buf
, cur
, TRUE
);
262 void hb_strfnum(gchar
*outstr
, gint outlen
, gdouble value
, guint32 kcur
, gboolean minor
)
264 gchar formatd_buf
[outlen
];
270 cur
= hb_strfmon_check(outstr
, kcur
);
273 monval
= hb_amount_round(value
, cur
->frac_digits
);
274 g_ascii_formatd(formatd_buf
, outlen
, "%0.f", monval
);
275 hb_str_formatd(outstr
, outlen
, formatd_buf
, cur
, TRUE
);
280 cur
= &PREFS
->minor_cur
;
281 monval
= hb_amount_to_euro(value
);
282 g_ascii_formatd(formatd_buf
, outlen
, "%0.f", monval
);
283 hb_str_formatd(outstr
, outlen
, formatd_buf
, cur
, TRUE
);
291 gchar
*get_normal_color_amount(gdouble value
)
296 value
= hb_amount_round(value
, 2);
298 if(value
!= 0.0 && PREFS
->custom_colors
== TRUE
)
300 color
= (value
> 0.0) ? PREFS
->color_inc
: PREFS
->color_exp
;
306 gchar
*get_minimum_color_amount(gdouble value
, gdouble minvalue
)
311 value
= hb_amount_round(value
, 2);
312 if(value
!= 0.0 && PREFS
->custom_colors
== TRUE
)
314 color
= (value
> 0.0) ? PREFS
->color_inc
: PREFS
->color_exp
;
315 if( value
< minvalue
)
316 color
= PREFS
->color_warn
;
321 void hb_label_set_amount(GtkLabel
*label
, gdouble value
, guint32 kcur
, gboolean minor
)
323 gchar strbuffer
[G_ASCII_DTOSTR_BUF_SIZE
];
325 hb_strfmon(strbuffer
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, kcur
, minor
);
326 gtk_label_set_text(GTK_LABEL(label
), strbuffer
);
332 ** format/color and set a label text with a amount value
334 void hb_label_set_colvalue(GtkLabel
*label
, gdouble value
, guint32 kcur
, gboolean minor
)
336 gchar strbuffer
[G_ASCII_DTOSTR_BUF_SIZE
];
340 hb_strfmon(strbuffer
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, kcur
, minor
);
342 if(value
!= 0.0 && PREFS
->custom_colors
== TRUE
)
344 color
= get_normal_color_amount(value
);
346 //g_print("color: %s\n", color);
350 markuptxt
= g_strdup_printf("<span color='%s'>%s</span>", color
, strbuffer
);
351 gtk_label_set_markup(GTK_LABEL(label
), markuptxt
);
357 gtk_label_set_text(GTK_LABEL(label
), strbuffer
);
368 gint
hb_string_compare(gchar
*s1
, gchar
*s2
)
372 if (s1
== NULL
|| s2
== NULL
)
374 if (s1
== NULL
&& s2
== NULL
)
377 retval
= (s1
== NULL
) ? -1 : 1;
381 retval
= strcasecmp(s1
, s2
);
389 * compare 2 utf8 string
391 gint
hb_string_utf8_compare(gchar
*s1
, gchar
*s2
)
396 if (s1
== NULL
|| s2
== NULL
)
398 if (s1
== NULL
&& s2
== NULL
)
401 retval
= (s1
== NULL
) ? -1 : 1;
406 //retval = g_utf8_collate(s1 != NULL ? s1 : "", s2 != NULL ? s2 : "");
407 ns1
= g_utf8_normalize(s1
, -1, G_NORMALIZE_DEFAULT
);
408 ns2
= g_utf8_normalize(s2
, -1, G_NORMALIZE_DEFAULT
);
409 retval
= strcasecmp(ns1
, ns2
);
418 void hb_string_strip_crlf(gchar
*str
)
426 if( *p
== '\n' || *p
== '\r')
436 void hb_string_replace_char(gchar c
, gchar
*str
)
456 /*static void strip_extra_spaces(char* str) {
458 for(i=x=1; str[i]; ++i)
459 if(!isspace(str[i]) || (i>0 && !isspace(str[i-1])))
467 hb_strdup_nobrackets (const gchar
*str
)
475 length
= strlen (str
) + 1;
476 new_str
= g_new (char, length
);
481 if( *s
!= '[' && *s
!= ']' )
495 hb_date_parser_get_nums(gchar
*string
, gint
*n1
, gint
*n2
, gint
*n3
)
500 //DB( g_print("(qif) hb_qif_parser_get_dmy for '%s'\n", string) );
503 str_array
= g_strsplit (string
, "/", 3);
504 if( g_strv_length( str_array
) != 3 )
506 g_strfreev (str_array
);
507 str_array
= g_strsplit (string
, ".", 3);
510 if( g_strv_length( str_array
) != 3 )
512 g_strfreev (str_array
);
513 str_array
= g_strsplit (string
, "-", 3);
517 if( g_strv_length( str_array
) == 3 )
519 *n1
= atoi(str_array
[0]);
520 *n2
= atoi(str_array
[1]);
521 *n3
= atoi(str_array
[2]);
525 g_strfreev (str_array
);
531 guint32
hb_date_get_julian(gchar
*string
, gint datefmt
)
534 gint n1
, n2
, n3
, d
, m
, y
;
537 DB( g_print("\n[utils] hb_date_get_julian\n") );
539 DB( g_print(" - '%s' dateorder=%d\n", string
, datefmt
) );
541 if( hb_date_parser_get_nums(string
, &n1
, &n2
, &n3
) )
543 DB( g_print(" - '%d' '%d' '%d'\n", n1
, n2
, n3
) );
547 case PRF_DATEFMT_MDY
:
552 case PRF_DATEFMT_DMY
:
558 case PRF_DATEFMT_YMD
:
565 //correct for 2 digits year
574 if(d
<= 31 && m
<= 12)
576 if( g_date_valid_dmy(d
, m
, y
) )
578 date
= g_date_new_dmy(d
, m
, y
);
579 julian
= g_date_get_julian (date
);
584 DB( g_print(" > %d %d %d julian=%d\n", d
, m
, y
, julian
) );
592 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
595 gchar
*hb_util_filename_new_with_extension(gchar
*filename
, const gchar
*extension
)
597 gchar
*lastdot
, *fwe
;
600 DB( g_print("\n[util] filename with extension\n") );
602 DB( g_print(" - orig: '%s' => '%s'\n", filename
, extension
) );
604 //duplicate without extensions
605 lastdot
= g_strrstr(filename
, ".");
608 fwe
= g_strndup(filename
, strlen(filename
) - strlen(lastdot
));
609 DB( g_print(" - fwe: '%s'\n", fwe
) );
610 newfilename
= g_strdup_printf("%s.%s", fwe
, extension
);
615 newfilename
= g_strdup_printf("%s.%s", filename
, extension
);
618 DB( g_print(" - new: '%s'\n", newfilename
) );
624 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
627 gboolean
hb_string_isdate(gchar
*str
)
631 return(hb_date_parser_get_nums(str
, &d
, &m
, &y
));
635 gboolean
hb_string_isdigit(gchar
*str
)
637 gboolean valid
= TRUE
;
639 valid
= g_ascii_isdigit(*str
++);
644 gboolean hb_string_isprint(gchar *str)
646 gboolean valid = TRUE;
648 valid = g_ascii_isprint(*str++);
655 gboolean
hb_string_isprint(gchar
*str
)
657 gboolean valid
= TRUE
;
661 if(g_utf8_validate(str
, -1, NULL
))
666 c
= g_utf8_get_char(p
);
667 valid
= g_unichar_isprint(c
);
668 p
= g_utf8_next_char(p
);
675 gchar
*hb_sprint_date(gchar
*outstr
, guint32 julian
)
679 g_date_clear(&date
, 1);
680 g_date_set_julian (&date
, julian
);
681 switch(PREFS
->dtex_datefmt
)
683 case PRF_DATEFMT_MDY
:
685 g_sprintf(outstr
, "%02d/%02d/%04d",
686 g_date_get_month(&date
),
687 g_date_get_day(&date
),
688 g_date_get_year(&date
)
692 case PRF_DATEFMT_DMY
:
694 g_sprintf(outstr
, "%02d/%02d/%04d",
695 g_date_get_day(&date
),
696 g_date_get_month(&date
),
697 g_date_get_year(&date
)
701 g_sprintf(outstr
, "%04d/%02d/%02d",
702 g_date_get_year(&date
),
703 g_date_get_month(&date
),
704 g_date_get_day(&date
)
712 //used only in DB() macro !!
713 void hb_print_date(guint32 jdate
, gchar
*label
)
718 date
= g_date_new_julian(jdate
);
719 g_date_strftime (buffer1
, 128-1, "%x", date
);
721 g_print(" - %s %s\n", label
!= NULL
? label
:"date is", buffer1
);
727 ** parse a string an retrieve an iso date (dd-mm-yy(yy) or dd/mm/yy(yy))
731 guint32 hb_date_get_julian_parse(gchar *str)
733 gchar **str_array = NULL;
736 guint32 julian = GLOBALS->today;
738 // try with - separator
739 if( g_strrstr(str, "-") != NULL )
741 str_array = g_strsplit (str, "-", 3);
745 if( g_strrstr(str, "/") != NULL )
747 str_array = g_strsplit (str, "/", 3);
751 if( g_strv_length( str_array ) == 3 )
753 d = atoi(str_array[0]);
754 m = atoi(str_array[1]);
755 y = atoi(str_array[2]);
757 //correct for 2 digits year
766 //todo: here if month is > 12 then the format is probably mm/dd/yy(yy)
767 //or maybe check with g_date_valid_julian(julian)
772 g_date_set_dmy(date, d, m, y);
773 julian = g_date_get_julian (date);
776 DB( g_print("date: %s :: %d %d %d :: %d\n", str, d, m, y, julian ) );
780 g_strfreev (str_array);
786 /* -------------------- */
794 void hex_dump(guchar
*ptr
, guint length
)
796 guchar ascii
[MAX_DUMP
+4];
799 g_print("**hex_dump - %d bytes\n", length
);
803 g_print("%08x: ", (guint
)ptr
+i
);
805 for(j
=0;j
<MAX_DUMP
;j
++)
807 if(i
>= length
) break;
810 if(ptr
[i
] >= 32 && ptr
[i
] <= 126)
815 g_print("%02x ", ptr
[i
]);
820 g_print(" '%s'\n", ascii
);
This page took 0.092498 seconds and 4 git commands to generate.