25 #include <glib/gi18n.h> 29 #include "dialog-utils.h" 30 #include "assistant-xml-encoding.h" 32 #include "gnc-component-manager.h" 39 #include "gnc-gui-query.h" 40 #include "gnc-hooks.h" 42 #include "gnc-splash.h" 44 #include "gnc-ui-balances.h" 51 #include "ScrubBudget.h" 53 #include "gnc-session.h" 55 #include "gnc-autosave.h" 61 static QofLogModule log_module = GNC_MOD_GUI;
63 static GNCShutdownCB shutdown_cb = NULL;
64 static gint save_in_progress = 0;
68 gnc_file_dialog_int (GtkWindow *parent,
71 const char * starting_dir,
72 GNCFileDialogType type,
77 char *file_name = NULL;
78 gchar * okbutton = NULL;
79 const gchar *ok_icon = NULL;
80 GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
82 GSList* file_name_list = NULL;
88 case GNC_FILE_DIALOG_OPEN:
89 action = GTK_FILE_CHOOSER_ACTION_OPEN;
90 okbutton = _(
"_Open");
94 case GNC_FILE_DIALOG_IMPORT:
95 action = GTK_FILE_CHOOSER_ACTION_OPEN;
96 okbutton = _(
"_Import");
100 case GNC_FILE_DIALOG_SAVE:
101 action = GTK_FILE_CHOOSER_ACTION_SAVE;
102 okbutton = _(
"_Save");
106 case GNC_FILE_DIALOG_EXPORT:
107 action = GTK_FILE_CHOOSER_ACTION_SAVE;
108 okbutton = _(
"_Export");
116 file_box = gtk_file_chooser_dialog_new(
120 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
123 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (file_box), TRUE);
126 gnc_gtk_dialog_add_button(file_box, okbutton, ok_icon, GTK_RESPONSE_ACCEPT);
128 gtk_dialog_add_button(GTK_DIALOG(file_box),
129 okbutton, GTK_RESPONSE_ACCEPT);
132 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_box),
135 gtk_window_set_modal(GTK_WINDOW(file_box), TRUE);
140 GtkFileFilter* all_filter = gtk_file_filter_new();
142 for (filter = filters; filter; filter = filter->next)
144 g_return_val_if_fail(GTK_IS_FILE_FILTER(filter->data), NULL);
145 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_box),
146 GTK_FILE_FILTER (filter->data));
149 gtk_file_filter_set_name (all_filter, _(
"All files"));
150 gtk_file_filter_add_pattern (all_filter,
"*");
151 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_box), all_filter);
157 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (file_box),
158 GTK_FILE_FILTER (filters->data));
159 g_list_free (filters);
162 response = gtk_dialog_run(GTK_DIALOG(file_box));
165 gtk_widget_set_name (GTK_WIDGET(file_box),
"gnc-id-file");
167 if (response == GTK_RESPONSE_ACCEPT)
171 file_name_list = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (file_box));
176 file_name = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER (file_box));
177 if (file_name != NULL)
179 if (strstr (file_name,
"file://") == file_name)
183 file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_box));
185 file_name_list = g_slist_append (file_name_list, file_name);
189 gtk_widget_destroy(GTK_WIDGET(file_box));
190 LEAVE(
"%s", file_name ? file_name :
"(null)");
191 return file_name_list;
209 gnc_file_dialog (GtkWindow *parent,
212 const char * starting_dir,
213 GNCFileDialogType type
216 gchar* file_name = NULL;
217 GSList* ret = gnc_file_dialog_int (parent, title, filters, starting_dir, type, FALSE);
219 file_name = g_strdup (ret->data);
220 g_slist_free_full (ret, g_free);
239 gnc_file_dialog_multi (GtkWindow *parent,
242 const char * starting_dir,
243 GNCFileDialogType type
246 return gnc_file_dialog_int (parent, title, filters, starting_dir, type, TRUE);
250 show_session_error (GtkWindow *parent,
253 GNCFileDialogType type)
256 gboolean uh_oh = TRUE;
257 const char *fmt, *label;
263 displayname = g_strdup(_(
"(null)"));
277 case ERR_BACKEND_NO_ERR:
282 fmt = _(
"No suitable backend was found for %s.");
283 gnc_error_dialog(parent, fmt, displayname);
287 fmt = _(
"The URL %s is not supported by this version of GnuCash.");
288 gnc_error_dialog (parent, fmt, displayname);
292 fmt = _(
"Can't parse the URL %s.");
293 gnc_error_dialog (parent, fmt, displayname);
297 fmt = _(
"Can't connect to %s. " 298 "The host, username or password were incorrect.");
299 gnc_error_dialog (parent, fmt, displayname);
303 fmt = _(
"Can't connect to %s. " 304 "Connection was lost, unable to send data.");
305 gnc_error_dialog (parent, fmt, displayname);
309 fmt = _(
"This file/URL appears to be from a newer version " 310 "of GnuCash. You must upgrade your version of GnuCash " 311 "to work with this data.");
312 gnc_error_dialog (parent,
"%s", fmt);
316 fmt = _(
"The database %s doesn't seem to exist. " 317 "Do you want to create it?");
318 if (gnc_verify_dialog (parent, TRUE, fmt, displayname))
327 case GNC_FILE_DIALOG_OPEN:
330 fmt = _(
"GnuCash could not obtain the lock for %s. " 331 "That database may be in use by another user, " 332 "in which case you should not open the database. " 333 "Do you want to proceed with opening the database?");
336 case GNC_FILE_DIALOG_IMPORT:
338 fmt = _(
"GnuCash could not obtain the lock for %s. " 339 "That database may be in use by another user, " 340 "in which case you should not import the database. " 341 "Do you want to proceed with importing the database?");
344 case GNC_FILE_DIALOG_SAVE:
346 fmt = _(
"GnuCash could not obtain the lock for %s. " 347 "That database may be in use by another user, " 348 "in which case you should not save the database. " 349 "Do you want to proceed with saving the database?");
352 case GNC_FILE_DIALOG_EXPORT:
354 fmt = _(
"GnuCash could not obtain the lock for %s. " 355 "That database may be in use by another user, " 356 "in which case you should not export the database. " 357 "Do you want to proceed with exporting the database?");
361 dialog = gtk_message_dialog_new(parent,
362 GTK_DIALOG_DESTROY_WITH_PARENT,
363 GTK_MESSAGE_QUESTION,
367 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
368 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
369 label, GTK_RESPONSE_YES,
372 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
373 response = gtk_dialog_run(GTK_DIALOG(dialog));
374 gtk_widget_destroy(dialog);
375 uh_oh = (response != GTK_RESPONSE_YES);
379 fmt = _(
"GnuCash could not write to %s. " 380 "That database may be on a read-only file system, " 381 "you may not have write permission for the directory " 382 "or your anti-virus software is preventing this action.");
383 gnc_error_dialog (parent, fmt, displayname);
387 fmt = _(
"The file/URL %s " 388 "does not contain GnuCash data or the data is corrupt.");
389 gnc_error_dialog (parent, fmt, displayname);
393 fmt = _(
"The server at URL %s " 394 "experienced an error or encountered bad or corrupt data.");
395 gnc_error_dialog (parent, fmt, displayname);
399 fmt = _(
"You do not have permission to access %s.");
400 gnc_error_dialog (parent, fmt, displayname);
404 fmt = _(
"An error occurred while processing %s.");
405 gnc_error_dialog (parent, fmt, displayname);
409 fmt = _(
"There was an error reading the file. " 410 "Do you want to continue?");
411 if (gnc_verify_dialog (parent, TRUE,
"%s", fmt))
418 fmt = _(
"There was an error parsing the file %s.");
419 gnc_error_dialog (parent, fmt, displayname);
423 fmt = _(
"The file %s is empty.");
424 gnc_error_dialog (parent, fmt, displayname);
428 if (type == GNC_FILE_DIALOG_SAVE)
436 fmt = _(
"The file/URI %s could not be found.\n\nThe file is in the history list, do you want to remove it?");
437 if (gnc_verify_dialog (parent, FALSE, fmt, displayname))
442 fmt = _(
"The file/URI %s could not be found.");
443 gnc_error_dialog (parent, fmt, displayname);
449 fmt = _(
"This file is from an older version of GnuCash. " 450 "Do you want to continue?");
451 if (gnc_verify_dialog (parent, TRUE,
"%s", fmt))
458 fmt = _(
"The file type of file %s is unknown.");
459 gnc_error_dialog(parent, fmt, displayname);
463 fmt = _(
"Could not make a backup of the file %s");
464 gnc_error_dialog(parent, fmt, displayname);
468 fmt = _(
"Could not write to file %s. Check that you have " 469 "permission to write to this file and that " 470 "there is sufficient space to create it.");
471 gnc_error_dialog(parent, fmt, displayname);
475 fmt = _(
"No read permission to read from file %s.");
476 gnc_error_dialog (parent, fmt, displayname);
482 fmt = _(
"You attempted to save in\n%s\nor a subdirectory thereof. " 483 "This is not allowed as %s reserves that directory for internal use.\n\n" 484 "Please try again in a different directory.");
489 fmt = _(
"This database is from an older version of GnuCash. " 490 "Select OK to upgrade it to the current version, Cancel " 491 "to mark it read-only.");
493 response = gnc_ok_cancel_dialog(parent, GTK_RESPONSE_CANCEL,
"%s", fmt);
494 uh_oh = (response == GTK_RESPONSE_CANCEL);
498 fmt = _(
"This database is from a newer version of GnuCash. " 499 "This version can read it, but cannot safely save to it. " 500 "It will be marked read-only until you do File->Save As, " 501 "but data may be lost in writing to the old version.");
502 gnc_warning_dialog (parent,
"%s", fmt);
507 fmt = _(
"The SQL database is in use by other users, " 508 "and the upgrade cannot be performed until they logoff. " 509 "If there are currently no other users, consult the " 510 "documentation to learn how to clear out dangling login " 512 gnc_error_dialog (parent,
"%s", fmt);
517 fmt = _(
"The library \"libdbi\" installed on your system doesn't correctly " 518 "store large numbers. This means GnuCash cannot use SQL databases " 519 "correctly. Gnucash will not open or save to SQL databases until this is " 520 "fixed by installing a different version of \"libdbi\". Please see " 521 "https://bugs.gnucash.org/show_bug.cgi?id=611936 for more " 524 gnc_error_dialog (parent,
"%s", fmt);
529 fmt = _(
"GnuCash could not complete a critical test for the presence of " 530 "a bug in the \"libdbi\" library. This may be caused by a " 531 "permissions misconfiguration of your SQL database. Please see " 532 "https://bugs.gnucash.org/show_bug.cgi?id=645216 for more " 535 gnc_error_dialog (parent,
"%s", fmt);
539 fmt = _(
"This file is from an older version of GnuCash and will be " 540 "upgraded when saved by this version. You will not be able " 541 "to read the saved file from the older version of Gnucash " 542 "(it will report an \"error parsing the file\"). If you wish " 543 "to preserve the old version, exit without saving.");
544 gnc_warning_dialog (parent,
"%s", fmt);
549 PERR(
"FIXME: Unhandled error %d", io_error);
550 fmt = _(
"An unknown I/O error (%d) occurred.");
551 gnc_error_dialog (parent, fmt, io_error);
555 g_free (displayname);
560 gnc_add_history (QofSession * session)
565 if (!session)
return;
567 url = qof_session_get_url ( session );
581 gnc_book_opened (
void)
583 gnc_hook_run(HOOK_BOOK_OPENED, gnc_get_current_session());
587 gnc_file_new (GtkWindow *parent)
593 if (!gnc_file_query_save (parent, TRUE))
596 if (gnc_current_session_exist())
598 session = gnc_get_current_session ();
604 gnc_hook_run(HOOK_BOOK_CLOSED, session);
606 gnc_close_gui_component_by_session (session);
608 gnc_clear_current_session();
613 gnc_get_current_session ();
615 gnc_hook_run(HOOK_NEW_BOOK, NULL);
617 gnc_gui_refresh_all ();
624 gnc_file_query_save (GtkWindow *parent, gboolean can_cancel)
626 QofBook *current_book;
628 if (!gnc_current_session_exist())
633 gnc_autosave_remove_timer(current_book);
645 const char *title = _(
"Save changes to the file?");
650 dialog = gtk_message_dialog_new(parent,
651 GTK_DIALOG_DESTROY_WITH_PARENT,
652 GTK_MESSAGE_QUESTION,
656 minutes = (
gnc_time (NULL) - oldest_change) / 60 + 1;
657 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
658 ngettext(
"If you don't save, changes from the past %d minute will be discarded.",
659 "If you don't save, changes from the past %d minutes will be discarded.",
661 gtk_dialog_add_button(GTK_DIALOG(dialog),
662 _(
"Continue _Without Saving"), GTK_RESPONSE_OK);
665 gtk_dialog_add_button(GTK_DIALOG(dialog),
666 _(
"_Cancel"), GTK_RESPONSE_CANCEL);
667 gtk_dialog_add_button(GTK_DIALOG(dialog),
668 _(
"_Save"), GTK_RESPONSE_YES);
670 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES);
672 response = gtk_dialog_run(GTK_DIALOG(dialog));
673 gtk_widget_destroy(dialog);
677 case GTK_RESPONSE_YES:
678 gnc_file_save (parent);
682 case GTK_RESPONSE_CANCEL:
689 case GTK_RESPONSE_OK:
700 get_account_sep_warning (QofBook *book)
704 if (!violation_accts)
708 g_list_free_full (violation_accts, g_free);
714 #define RESPONSE_NEW 1 715 #define RESPONSE_OPEN 2 716 #define RESPONSE_QUIT 3 717 #define RESPONSE_READONLY 4 718 #define RESPONSE_FILE 5 723 run_post_load_scrubs (GtkWindow *parent, QofBook *book)
725 const char *budget_warning =
726 _(
"This book has budgets. The internal representation of " 727 "budget amounts no longer depends on the Reverse Balanced " 728 "Accounts preference. Please review the budgets and amend " 729 "signs if necessary.");
737 if (gnc_maybe_scrub_all_budget_signs (book))
738 infos = g_list_prepend (infos, g_strdup (budget_warning));
745 char *sep_warning = get_account_sep_warning (book);
747 infos = g_list_prepend (infos, sep_warning);
754 const char *header = N_(
"The following are noted in this file:");
755 infos = g_list_reverse (infos);
756 infos = g_list_prepend (infos, g_strdup (_(header)));
758 gnc_info_dialog (parent,
"%s",
final);
761 g_list_free_full (infos, g_free);
765 gnc_post_file_open (GtkWindow *parent,
const char * filename, gboolean is_readonly)
767 QofSession *new_session;
768 gboolean uh_oh = FALSE;
772 gchar *scheme = NULL;
773 gchar *hostname = NULL;
774 gchar *username = NULL;
775 gchar *password = NULL;
780 ENTER(
"filename %s", filename);
782 if (!filename || (*filename ==
'\0'))
return FALSE;
789 show_session_error (parent,
791 GNC_FILE_DIALOG_OPEN);
796 &port, &username, &password, &path);
808 gboolean have_valid_pw = FALSE;
810 path, &username, &password );
817 username, password, path);
823 gchar *default_dir = g_path_get_dirname(path);
824 gnc_set_default_directory (GNC_PREFS_GROUP_OPEN_SAVE, default_dir);
834 gnc_set_busy_cursor (NULL, TRUE);
838 if (gnc_current_session_exist())
840 QofSession *current_session = gnc_get_current_session();
841 gnc_hook_run(HOOK_BOOK_CLOSED, current_session);
842 gnc_close_gui_component_by_session (current_session);
844 gnc_clear_current_session();
859 show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_OPEN);
860 if (g_file_test (filename, G_FILE_TEST_IS_DIR))
861 directory = g_strdup (filename);
863 directory = gnc_get_default_directory (GNC_PREFS_GROUP_OPEN_SAVE);
865 filename = gnc_file_dialog (parent, NULL, NULL, directory,
866 GNC_FILE_DIALOG_OPEN);
869 qof_session_destroy (new_session);
878 gchar *displayname = NULL;
880 char *fmt1 = _(
"GnuCash could not obtain the lock for %s.");
882 _(
"That database may be in use by another user, " 883 "in which case you should not open the database. " 884 "What would you like to do?") :
885 _(
"That database may be on a read-only file system, " 886 "you may not have write permission for the directory, " 887 "or your anti-virus software is preventing this action. " 888 "If you proceed you may not be able to save any changes. " 889 "What would you like to do?")
899 dialog = gtk_message_dialog_new(parent,
904 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
906 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
908 gnc_gtk_dialog_add_button(dialog, _(
"Open _Read-Only"),
909 "emblem-readonly", RESPONSE_READONLY);
911 gnc_gtk_dialog_add_button(dialog, _(
"Create _New File"),
912 "document-new-symbolic", RESPONSE_NEW);
914 gnc_gtk_dialog_add_button(dialog, _(
"Open _Anyway"),
915 "document-open-symbolic", RESPONSE_OPEN);
917 gnc_gtk_dialog_add_button(dialog, _(
"Open _Folder"),
918 "folder-open-symbolic", RESPONSE_FILE);
922 gtk_dialog_add_button(GTK_DIALOG(dialog),
923 _(
"_Quit"), RESPONSE_QUIT);
924 gtk_dialog_set_default_response (GTK_DIALOG(dialog), RESPONSE_QUIT);
927 gtk_dialog_set_default_response (GTK_DIALOG(dialog), RESPONSE_FILE);
929 rc = gtk_dialog_run(GTK_DIALOG(dialog));
930 gtk_widget_destroy(dialog);
931 g_free (displayname);
933 if (rc == GTK_RESPONSE_DELETE_EVENT)
935 rc = shutdown_cb ? RESPONSE_QUIT : RESPONSE_FILE;
944 case RESPONSE_READONLY:
958 gnc_file_new (parent);
965 gnc_file_open (parent);
972 if (!show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_OPEN))
994 uh_oh = show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_OPEN);
1006 path, username, password );
1009 gnc_window_show_progress(_(
"Loading user dataā¦"), 0.0);
1010 qof_session_load (new_session, gnc_window_show_progress);
1011 gnc_window_show_progress(NULL, -1.0);
1026 if (gnc_xml_convert_single_file (newfile))
1029 gnc_window_show_progress(_(
"Loading user dataā¦"), 0.0);
1030 qof_session_load (new_session, gnc_window_show_progress);
1031 gnc_window_show_progress(NULL, -1.0);
1041 uh_oh = show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_OPEN);
1045 gnc_window_show_progress(_(
"Re-saving user dataā¦"), 0.0);
1048 uh_oh = show_session_error(parent, io_err, newfile, GNC_FILE_DIALOG_SAVE);
1061 if (uh_oh) new_root = NULL;
1065 if (!uh_oh && !new_root)
1068 GNC_FILE_DIALOG_OPEN);
1083 gnc_error_dialog (parent, msg,
"");
1086 if (template_root != NULL)
1088 GList *child = NULL;
1091 for (child = children; child; child = g_list_next (child))
1093 Account *acc = GNC_ACCOUNT (child->data);
1095 g_list_foreach (splits,
1097 g_list_free (splits);
1099 g_list_free (children);
1110 gnc_unset_busy_cursor (NULL);
1116 qof_session_destroy (new_session);
1125 gnc_get_current_session ();
1130 gnc_gui_refresh_all ();
1137 gnc_set_current_session(new_session);
1142 gnc_add_history (new_session);
1147 gnc_gui_refresh_all ();
1152 run_post_load_scrubs (parent, gnc_get_current_book ());
1164 gnc_file_open (GtkWindow *parent)
1166 const gchar * newfile;
1168 gchar *default_dir = NULL;
1171 if (!gnc_file_query_save (parent, TRUE))
1177 default_dir = g_path_get_dirname( filepath );
1178 g_free ( filepath );
1181 default_dir = gnc_get_default_directory(GNC_PREFS_GROUP_OPEN_SAVE);
1183 newfile = gnc_file_dialog (parent, _(
"Open"), NULL, default_dir, GNC_FILE_DIALOG_OPEN);
1185 g_free ( default_dir );
1187 result = gnc_post_file_open (parent, newfile, FALSE );
1193 gnc_get_current_session ();
1199 gnc_file_open_file (GtkWindow *parent,
const char * newfile, gboolean open_readonly)
1201 if (!newfile)
return FALSE;
1203 if (!gnc_file_query_save (parent, TRUE))
1210 return gnc_post_file_open (parent, newfile, open_readonly);
1218 gnc_file_export (GtkWindow *parent)
1220 const char *filename;
1221 char *default_dir = NULL;
1230 default_dir = g_path_get_dirname( filepath );
1231 g_free ( filepath );
1234 default_dir = gnc_get_default_directory(GNC_PREFS_GROUP_EXPORT);
1236 filename = gnc_file_dialog (parent,
1237 _(
"Save"), NULL, default_dir,
1238 GNC_FILE_DIALOG_SAVE);
1240 g_free ( default_dir );
1241 if (!filename)
return;
1243 gnc_file_do_export (parent, filename);
1252 check_file_path (
const char *path)
1255 gchar *dir = g_path_get_dirname(path);
1257 char *dirpath = dir;
1262 while (strcmp(dir = g_path_get_dirname(dirpath), dirpath) != 0)
1264 if (strcmp(dirpath, dotgnucash) == 0)
1280 gnc_file_do_export(GtkWindow *parent,
const char * filename)
1282 QofSession *current_session, *new_session;
1287 const gchar *oldfile;
1289 gchar *scheme = NULL;
1290 gchar *hostname = NULL;
1291 gchar *username = NULL;
1292 gchar *password = NULL;
1304 GNC_FILE_DIALOG_EXPORT);
1311 &port, &username, &password, &path);
1316 if (g_strcmp0 (scheme,
"file") == 0)
1319 scheme = g_strdup (
"xml");
1321 username, password, path);
1323 newfile = norm_file;
1331 if (check_file_path (path))
1334 GNC_FILE_DIALOG_SAVE);
1337 gnc_set_default_directory (GNC_PREFS_GROUP_OPEN_SAVE,
1338 g_path_get_dirname(path));
1342 current_session = gnc_get_current_session ();
1343 oldfile = qof_session_get_url(current_session);
1344 if (strlen (oldfile) && (strcmp(oldfile, newfile) == 0))
1348 GNC_FILE_DIALOG_EXPORT);
1356 new_session = qof_session_new (NULL);
1363 const char *format = _(
"The file %s already exists. " 1364 "Are you sure you want to overwrite it?");
1372 if (!gnc_verify_dialog (parent, FALSE, format, name))
1381 if (!show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_EXPORT))
1391 gnc_set_busy_cursor (NULL, TRUE);
1392 gnc_window_show_progress(_(
"Exporting fileā¦"), 0.0);
1393 ok = qof_session_export (new_session, current_session,
1394 gnc_window_show_progress);
1395 gnc_window_show_progress(NULL, -1.0);
1396 gnc_unset_busy_cursor (NULL);
1398 qof_session_destroy (new_session);
1405 const char *format = _(
"There was an error saving the file.\n\n%s");
1407 gnc_error_dialog (parent, format, strerror(errno));
1412 static gboolean been_here_before = FALSE;
1415 gnc_file_save (GtkWindow *parent)
1418 const char * newfile;
1419 QofSession *session;
1422 if (!gnc_current_session_exist ())
1428 session = gnc_get_current_session ();
1430 if (!strlen (qof_session_get_url (session)))
1432 gnc_file_save_as (parent);
1438 gint response = gnc_ok_cancel_dialog(parent,
1439 GTK_RESPONSE_CANCEL,
1440 _(
"The database was opened read-only. " 1441 "Do you want to save it to a different place?"));
1442 if (response == GTK_RESPONSE_OK)
1444 gnc_file_save_as (parent);
1451 gnc_set_busy_cursor (NULL, TRUE);
1452 gnc_window_show_progress(_(
"Writing fileā¦"), 0.0);
1454 gnc_window_show_progress(NULL, -1.0);
1455 gnc_unset_busy_cursor (NULL);
1461 if (ERR_BACKEND_NO_ERR != io_err)
1463 newfile = qof_session_get_url(session);
1464 show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_SAVE);
1466 if (been_here_before)
return;
1467 been_here_before = TRUE;
1468 gnc_file_save_as (parent);
1469 been_here_before = FALSE;
1474 gnc_add_history (session);
1475 gnc_hook_run(HOOK_BOOK_SAVED, session);
1484 gnc_file_save_as (GtkWindow *parent)
1486 const gchar *filename;
1487 gchar *default_dir = NULL;
1492 if (!gnc_current_session_exist ())
1494 LEAVE(
"No Session.");
1502 default_dir = g_path_get_dirname( filepath );
1503 g_free ( filepath );
1506 default_dir = gnc_get_default_directory(GNC_PREFS_GROUP_OPEN_SAVE);
1508 filename = gnc_file_dialog (parent,
1509 _(
"Save"), NULL, default_dir,
1510 GNC_FILE_DIALOG_SAVE);
1512 g_free ( default_dir );
1513 if (!filename)
return;
1515 gnc_file_do_save_as (parent, filename);
1521 gnc_file_do_save_as (GtkWindow *parent,
const char* filename)
1523 QofSession *new_session;
1524 QofSession *session;
1527 const gchar *oldfile;
1529 gchar *scheme = NULL;
1530 gchar *hostname = NULL;
1531 gchar *username = NULL;
1532 gchar *password = NULL;
1547 GNC_FILE_DIALOG_SAVE);
1554 &port, &username, &password, &path);
1559 if (g_strcmp0 (scheme,
"file") == 0)
1562 scheme = g_strdup (
"xml");
1564 username, password, path);
1566 newfile = norm_file;
1574 if (check_file_path (path))
1577 GNC_FILE_DIALOG_SAVE);
1580 gnc_set_default_directory (GNC_PREFS_GROUP_OPEN_SAVE,
1581 g_path_get_dirname (path));
1586 session = gnc_get_current_session ();
1587 oldfile = qof_session_get_url(session);
1588 if (strlen (oldfile) && (strcmp(oldfile, newfile) == 0))
1591 gnc_file_save (parent);
1597 gnc_suspend_gui_refresh ();
1599 gnc_resume_gui_refresh ();
1606 new_session = qof_session_new (NULL);
1614 const char *format = _(
"The file %s already exists. " 1615 "Are you sure you want to overwrite it?");
1624 if (!gnc_verify_dialog (parent, FALSE, format, name ))
1627 qof_session_destroy (new_session);
1638 if (!show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_SAVE))
1650 if (!show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_SAVE))
1662 if (ERR_BACKEND_NO_ERR != io_err)
1664 show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_SAVE);
1666 qof_session_destroy (new_session);
1678 path, username, password );
1694 gnc_set_busy_cursor (NULL, TRUE);
1695 gnc_window_show_progress(_(
"Writing fileā¦"), 0.0);
1697 gnc_window_show_progress(NULL, -1.0);
1698 gnc_unset_busy_cursor (NULL);
1701 if ( ERR_BACKEND_NO_ERR != io_err )
1706 show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_SAVE);
1709 qof_session_destroy( new_session );
1717 gnc_clear_current_session();
1718 gnc_set_current_session( new_session );
1723 gnc_add_history (new_session);
1724 gnc_hook_run(HOOK_BOOK_SAVED, new_session);
1735 gnc_file_revert (GtkWindow *parent)
1737 QofSession *session;
1738 const gchar *fileurl, *filename, *tmp;
1739 const gchar *title = _(
"Reverting will discard all unsaved changes to %s. Are you sure you want to proceed?");
1744 session = gnc_get_current_session();
1745 fileurl = qof_session_get_url(session);
1746 if (!strlen (fileurl))
1747 fileurl = _(
"<unknown>");
1748 if ((tmp = strrchr(fileurl,
'/')) != NULL)
1753 if (!gnc_verify_dialog (parent, FALSE, title, filename))
1760 gnc_file_quit (
void)
1762 QofSession *session;
1764 if (!gnc_current_session_exist ())
1766 gnc_set_busy_cursor (NULL, TRUE);
1767 session = gnc_get_current_session ();
1773 gnc_hook_run(HOOK_BOOK_CLOSED, session);
1774 gnc_close_gui_component_by_session (session);
1776 gnc_clear_current_session();
1779 gnc_unset_busy_cursor (NULL);
1783 gnc_file_set_shutdown_callback (GNCShutdownCB cb)
1789 gnc_file_save_in_progress (
void)
1791 if (gnc_current_session_exist())
1793 QofSession *session = gnc_get_current_session();
No read access permission for the given file.
Lost connection to server.
Functions to load, save and get gui state.
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
The qof_session_save() method will commit all changes that have been made to the session.
database is busy, cannot upgrade version
gboolean qof_session_save_in_progress(const QofSession *session)
The qof_session_not_saved() subroutine will return TRUE if any data in the session hasn't been saved ...
Functions to save and retrieve passwords.
couldn't parse the data in the file
SplitList * xaccAccountGetSplitList(const Account *acc)
The xaccAccountGetSplitList() routine returns a pointer to a GList of the splits in the account...
void gnc_sx_scrub_split_numerics(gpointer psplit, gpointer user)
Fix up numerics where they've gotten out-of-sync with the formulas.
void gnc_history_add_file(const char *newfile)
Add a file name to the front of the file "history list".
gchar * gnc_g_list_stringjoin(GList *list_of_strings, const gchar *sep)
Return a string joining a GList whose elements are gchar* strings.
gboolean gnc_uri_is_file_uri(const gchar *uri)
Checks if the given uri defines a file (as opposed to a network service like a database or web url) ...
utility functions for the GnuCash UI
void gnc_state_save(const QofSession *session)
Save the state to a state file on disk for the given session.
gboolean gnc_uri_is_file_scheme(const gchar *scheme)
Checks if the given scheme is used to refer to a file (as opposed to a network service like a databas...
QofBackendError
The errors that can be reported to the GUI & other front-end users.
time64 qof_book_get_session_dirty_time(const QofBook *book)
Retrieve the earliest modification time on the book.
void qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
A special version of save used in the sql backend which moves the existing tables aside...
void qof_session_begin(QofSession *session, const char *uri, SessionOpenMode mode)
Begins a new session.
void xaccLogDisable(void)
document me
Functions that are supported by all types of windows.
QofBook * qof_book_new(void)
Allocate, initialise and return a new QofBook.
database is old and needs upgrading
gchar * gnc_uri_get_path(const gchar *uri)
Extracts the path part from a uri.
Account * gnc_book_get_template_root(const QofBook *book)
Returns the template group from the book.
GList * gnc_account_list_name_violations(QofBook *book, const gchar *separator)
Runs through all the accounts and returns a list of account names that contain the provided separator...
in use by another user (ETXTBSY)
void qof_book_mark_readonly(QofBook *book)
Mark the book as read only.
Create a new store at the URI.
couldn't write to the file
Open the session read-only, ignoring any existing lock and not creating one if the URI isn't locked...
void gnc_uri_get_components(const gchar *uri, gchar **scheme, gchar **hostname, gint32 *port, gchar **username, gchar **password, gchar **path)
Converts a uri in separate components.
#define PERR(format, args...)
Log a serious error.
void qof_session_ensure_all_data_loaded(QofSession *session)
Ensure all of the data is loaded from the session.
#define ENTER(format, args...)
Print a function entry debugging message.
file will be upgraded and not be able to be read by prior versions - warn users
const gchar * gnc_userdata_dir(void)
Ensure that the user's configuration directory exists and is minimally populated. ...
Create a new store at the URI even if a store already exists there.
error in response from server
didn't recognize the file type
user login successful, but no permissions to access the desired object
convert single-entry accounts to clean double-entry
file does not specify encoding
database is newer, we can't write to it
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
Account handling public routines.
char * gnc_history_get_last(void)
Retrieve the name of the file most recently accessed.
gchar * gnc_uri_normalize_uri(const gchar *uri, gboolean allow_password)
Composes a normalized uri starting from any uri (filename, db spec,...).
gchar * gnc_account_name_violations_errmsg(const gchar *separator, GList *invalid_account_names)
Composes a translatable error message showing which account names clash with the current account sepa...
void qof_book_mark_session_saved(QofBook *book)
The qof_book_mark_saved() routine marks the book as having been saved (to a file, to a database)...
Functions providing the file history menu.
User attempt to write to a directory reserved for internal use by GnuCash.
QofBackendError qof_session_pop_error(QofSession *session)
The qof_session_pop_error() routine can be used to obtain the reason for any failure.
Anchor Scheduled Transaction info in a book.
void gnc_account_reset_convert_bayes_to_flat(void)
Reset the flag that indicates the function imap_convert_bayes_to_flat has been run.
void gnc_history_remove_file(const char *oldfile)
Remove all occurrences of a file name from the history list.
void gnc_keyring_set_password(const gchar *access_method, const gchar *server, guint32 port, const gchar *service, const gchar *user, const gchar *password)
Attempt to store a password in some trusted keystore.
file exists, is readable, but is empty
QofBackendError qof_session_get_error(QofSession *session)
The qof_session_get_error() routine can be used to obtain the reason for any failure.
gchar * gnc_features_test_unknown(QofBook *book)
Test if the current book relies on features only introduced in a more recent version of GnuCash...
void qof_session_swap_data(QofSession *session_1, QofSession *session_2)
The qof_session_swap_data () method swaps the book of the two given sessions.
file/db version newer than what we can read
no backend handler found for this access method (ENOSYS)
read failed or file prematurely truncated
gboolean qof_book_session_not_saved(const QofBook *book)
qof_book_not_saved() returns the value of the session_dirty flag, set when changes to any object in t...
LibDBI has numeric errors.
All type declarations for the whole Gnucash engine.
gchar * gnc_uri_add_extension(const gchar *uri, const gchar *extension)
Adds an extension to the uri if:
gboolean gnc_keyring_get_password(GtkWidget *parent, const gchar *access_method, const gchar *server, guint32 port, const gchar *service, gchar **user, gchar **password)
Attempt to retrieve a password to connect to a remote service.
void qof_book_mark_session_dirty(QofBook *book)
The qof_book_mark_dirty() routine marks the book as having been modified.
the named database doesn't exist
GList * gnc_account_get_descendants(const Account *account)
This routine returns a flat list of all of the accounts that are descendants of the specified account...
gboolean gnc_uri_targets_local_fs(const gchar *uri)
Checks if the given uri is either a valid file uri or a local filesystem path.
API for the transaction logger.
gboolean gnc_history_test_for_file(const char *oldfile)
Test for a file name existing in the history list.
couldn't make a backup of the file
File exists, data would be destroyed.
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
void qof_event_suspend(void)
Suspend all engine events.
Backend * pointer was unexpectedly null.
void qof_event_resume(void)
Resume engine event generation.
cannot write to file/directory
bad dbname/login/passwd or network failure
#define LEAVE(format, args...)
Print a function exit debugging message.
time64 gnc_time(time64 *tbuf)
get the current time
Utility functions for convert uri in separate components and back.
could not complete test for LibDBI bug
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
void xaccAccountScrubColorNotSet(QofBook *book)
Remove color slots that have a "Not Set" value, since 2.4.0, fixed in 3.4 This should only be run onc...
File path resolution utility functions.
gboolean gnc_main_window_all_finish_pending(void)
Tell all pages in all windows to finish any outstanding activities.
gchar * gnc_uri_create_uri(const gchar *scheme, const gchar *hostname, gint32 port, const gchar *username, const gchar *password, const gchar *path)
Composes a normalized uri starting from its separate components.
Commodity handling public routines.
file version so old we can't read it
Open will fail if the URI doesn't exist or is locked.
void xaccLogEnable(void)
document me
const gchar * gnc_get_account_separator_string(void)
Returns the account separation character chosen by the user.
Utility functions for file access.