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