c452bdd263d1b2a0c031c9600674e0eaeb38e0a8
[chaz/homebank] / src / homebank.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2014 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20 #include "homebank.h"
21
22 #include "dsp_mainwindow.h"
23 #include "hb-preferences.h"
24 #include "language.h"
25
26 #ifdef G_OS_WIN32
27 #include <windows.h>
28 #endif
29
30 #define APPLICATION_NAME "HomeBank"
31
32 /****************************************************************************/
33 /* Debug macros */
34 /****************************************************************************/
35 #define MYDEBUG 0
36
37 #if MYDEBUG
38 #define DB(x) (x);
39 #else
40 #define DB(x);
41 #endif
42
43 /* our global datas */
44 struct HomeBank *GLOBALS;
45 struct Preferences *PREFS;
46
47
48 /* installation paths */
49 static gchar *config_dir = NULL;
50 static gchar *images_dir = NULL;
51 static gchar *pixmaps_dir = NULL;
52 static gchar *locale_dir = NULL;
53 static gchar *help_dir = NULL;
54 static gchar *datas_dir = NULL;
55
56
57 //#define MARKUP_STRING "<span size='small'>%s</span>"
58
59
60 /* Application arguments */
61 static gboolean arg_version = FALSE;
62 static gchar **files = NULL;
63
64 static GOptionEntry option_entries[] =
65 {
66 { "version", '\0', 0, G_OPTION_ARG_NONE, &arg_version,
67 N_("Output version information and exit"), NULL },
68
69 { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &files,
70 NULL, N_("[FILE]") },
71
72 { NULL }
73 };
74
75
76 /*
77 ** try to determine the file type (if supported for import by homebank)
78 **
79 **
80 */
81 gint homebank_alienfile_recognize(gchar *filename)
82 {
83 GIOChannel *io;
84 gint i, retval = FILETYPE_UNKNOW;
85 gchar *tmpstr;
86 gint io_stat;
87 GError *err = NULL;
88 static gint csvtype[7] = {
89 CSV_DATE,
90 CSV_INT,
91 CSV_STRING,
92 CSV_STRING,
93 CSV_STRING,
94 CSV_DOUBLE,
95 CSV_STRING,
96 };
97
98
99 DB( g_print("\n[homebank] alienfile_recognize\n") );
100
101
102 io = g_io_channel_new_file(filename, "r", NULL);
103 if(io != NULL)
104 {
105 g_io_channel_set_encoding(io, NULL, NULL); /* set to binary mode */
106
107 for(i=0;i<4;i++)
108 {
109 if( retval != FILETYPE_UNKNOW )
110 break;
111
112 io_stat = g_io_channel_read_line(io, &tmpstr, NULL, NULL, &err);
113 if( io_stat == G_IO_STATUS_EOF)
114 break;
115 if( io_stat == G_IO_STATUS_ERROR )
116 {
117 DB (g_print(" + ERROR %s\n",err->message));
118 break;
119 }
120 if( io_stat == G_IO_STATUS_NORMAL)
121 {
122 if( *tmpstr != '\0' )
123 {
124 DB( g_print(" line %d: '%s' retval=%d\n", i, tmpstr, retval) );
125
126 /* native homebank file */
127 if( g_str_has_prefix(tmpstr, "<homebank v="))
128 {
129 DB( g_print(" type is HomeBank\n") );
130 retval = FILETYPE_HOMEBANK;
131 }
132 else
133
134 // QIF file ?
135 if( g_str_has_prefix(tmpstr, "!Type") ||
136 g_str_has_prefix(tmpstr, "!type") ||
137 g_str_has_prefix(tmpstr, "!Option") ||
138 g_str_has_prefix(tmpstr, "!option") ||
139 g_str_has_prefix(tmpstr, "!Account") ||
140 g_str_has_prefix(tmpstr, "!account")
141 )
142 {
143 DB( g_print(" type is QIF\n") );
144 retval = FILETYPE_QIF;
145 }
146 else
147
148 /* is it OFX ? */
149 if( g_strstr_len(tmpstr, 10, "OFX") != NULL)
150 {
151 DB( g_print(" type is OFX\n") );
152 retval = FILETYPE_OFX;
153 }
154
155 /* is it csv homebank ? */
156 else
157 {
158 gboolean hbcsv;
159
160 hbcsv = hb_string_csv_valid(tmpstr, 8, csvtype);
161
162 DB( g_print(" hbcsv %d\n", hbcsv) );
163
164 if( hbcsv == TRUE )
165 {
166 DB( g_print(" type is CSV homebank\n") );
167 retval = FILETYPE_CSV_HB;
168 }
169
170
171 }
172
173 g_free(tmpstr);
174 }
175 }
176
177 }
178 g_io_channel_unref (io);
179 }
180
181 return retval;
182 }
183
184
185 /* = = = = = = = = = = = = = = = = = = = = */
186
187
188
189
190 /*
191 ** ensure the filename ends with '.xhb'
192 */
193 void homebank_file_ensure_xhb(void)
194 {
195 gchar *newfilepath;
196
197 DB( g_print("\n[homebank] file_ensure_xhb\n") );
198
199 newfilepath = hb_filename_new_with_extention(GLOBALS->xhb_filepath, "xhb");
200 hbfile_change_filepath(newfilepath);
201
202 DB( g_print("- out: %s\n", GLOBALS->xhb_filepath) );
203 }
204
205
206 static gboolean homebank_copy_file(gchar *srcfile, gchar *dstfile)
207 {
208 gchar *buffer;
209 gsize length;
210 //GError *error = NULL;
211 gboolean retval = FALSE;
212
213 if (g_file_get_contents (srcfile, &buffer, &length, NULL))
214 {
215 if(g_file_set_contents(dstfile, buffer, length, NULL))
216 {
217 retval = TRUE;
218 }
219 }
220 return retval;
221 }
222
223
224
225 void homebank_backup_current_file(gchar *pathname)
226 {
227 gchar *basename;
228 gchar *dirname;
229 gchar *filename;
230 gchar *newname;
231 gchar **str_array;
232
233 DB( g_print("\n[homebank] backup_current_file\n") );
234
235 basename = g_path_get_basename(pathname);
236 dirname = g_path_get_dirname (pathname);
237
238 if( g_str_has_suffix(basename, ".xhb") )
239 {
240 str_array = g_strsplit(basename, ".", 0);
241 filename = g_strdup_printf("%s.xhb~", str_array[0]);
242 newname = g_build_filename(dirname, filename, NULL);
243 g_free(filename);
244
245 if( g_file_test(newname, G_FILE_TEST_EXISTS) )
246 {
247 DB( g_print("- remove existing: %s\n", newname) );
248 g_remove(newname);
249 }
250
251 DB( g_print("- copy %s => %s\n", pathname, newname) );
252
253 homebank_copy_file (pathname, newname);
254 //#512046
255 //retval = g_rename(pathname, newname);
256
257 //DB( g_print("retval %d\n", retval) );
258
259 g_strfreev(str_array);
260 g_free(newname);
261 }
262 g_free(basename);
263 g_free(dirname);
264 }
265
266 /* = = = = = = = = = = = = = = = = = = = = */
267 /* url open */
268
269
270 #ifdef G_OS_WIN32
271 #define SW_NORMAL 1
272
273 static gboolean
274 homebank_util_url_show_win32 (const gchar *url)
275 {
276 int retval;
277 gchar *errmsg;
278
279 /* win32 API call */
280 retval = ShellExecuteA (NULL, "open", url, NULL, NULL, SW_NORMAL);
281
282 if (retval < 0 || retval > 32)
283 return TRUE;
284
285 errmsg = g_win32_error_message(retval);
286 DB( g_print ("%s\n", errmsg) );
287 g_free(errmsg);
288
289 return FALSE;
290 }
291
292 #else
293
294 static gboolean
295 homebank_util_url_show_unix (const gchar *url)
296 {
297 gboolean retval;
298 GError *err = NULL;
299
300 retval = gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (GLOBALS->mainwindow)), url, GDK_CURRENT_TIME, &err);
301
302 if (!retval)
303 {
304 ui_dialog_msg_infoerror(GTK_WINDOW(GLOBALS->mainwindow), GTK_MESSAGE_ERROR,
305 _("Browser error."),
306 _("Could not display the URL '%s'"),
307 url
308 );
309 }
310
311 if(err != NULL)
312 {
313 g_print ("%s\n", err->message);
314 g_error_free (err);
315 }
316
317 return retval;
318 }
319
320 #endif
321
322 gboolean
323 homebank_util_url_show (const gchar *url)
324 {
325
326 if(url == NULL)
327 return FALSE;
328
329
330 #ifdef G_OS_WIN32
331 return homebank_util_url_show_win32 (url);
332 #else
333 return homebank_util_url_show_unix (url);
334 #endif
335 }
336
337
338 /* = = = = = = = = = = = = = = = = = = = = */
339 /* lastopenedfiles */
340
341 /*
342 ** load lastopenedfiles from homedir/.homebank
343 */
344 gboolean homebank_lastopenedfiles_load(void)
345 {
346 GKeyFile *keyfile;
347 gboolean retval = FALSE;
348 gchar *group, *filename, *lastfilename;
349
350 DB( g_print("\n[homebank] lastopenedfiles load\n") );
351
352 keyfile = g_key_file_new();
353 if(keyfile)
354 {
355
356 filename = g_build_filename(homebank_app_get_config_dir(), "lastopenedfiles", NULL );
357
358 DB( g_print(" -> filename: %s\n", filename) );
359
360 if(g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, NULL))
361 {
362 group = "HomeBank";
363
364 DB( g_print(" -> load keyfile ok\n") );
365
366 if(g_key_file_has_key(keyfile, group, "LastOpenedFile", NULL))
367 {
368 DB( g_print(" -> keyfile has key ok\n") );
369
370 lastfilename = g_key_file_get_string (keyfile, group, "LastOpenedFile", NULL);
371
372 DB( g_print(" -> lastfile loaded: %s\n", lastfilename ) );
373 // #593082
374 if (g_file_test (lastfilename, G_FILE_TEST_EXISTS) != FALSE)
375 {
376 DB( g_print(" -> file exists\n") );
377
378 hbfile_change_filepath(lastfilename);
379
380 retval = TRUE;
381 }
382 }
383 }
384 g_free(filename);
385 g_key_file_free (keyfile);
386 }
387
388 DB( g_print(" -> return: %d\n", retval) );
389
390 return retval;
391 }
392
393
394 /*
395 ** save lastopenedfiles to homedir/.homebank (HB_DATA_PATH)
396 */
397 gboolean homebank_lastopenedfiles_save(void)
398 {
399 GKeyFile *keyfile;
400 gboolean retval = FALSE;
401 gchar *group, *filename;
402 gsize length;
403
404 DB( g_print("\n[homebank] lastopenedfiles save\n") );
405
406 if( GLOBALS->xhb_filepath != NULL )
407 {
408
409 keyfile = g_key_file_new();
410 if(keyfile )
411 {
412 group = "HomeBank";
413 g_key_file_set_string (keyfile, group, "LastOpenedFile", GLOBALS->xhb_filepath);
414
415 gchar *contents = g_key_file_to_data( keyfile, &length, NULL);
416
417 //DB( g_print(" keyfile:\n%s\nlen=%d\n", contents, length) );
418
419 filename = g_build_filename(homebank_app_get_config_dir(), "lastopenedfiles", NULL );
420 g_file_set_contents(filename, contents, length, NULL);
421 g_free(filename);
422
423 g_free(contents);
424 g_key_file_free (keyfile);
425 }
426 }
427
428 return retval;
429 }
430
431
432
433 /* = = = = = = = = = = = = = = = = = = = = */
434 /* Main homebank */
435
436
437
438 static void free_list_pixbuf(void)
439 {
440 guint i;
441
442 DB( g_print("\n[homebank] free_list_pixbuf\n") );
443
444 for(i=0;i<NUM_LST_PIXBUF;i++)
445 {
446 if(GLOBALS->lst_pixbuf[i] != NULL)
447 {
448 g_object_unref(GLOBALS->lst_pixbuf[i]);
449 }
450 }
451 }
452
453 static void load_list_pixbuf(void)
454 {
455 GdkPixbuf *pixbuf;
456 guint i;
457 GtkWidget *cellview;
458
459 DB( g_print("\n[homebank] load_list_pixbuf\n") );
460
461 cellview = gtk_cell_view_new ();
462
463 /* list added (account/transaction list) */
464 pixbuf = gtk_widget_render_icon (cellview, GTK_STOCK_NEW, GTK_ICON_SIZE_MENU, NULL);
465 //g_object_unref(pixbuf);
466 GLOBALS->lst_pixbuf[LST_PIXBUF_ADD] = pixbuf;
467
468 /* list scheduled (archive list) */
469 pixbuf = gtk_widget_render_icon (cellview, HB_STOCK_OPE_AUTO, GTK_ICON_SIZE_MENU, NULL);
470 //g_object_unref(pixbuf);
471 GLOBALS->lst_pixbuf[LST_PIXBUF_AUTO] = pixbuf;
472
473 /* list edited (account/transaction list) */
474 pixbuf = gtk_widget_render_icon (cellview, GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU, NULL);
475 //g_object_unref(pixbuf);
476 GLOBALS->lst_pixbuf[LST_PIXBUF_EDIT] = pixbuf;
477
478 /* list remind (transaction list) */
479 pixbuf = gtk_widget_render_icon (cellview, HB_STOCK_OPE_REMIND, GTK_ICON_SIZE_MENU, NULL);
480 //g_object_unref(pixbuf);
481 GLOBALS->lst_pixbuf[LST_PIXBUF_REMIND] = pixbuf;
482
483 /* list reconciled (transaction list) */
484 pixbuf = gtk_widget_render_icon (cellview, HB_STOCK_OPE_VALID, GTK_ICON_SIZE_MENU, NULL);
485 //g_object_unref(pixbuf);
486 GLOBALS->lst_pixbuf[LST_PIXBUF_VALID] = pixbuf;
487
488 /* list warning (import transaction list) */
489 pixbuf = gtk_widget_render_icon (cellview, GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU, NULL);
490 //g_object_unref(pixbuf);
491 GLOBALS->lst_pixbuf[LST_PIXBUF_WARNING] = pixbuf;
492
493 GLOBALS->lst_pixbuf_maxwidth = 0;
494 for(i=0;i<NUM_LST_PIXBUF;i++)
495 {
496 if( GLOBALS->lst_pixbuf[i] != NULL )
497 GLOBALS->lst_pixbuf_maxwidth = MAX(GLOBALS->lst_pixbuf_maxwidth, gdk_pixbuf_get_width(GLOBALS->lst_pixbuf[i]) );
498
499 }
500
501 DB( g_print(" -> pixbuf list maxwidth: %d\n", GLOBALS->lst_pixbuf_maxwidth) );
502
503 gtk_widget_destroy (cellview);
504
505 }
506
507
508 static void
509 homebank_register_stock_icons()
510 {
511 DB( g_print("\n[homebank] register_stock_icons\n") );
512
513 GtkIconFactory *factory;
514 GtkIconSet *icon_set;
515 GtkIconSource *icon_source;
516 guint i;
517
518 const char *icon_theme_items[] =
519 {
520 "hb-file-import",
521 "hb-file-export"
522 "pm-none",
523 "pm-ccard",
524 "pm-check",
525 "pm-cash" ,
526 "pm-transfer",
527 "pm-intransfer",
528 "pm-dcard",
529 "pm-standingorder",
530 "pm-epayment",
531 "pm-deposit",
532 "pm-fifee",
533 "pm-directdebit",
534 "flt-inactive",
535 "flt-include",
536 "flt-exclude",
537 HB_STOCK_OPE_VALID,
538 HB_STOCK_OPE_REMIND,
539 HB_STOCK_OPE_AUTO,
540 "prf-general",
541 "prf-interface",
542 "prf-columns",
543 "prf-display",
544 "prf-euro",
545 "prf-report",
546 "prf-import"
547 };
548
549 factory = gtk_icon_factory_new ();
550
551 for (i = 0; i < G_N_ELEMENTS (icon_theme_items); i++)
552 {
553 icon_source = gtk_icon_source_new ();
554 gtk_icon_source_set_icon_name (icon_source, icon_theme_items[i]);
555
556 icon_set = gtk_icon_set_new ();
557 gtk_icon_set_add_source (icon_set, icon_source);
558 gtk_icon_source_free (icon_source);
559
560 gtk_icon_factory_add (factory, icon_theme_items[i], icon_set);
561 gtk_icon_set_unref (icon_set);
562 }
563
564 //gtk_stock_add_static (icon_theme_items, G_N_ELEMENTS (icon_theme_items));
565
566 gtk_icon_factory_add_default (factory);
567 g_object_unref (factory);
568
569 #if MYDEBUG == 1
570 GtkIconTheme *ic = gtk_icon_theme_get_default();
571 gchar **paths;
572
573 DB( g_print(" -> get default icon theme\n") );
574
575 gtk_icon_theme_get_search_path(ic, &paths, NULL);
576 for(i=0;i<g_strv_length(paths);i++)
577 {
578 g_print("-> path %d: %s\n", i, paths[i]);
579 }
580
581 g_strfreev(paths);
582
583 #endif
584
585
586
587 DB( g_print(" -> adding theme search path: %s\n", homebank_app_get_pixmaps_dir()) );
588 gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), homebank_app_get_pixmaps_dir());
589 }
590
591 /*
592 void homebank_window_set_icon_from_file(GtkWindow *window, gchar *filename)
593 {
594 gchar *pathfilename;
595
596 pathfilename = g_build_filename(homebank_app_get_pixmaps_dir(), filename, NULL);
597 gtk_window_set_icon_from_file(GTK_WINDOW (window), pathfilename, NULL);
598 g_free(pathfilename);
599 }
600 */
601
602 const gchar *
603 homebank_app_get_config_dir (void)
604 {
605 return config_dir;
606 }
607
608 const gchar *
609 homebank_app_get_images_dir (void)
610 {
611 return images_dir;
612 }
613
614 const gchar *
615 homebank_app_get_pixmaps_dir (void)
616 {
617 return pixmaps_dir;
618 }
619
620 const gchar *
621 homebank_app_get_locale_dir (void)
622 {
623 return locale_dir;
624 }
625
626 const gchar *
627 homebank_app_get_help_dir (void)
628 {
629 return help_dir;
630 }
631
632 const gchar *
633 homebank_app_get_datas_dir (void)
634 {
635 return datas_dir;
636 }
637
638
639 /* build package paths at runtime */
640 static void
641 build_package_paths (void)
642 {
643 DB( g_print("\n[homebank] build_package_paths\n") );
644
645 #ifdef G_OS_WIN32
646 gchar *prefix;
647
648 prefix = g_win32_get_package_installation_directory_of_module (NULL);
649 locale_dir = g_build_filename (prefix, "share", "locale", NULL);
650 images_dir = g_build_filename (prefix, "share", PACKAGE, "images", NULL);
651 pixmaps_dir = g_build_filename (prefix, "share", PACKAGE, "icons", NULL);
652 help_dir = g_build_filename (prefix, "share", PACKAGE, "help", NULL);
653 datas_dir = g_build_filename (prefix, "share", PACKAGE, "datas", NULL);
654 #ifdef PORTABLE_APP
655 DB( g_print("- app is portable under windows\n") );
656 config_dir = g_build_filename(prefix, "config", NULL);
657 #else
658 config_dir = g_build_filename(g_get_user_config_dir(), HB_DATA_PATH, NULL);
659 #endif
660 g_free (prefix);
661 #else
662 locale_dir = g_build_filename (DATA_DIR, "locale", NULL);
663 images_dir = g_build_filename (SHARE_DIR, "images", NULL);
664 pixmaps_dir = g_build_filename (DATA_DIR, PACKAGE, "icons", NULL);
665 help_dir = g_build_filename (DATA_DIR, PACKAGE, "help", NULL);
666 datas_dir = g_build_filename (DATA_DIR, PACKAGE, "datas", NULL);
667 config_dir = g_build_filename(g_get_user_config_dir(), HB_DATA_PATH, NULL);
668
669 //#870023 Ubuntu packages the help files in "/usr/share/doc/homebank-data/help/" for some strange reason
670 if(! g_file_test(help_dir, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
671 {
672 g_free (help_dir);
673 help_dir = g_build_filename ("/usr", "share", "doc", "homebank-data", "help", NULL);
674 }
675 #endif
676
677 DB( g_print("- config_dir : %s\n", config_dir) );
678 DB( g_print("- images_dir : %s\n", images_dir) );
679 DB( g_print("- pixmaps_dir: %s\n", pixmaps_dir) );
680 DB( g_print("- locale_dir : %s\n", locale_dir) );
681 DB( g_print("- help_dir : %s\n", help_dir) );
682 DB( g_print("- datas_dir : %s\n", datas_dir) );
683
684 }
685
686
687 guint32 homebank_app_date_get_julian(void)
688 {
689 GDate *date;
690 //init global default value
691 date = g_date_new();
692 g_date_set_time_t(date, time(NULL));
693 GLOBALS->today = g_date_get_julian(date);
694 g_date_free(date);
695 return GLOBALS->today;
696 }
697
698
699 static gboolean homebank_check_app_dir_migrate_file(gchar *srcdir, gchar *dstdir, gchar *filename)
700 {
701 gchar *srcpath;
702 gchar *dstpath;
703 gchar *buffer;
704 gsize length;
705 //GError *error = NULL;
706 gboolean retval = FALSE;
707
708 DB( g_print("\n[homebank] check_app_dir_migrate_file\n") );
709
710 srcpath = g_build_filename(srcdir, filename, NULL );
711 dstpath = g_build_filename(dstdir, filename, NULL );
712
713 if (g_file_get_contents (srcpath, &buffer, &length, NULL))
714 {
715 if(g_file_set_contents(dstpath, buffer, length, NULL))
716 {
717 //g_print("sould remove %s\n", srcpath);
718 g_remove(srcpath);
719 retval = TRUE;
720 }
721 }
722
723 g_free(dstpath);
724 g_free(srcpath);
725
726 return retval;
727 }
728
729 /*
730 * check/create user home directory for .homebank (HB_DATA_PATH) directory
731 */
732 static void homebank_check_app_dir()
733 {
734 gchar *homedir;
735 const gchar *configdir;
736 gboolean exists;
737
738 DB( g_print("\n[homebank] check_app_dir\n") );
739
740 /* check if <userdir>/.config exist */
741 #ifndef G_OS_WIN32
742 configdir = g_get_user_config_dir();
743 DB( g_print("- check '%s' exists\n", configdir) );
744 if(!g_file_test(configdir, G_FILE_TEST_IS_DIR))
745 {
746 DB( g_print("- creating dir\n") );
747 g_mkdir(configdir, 0755);
748 }
749 #endif
750
751 /* check for XDG .config/homebank */
752 configdir = homebank_app_get_config_dir();
753 DB( g_print("- config_dir is: '%s'\n", configdir) );
754 exists = g_file_test(configdir, G_FILE_TEST_IS_DIR);
755 if(exists)
756 {
757 /* just update folder security */
758 DB( g_print("- chmod 0700\n") );
759 g_chmod(configdir, 0700);
760 GLOBALS->first_run = FALSE;
761 }
762 else
763 {
764 /* create the config dir */
765 DB( g_print("- create config_dir\n") );
766 g_mkdir(configdir, 0755);
767 g_chmod(configdir, 0700);
768
769 /* any old homedir configuration out there ? */
770 homedir = g_build_filename(g_get_home_dir (), ".homebank", NULL );
771 DB( g_print("- homedir is: '%s'\n", homedir) );
772
773 exists = g_file_test(homedir, G_FILE_TEST_IS_DIR);
774 if(exists)
775 {
776 gboolean f1, f2;
777 /* we must do the migration properly */
778 DB( g_print("- migrate old 2 files\n") );
779 f1 = homebank_check_app_dir_migrate_file(homedir, config_dir, "preferences");
780 f2 = homebank_check_app_dir_migrate_file(homedir, config_dir, "lastopenedfiles");
781 if(f1 && f2)
782 {
783 DB( g_print("- removing old dir\n") );
784 g_rmdir(homedir);
785 }
786 }
787 g_free(homedir);
788 GLOBALS->first_run = TRUE;
789 }
790
791 }
792
793
794 /*
795 ** application cleanup: icons, GList, memory
796 */
797 static void homebank_cleanup()
798 {
799
800 DB( g_print("\n\n[homebank] cleanup\n") );
801
802 //v3.4 save windows size/position
803 homebank_pref_save();
804
805 free_list_pixbuf();
806 free_paymode_icons();
807 free_nainex_icons();
808 free_pref_icons();
809
810 hbfile_cleanup(TRUE);
811
812 /* free our global datas */
813 if( PREFS )
814 {
815 homebank_pref_free();
816 g_free(PREFS);
817 }
818
819 if(GLOBALS)
820 {
821 g_free(GLOBALS);
822 }
823
824 g_free (config_dir);
825 g_free (images_dir);
826 g_free (pixmaps_dir);
827 g_free (locale_dir);
828 g_free (help_dir);
829
830 }
831
832
833
834 /*
835 ** application setup: icons, GList, memory
836 */
837 static gboolean homebank_setup()
838 {
839
840 DB( g_print("\n[homebank] setup\n") );
841
842 GLOBALS = g_malloc0(sizeof(struct HomeBank));
843 if(!GLOBALS) return FALSE;
844 PREFS = g_malloc0(sizeof(struct Preferences));
845 if(!PREFS) return FALSE;
846
847 // check homedir for .homebank dir
848 homebank_check_app_dir();
849
850 homebank_pref_setdefault();
851 homebank_pref_load();
852
853 hbfile_setup(TRUE);
854
855 homebank_register_stock_icons();
856
857 load_list_pixbuf();
858 load_paymode_icons();
859 load_nainex_icons();
860 load_pref_icons();
861
862 homebank_app_date_get_julian();
863
864
865 #if MYDEBUG == 1
866
867 g_print("- user_name: %s\n", g_get_user_name ());
868 g_print("- real_name: %s\n", g_get_real_name ());
869 g_print("- user_cache_dir: %s\n", g_get_user_cache_dir());
870 g_print("- user_data_dir: %s\n", g_get_user_data_dir ());
871 g_print("- user_config_dir: %s\n", g_get_user_config_dir ());
872 //g_print("- system_data_dirs: %s\n", g_get_system_data_dirs ());
873 //g_print("- system_config_dirs: %s\n", g_get_system_config_dirs ());
874
875 g_print("- home_dir: %s\n", g_get_home_dir ());
876 g_print("- tmp_dir: %s\n", g_get_tmp_dir ());
877 g_print("- current_dir: %s\n", g_get_current_dir ());
878
879 #endif
880
881 return TRUE;
882 }
883
884
885 /* = = = = = = = = = = = = = = = = = = = = */
886 /* Main homebank */
887
888 static GtkWidget *
889 homebank_construct_splash()
890 {
891 GtkWidget *window;
892 GtkWidget *frame, *vbox, *image;
893 //gchar *ver_string, *markup, *version;
894 gchar *pathfilename;
895
896 DB( g_print("[homebank_construct_splash]\n") );
897
898 window = gtk_window_new(GTK_WINDOW_POPUP); //TOPLEVEL DONT WORK
899 gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
900 gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
901
902 gtk_window_set_title (GTK_WINDOW (window), "HomeBank");
903 gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
904
905 pathfilename = g_build_filename(homebank_app_get_images_dir(), "splash.png", NULL);
906 image = gtk_image_new_from_file((const gchar *)pathfilename);
907 g_free(pathfilename);
908
909 frame = gtk_frame_new (NULL);
910 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
911 gtk_container_add (GTK_CONTAINER (window), frame);
912
913 vbox = gtk_vbox_new (FALSE, 0);
914 gtk_container_add (GTK_CONTAINER (frame), vbox);
915
916 /*
917 ver_string = g_strdup_printf(_("Version: HomeBank-%s"), VERSION);
918
919 version = gtk_label_new(NULL);
920 markup = g_markup_printf_escaped(MARKUP_STRING, ver_string);
921 gtk_label_set_markup(GTK_LABEL(version), markup);
922 g_free(markup);
923 g_free(ver_string);
924 */
925
926 gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
927 //gtk_box_pack_start (GTK_BOX (vbox), version, FALSE, FALSE, 0);
928
929 return window;
930 }
931
932 static void
933 homebank_init_i18n (void)
934 {
935 /* We may change the locale later if the user specifies a language
936 * in the gimprc file. Here we are just initializing the locale
937 * according to the environment variables and set up the paths to
938 * the message catalogs.
939 */
940
941 setlocale (LC_ALL, "");
942
943 bindtextdomain (GETTEXT_PACKAGE, homebank_app_get_locale_dir ());
944 //#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
945 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
946 //#endif
947
948 textdomain (GETTEXT_PACKAGE);
949
950 /*#ifdef G_OS_WIN32
951 gchar *wl = g_win32_getlocale ();
952 DB( g_print(" -> win32 locale is '%s'\n", wl) );
953 g_free(wl);
954 #endif*/
955
956 }
957
958
959 int
960 main (int argc, char *argv[])
961 {
962 GOptionContext *option_context;
963 GOptionGroup *option_group;
964 GError *error = NULL;
965 GtkWidget *mainwin;
966 GtkWidget *splash = NULL;
967 gboolean openlast;
968
969 DB( g_print("\n--------------------------------" ) );
970 DB( g_print("\nhomebank starting...\n" ) );
971
972 build_package_paths();
973
974 homebank_init_i18n ();
975
976 /* Set up option groups */
977 option_context = g_option_context_new (NULL);
978
979 //g_option_context_set_summary (option_context, _(""));
980
981 option_group = g_option_group_new ("homebank",
982 N_("HomeBank options"),
983 N_("HomeBank options"),
984 NULL, NULL);
985 g_option_group_add_entries (option_group, option_entries);
986 g_option_context_set_main_group (option_context, option_group);
987 g_option_group_set_translation_domain (option_group, GETTEXT_PACKAGE);
988
989 /* Add Gtk option group */
990 g_option_context_add_group (option_context, gtk_get_option_group (FALSE));
991
992 /* Parse command line */
993 if (!g_option_context_parse (option_context, &argc, &argv, &error))
994 {
995 g_option_context_free (option_context);
996
997 if (error)
998 {
999 g_print ("%s\n", error->message);
1000 g_error_free (error);
1001 }
1002 else
1003 g_print ("An unknown error occurred\n");
1004
1005 return -1;
1006 }
1007
1008 g_option_context_free (option_context);
1009 option_context = NULL;
1010
1011 if (arg_version != FALSE)
1012 {
1013 /* Print version information and exit */
1014 g_print ("%s\n", PACKAGE " " VERSION);
1015 return 0;
1016 }
1017
1018 /* Pass NULL here since we parsed the gtk+ args already...
1019 * from this point all we need a DISPLAY variable to be set.
1020 */
1021 gtk_init (NULL, NULL);
1022
1023 //todo: sanity check gtk version here ?
1024
1025 g_set_application_name (APPLICATION_NAME);
1026
1027 if( homebank_setup() )
1028 {
1029 /* change the locale if a language is specified */
1030 language_init (PREFS->language);
1031
1032 if( PREFS->showsplash == TRUE )
1033 {
1034 splash = homebank_construct_splash();
1035 gtk_window_set_auto_startup_notification (FALSE);
1036 gtk_widget_show_all (splash);
1037 gtk_window_set_auto_startup_notification (TRUE);
1038
1039 // make sure splash is up
1040 while (gtk_events_pending ())
1041 gtk_main_iteration ();
1042 }
1043
1044 /*
1045 pathfilename = g_build_filename(homebank_app_get_pixmaps_dir(), "homebank.svg", NULL);
1046 gtk_window_set_default_icon_from_file(pathfilename, NULL);
1047 g_free(pathfilename);
1048 */
1049
1050 gtk_window_set_default_icon_name ("homebank");
1051
1052 DB( g_print(" -> creating window\n" ) );
1053
1054
1055 mainwin = (GtkWidget *)create_hbfile_window (NULL);
1056
1057 if(mainwin)
1058 {
1059
1060 //todo: pause on splash
1061 if( PREFS->showsplash == TRUE )
1062 {
1063 //g_usleep( G_USEC_PER_SEC * 1 );
1064 gtk_widget_hide(splash);
1065 gtk_widget_destroy(splash);
1066 }
1067
1068
1069 #if HB_UNSTABLE == TRUE
1070 /* GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(mainwin),
1071 GTK_DIALOG_DESTROY_WITH_PARENT,
1072 GTK_MESSAGE_WARNING,
1073 GTK_BUTTONS_CLOSE,
1074 "This is a beta version of HomeBank (UNSTABLE)"
1075 );
1076
1077 gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
1078 "DO NOT USE with important files or do a backup first.\n"
1079 "This kind of release is for <b>TESTING ONLY</b>.\n"
1080 "<u>It may be buggy, crash, or lose your data</u>.\n\n"
1081
1082 "For unstable bugs report, questions, suggestions:\n"
1083 " - <b>DO NOT USE LaunchPad</b>\n"
1084 " - direct email to: &lt;homebank@free.fr&gt;\n\n"
1085
1086 "<i>Thanks !</i>"
1087 );
1088
1089 gtk_dialog_run (GTK_DIALOG (dialog));
1090 gtk_widget_destroy (dialog);*/
1091 #endif
1092
1093 if(GLOBALS->first_run)
1094 {
1095 ui_mainwindow_action_help_welcome();
1096 }
1097
1098
1099 while (gtk_events_pending ()) /* make sure splash is gone */
1100 gtk_main_iteration ();
1101
1102
1103 DB( g_print(" -> open last file ?\n" ) );
1104
1105 // load a file ?
1106 /* load 1st file specified on commandline */
1107 openlast = PREFS->loadlast;
1108 if (files != NULL)
1109 {
1110 if (g_file_test (files[0], G_FILE_TEST_EXISTS) != FALSE)
1111 {
1112 DB( g_print(" -> should load %s\n", files[0] ) );
1113 hbfile_change_filepath(g_strdup(files[0]));
1114 ui_mainwindow_open_internal(mainwin, NULL);
1115 openlast = FALSE;
1116 }
1117 else
1118 {
1119 g_warning (_("Unable to open '%s', the file does not exist.\n"), files[0]);
1120
1121 }
1122 g_strfreev (files);
1123 }
1124
1125
1126 DB( g_print(" -> GLOBALS->xhb_filepath: '%s'\n", GLOBALS->xhb_filepath ) );
1127
1128 if( openlast )
1129 {
1130 if( homebank_lastopenedfiles_load() == TRUE )
1131 ui_mainwindow_open_internal(mainwin, NULL);
1132 }
1133
1134 /* update the mainwin display */
1135 ui_mainwindow_update(mainwin, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_BALANCE+UF_VISUAL));
1136
1137 DB( g_print(" -> gtk_main()\n" ) );
1138
1139 gtk_main ();
1140 }
1141
1142 }
1143
1144
1145 homebank_cleanup();
1146
1147 return EXIT_SUCCESS;
1148 }
1149
1150 #ifdef G_OS_WIN32
1151 /* In case we build this as a windowed application */
1152
1153 #ifdef __GNUC__
1154 #define _stdcall __attribute__((stdcall))
1155 #endif
1156
1157 int _stdcall
1158 WinMain (struct HINSTANCE__ *hInstance,
1159 struct HINSTANCE__ *hPrevInstance,
1160 char *lpszCmdLine,
1161 int nCmdShow)
1162 {
1163 return main (__argc, __argv);
1164 }
1165 #endif
1166
This page took 0.106511 seconds and 4 git commands to generate.