void traitement_sigsegv ( gint signal_nb ) { gchar *gsb_file_default_dir; gchar *errmsg = g_strdup ( "" ); gchar *old_errmsg; gchar *tmpstr; GtkWidget * dialog; #ifdef HAVE_BACKTRACE GtkWidget * expander; #endif /* il y a 3 possibilités : */ /* soit on était en train de charger un fichier, c'est que celui-ci est corrompu */ /* soit on était en train de sauver un fichier, et là on peut rien faire */ /* sinon on essaie de sauver le fichier sous le nom entouré de # */ if ( run.is_loading || run.is_saving || !gsb_file_get_modified ( ) ) { if ( run.is_loading ) { old_errmsg = errmsg; errmsg = g_strconcat ( errmsg, _("File is corrupted."), NULL ); g_free ( old_errmsg ); } if ( run.is_saving ) { old_errmsg = errmsg; errmsg = g_strconcat ( errmsg, _("Error occured saving file."), NULL ); g_free ( old_errmsg ); } } else { /* c'est un bug pendant le fonctionnement de Grisbi s'il n'y a pas de nom de fichier, on le crée, sinon on rajoute # autour */ gsb_file_default_dir = (gchar *) my_get_gsb_file_default_dir(); if ( nom_fichier_comptes ) /* set # around the filename */ nom_fichier_comptes = g_path_get_basename (nom_fichier_comptes); else /* no name for the file, create it */ nom_fichier_comptes = g_strconcat ( gsb_file_default_dir, "/#grisbi_crash_no_name#", NULL ); gsb_status_message ( _("Save file") ); gsb_file_save_save_file ( nom_fichier_comptes, conf.compress_file, FALSE ); gsb_status_clear(); old_errmsg = errmsg; errmsg = g_strconcat ( errmsg, g_strdup_printf ( _("Grisbi made a backup file at '%s'."), nom_fichier_comptes ), NULL ); g_free ( old_errmsg ); } old_errmsg = errmsg; errmsg = g_strconcat ( errmsg, "\n\n", _("Please report this problem to <tt>http://www.grisbi.org/bugtracking/</tt>. "), NULL ); g_free ( old_errmsg ); #ifdef HAVE_BACKTRACE old_errmsg = errmsg; errmsg = g_strconcat ( errmsg, _("Copy and paste the following backtrace with your bug " "report."), NULL ); g_free ( old_errmsg ); #endif dialog = dialogue_special_no_run ( GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, make_hint ( _("Grisbi terminated due to a segmentation fault."), errmsg )); g_free ( errmsg ); #ifdef HAVE_BACKTRACE tmpstr = g_strconcat ( "<b>", _("Backtrace"), "</b>", NULL ); expander = gtk_expander_new ( tmpstr ); g_free ( tmpstr ); gtk_expander_set_use_markup ( GTK_EXPANDER ( expander ), TRUE ); gtk_container_add ( GTK_CONTAINER ( expander ), print_backtrace() ); gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG(dialog)->vbox ), expander, FALSE, FALSE, 6 ); gtk_widget_show_all ( dialog ); #endif gtk_dialog_run ( GTK_DIALOG ( dialog ) ); /* on évite le message du fichier ouvert à la prochaine ouverture */ gsb_file_util_modify_lock ( FALSE ); exit(1); }
/** * propose to save the file if changed * if the current file is not changed, return GTK_RESPONSE_NO directly, without dialog * * \param * * \return GTK_RESPONSE_OK to save, GTK_RESPONSE_NO not to save, other to cancel * */ static gint gsb_file_dialog_save ( void ) { gchar * hint; gchar* time_elapsed; time_t now = time ( NULL ); gint result; GtkWidget *dialog; gint difference = (gint) difftime ( now, run.file_modification ); gchar* message; gchar* tmpstr1; gchar* tmpstr2; /* si le fichier n'est pas modifié on renvoie qu'on ne veut pas enregistrer */ if ( ! gsb_file_get_modified ( ) ) return GTK_RESPONSE_NO; if ( conf.sauvegarde_auto && ( !etat.fichier_deja_ouvert || conf.force_enregistrement ) && nom_fichier_comptes ) return GTK_RESPONSE_OK; /* si le fichier était déjà locké et que force enregistrement n'est pas mis, */ /* on prévient ici */ dialog = gtk_message_dialog_new ( GTK_WINDOW ( run.window ), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, " " ); if ( etat.fichier_deja_ouvert && !conf.force_enregistrement ) { hint = g_strdup(_("Save locked files?")); message = g_strdup_printf ( _("The document '%s' is locked but modified. If you want to save it, you must cancel and save it with another name or activate the \"%s\" option in setup."), (nom_fichier_comptes ? g_path_get_basename(nom_fichier_comptes) : _("unnamed")), _("Force saving of locked files")); gtk_dialog_add_buttons ( GTK_DIALOG(dialog), _("Close without saving"), GTK_RESPONSE_NO, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL ); gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL ); } else { hint = g_strdup_printf (_("Save changes to document '%s' before closing?"), (nom_fichier_comptes ? g_path_get_basename(nom_fichier_comptes) : _("unnamed"))); message = g_strdup(""); gtk_dialog_add_buttons ( GTK_DIALOG(dialog), _("Close without saving"), GTK_RESPONSE_NO, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL ); gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_OK ); } if ( difference >= 120 ) { time_elapsed = g_strdup_printf ( _( "%d minutes and %d seconds" ), difference / 60, difference % 60 ); } else if ( difference >= 60 ) { time_elapsed = g_strdup_printf ( _( "1 minute and %d seconds" ), difference % 60 ); } else { time_elapsed = g_strdup_printf ( _( "%d seconds" ), difference ); } tmpstr1 = message; tmpstr2 = g_strdup_printf ( _("If you close without saving, all of your changes " "since %s will be discarded."), time_elapsed ); message = g_strconcat ( tmpstr1, tmpstr2 , NULL ); g_free ( tmpstr1 ); g_free ( tmpstr2 ); g_free ( time_elapsed ); gtk_label_set_markup ( GTK_LABEL ( GTK_MESSAGE_DIALOG(dialog)->label ), make_hint ( hint, message ) ); g_free ( message ); g_free ( hint ); gtk_window_set_modal ( GTK_WINDOW ( dialog ), TRUE ); result = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy ( dialog ); return result; }
/** * save the file * * \param origine 0 from gsb_file_save (menu), -1 from gsb_file_close, -2 from gsb_file_save_as * * \return TRUE if ok, FALSE if problem * */ gboolean gsb_file_save_file ( gint origine ) { gint etat_force, result; gchar *nouveau_nom_enregistrement; devel_debug_int (origine); etat_force = 0; if ( ( !gsb_file_get_modified ( ) && origine != -2 ) || !gsb_data_account_get_accounts_amount () ) { notice_debug ( "nothing done in gsb_file_save_file" ); return ( TRUE ); } /* si le fichier de comptes n'a pas de nom ou si on enregistre sous un nouveau nom */ /* c'est ici */ if ( !nom_fichier_comptes || origine == -2 ) nouveau_nom_enregistrement = gsb_file_dialog_ask_name (); else nouveau_nom_enregistrement = nom_fichier_comptes; if ( !nouveau_nom_enregistrement ) return FALSE; /* on vérifie que le fichier n'est pas locké */ if ( etat.fichier_deja_ouvert && !conf.force_enregistrement && origine != -2 ) { gchar* tmpstr1 = g_strdup_printf( _("Grisbi was unable to save this file because it is locked. Please save it with another name or activate the \"%s\" option in preferences."), _("Force saving of locked files" ) ); gchar* tmpstr2 = g_strdup_printf( _("Can not save file \"%s\""), nom_fichier_comptes ); dialogue_error_hint ( tmpstr1, tmpstr2 ); g_free ( tmpstr1 ); g_free ( tmpstr2 ); return ( FALSE ); } /* Si le fichier est un d'une version précédente de grisbi on demande si on l'efface */ if ( copy_old_filename && strlen ( copy_old_filename ) > 0 ) { gsb_file_save_remove_old_file ( copy_old_filename ); g_free ( copy_old_filename ); copy_old_filename = NULL; } /* make backup before saving if asked */ if (conf.make_backup) gsb_file_save_backup(); /* on a maintenant un nom de fichier */ /* et on sait qu'on peut sauvegarder */ gsb_status_message ( _("Saving file") ); result = gsb_file_save_save_file ( nouveau_nom_enregistrement, conf.compress_file, FALSE ); if ( result ) { /* saving was right, so unlock the last name */ gsb_file_util_modify_lock ( FALSE ); nom_fichier_comptes = nouveau_nom_enregistrement; /* and lock the new name */ gsb_file_util_modify_lock ( TRUE ); /* update variables */ etat.fichier_deja_ouvert = 0; gsb_file_set_modified ( FALSE ); gsb_main_set_grisbi_title ( gsb_gui_navigation_get_current_account ( ) ); gsb_file_append_name_to_opened_list ( nom_fichier_comptes ); } gsb_status_message ( _("Done") ); return ( result ); }
/** * save a backup of the file * * \param * * \return TRUE ok, FALSE problem * */ gboolean gsb_file_save_backup ( void ) { gboolean retour; gchar *filename; struct tm *day_time; time_t temps; gchar *name; if (!gsb_file_get_backup_path () || !gsb_file_get_modified ( ) ) return FALSE; gsb_status_message ( _("Saving backup") ); name = g_path_get_basename (nom_fichier_comptes); if ( g_str_has_suffix ( name, ".gsb" ) ) { gchar **tab_str; tab_str = g_strsplit ( name, ".gsb", 0 ); if ( tab_str[0] && strlen ( tab_str[0] ) ) { g_free ( name ); name = g_strdup ( tab_str[0] ); } g_strfreev ( tab_str ); } /* create a filename for the backup : * filename_yyyymmddTmmhhss.gsb */ if ( conf.make_bakup_single_file ) { filename = g_strdup_printf ( "%s%s%s_backup.gsb", gsb_file_get_backup_path ( ), G_DIR_SEPARATOR_S, name ); } else { time ( &temps ); day_time = localtime (&temps); filename = g_strdup_printf ( "%s%s%s_%d%02d%02dT%02d%02d%02d.gsb", gsb_file_get_backup_path (), G_DIR_SEPARATOR_S, name, day_time -> tm_year + 1900, day_time -> tm_mon + 1, day_time -> tm_mday, day_time -> tm_hour, day_time -> tm_min, day_time -> tm_sec ); } retour = gsb_file_save_save_file ( filename, conf.compress_backup, FALSE ); g_free (filename); g_free (name); gsb_status_message ( _("Done") ); return ( retour ); }
/** * open a new grisbi file, don't check anything about another opened file that must * have been done before * * \para filename the name of the file * * \return TRUE ok, FALSE problem * */ gboolean gsb_file_open_file ( gchar *filename ) { GSList *list_tmp; devel_debug (filename); if ( !filename || !strlen (filename)) return FALSE; gsb_status_wait ( TRUE ); gsb_status_message ( _("Loading accounts") ); /* try to load the file */ /* FIXME:BUG under Windows: for unknwon reason yet filename is cleared * when returning from gsb_file_load_open_file! * making application crashes! */ if ( gsb_file_load_open_file (filename)) { /* the file has been opened succesfully */ /* we make a backup if necessary */ if ( conf.sauvegarde_demarrage ) { gsb_file_save_backup (); gsb_file_set_modified ( FALSE ); } } else { /* Loading failed. */ gsb_status_message ( _("Failed to load accounts") ); if ( conf.sauvegarde_demarrage || conf.make_backup || conf.make_backup_every_minutes ) { gchar *tmpstr = g_strdup_printf ( _("Error loading file '%s'"), filename); gchar *tmpstr2 = g_strdup_printf ( _("Grisbi was unable to load file. You should find the last " "backups in '%s', they are saved with date and time into " "their name so you should find easily the last backup " "saved.\n" "Please contact the Grisbi's team on [email protected] " "to find what happened to you current file."), gsb_file_get_backup_path ()); dialogue_error_hint ( tmpstr2, tmpstr ); g_free ( tmpstr ); g_free ( tmpstr2 ); gsb_status_stop_wait ( TRUE ); return FALSE; } else { gchar *tmpstr = g_strdup_printf ( _("Error loading file '%s'"), filename); gchar *tmpstr2; if (gsb_file_get_backup_path ()) tmpstr2 = g_strdup_printf ( _("Grisbi was unable to load file and the backups seem not to " "be activated... This is a bad thing.\nYour backup path is '%s', " "try to find if earlier you had some backups in there ?\n" "Please contact the Grisbi's team on [email protected] " "to find what happened to you current file."), gsb_file_get_backup_path ()); else tmpstr2 = my_strdup ( _("Grisbi was unable to load file and the backups seem not " "to be activated... This is a bad thing.\n" "Please contact the Grisbi's team on " "[email protected] to find what happened to you " "current file.")); dialogue_error_hint ( tmpstr2, tmpstr ); g_free ( tmpstr ); g_free ( tmpstr2 ); gsb_status_stop_wait ( TRUE ); return FALSE; } } /* ok, here the file or backup is loaded */ gsb_status_message ( _("Checking schedulers")); /* the the name in the last opened files */ gsb_file_append_name_to_opened_list ( filename ); /* create the archives store data, ie the transaction wich will replace the archive in * the list of transactions */ gsb_data_archive_store_create_list (); /* create all the gui */ gsb_file_new_gui (); /* check the amounts of all the accounts */ gsb_status_message ( _("Checking amounts")); list_tmp = gsb_data_account_get_list_accounts (); while ( list_tmp ) { gint account_number; volatile gint value; account_number = gsb_data_account_get_no_account ( list_tmp -> data ); /* set the minimum balances to be shown or not */ value = gsb_real_cmp ( gsb_data_account_get_current_balance (account_number), gsb_data_account_get_mini_balance_authorized (account_number) ) == -1; gsb_data_account_set_mini_balance_authorized_message ( account_number, value); value = gsb_real_cmp ( gsb_data_account_get_current_balance (account_number), gsb_data_account_get_mini_balance_wanted (account_number) ) == -1; gsb_data_account_set_mini_balance_wanted_message ( account_number, value); list_tmp = list_tmp -> next; } /* set Grisbi title */ gsb_main_set_grisbi_title ( -1 ); /* update the main page */ mise_a_jour_accueil (TRUE); /* for now, the flag for modification of the file is ok, but the menu couldn't be set * as sensitive/unsensitive so do it now */ gsb_file_set_modified ( gsb_file_get_modified ( ) ); gsb_status_message ( _("Done") ); gsb_status_stop_wait ( TRUE ); /* go to the home page */ gsb_gui_navigation_set_selection ( GSB_HOME_PAGE, -1, NULL ); /* set the focus to the selection tree at left */ gtk_widget_grab_focus ( gsb_gui_navigation_get_tree_view ( ) ); return TRUE; }