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