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