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