mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Add a progress bar to main window. Use this progress bar to show the
progress of read, write and export functions. Internally this adds a callback pointer for the various backends to pass a percentage done number out to the session code. It also adds a callback pointer for the session code to pass this percentage on out to the routine that initiated the file read/write. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7225 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
74
ChangeLog
74
ChangeLog
@@ -1,3 +1,77 @@
|
||||
2002-09-17 David Hampton <hampton@employees.org>
|
||||
|
||||
Add progress bar to main window. Shows progress of read, write
|
||||
and export functions. Adds a callback for the backend to pass a
|
||||
percentage done number out to the session code, and a callback for
|
||||
the session code to pass this percentage out to the caller's gui
|
||||
display funtion.
|
||||
|
||||
* src/app-file/gnc-file-p.h:
|
||||
* src/app-file/gnc-file.c (gnc_file_set_pct_handler): Add a file
|
||||
handler "percent done" routine that can be installed.
|
||||
|
||||
* src/app-file/gnc-file.c (gnc_post_file_open) (gnc_file_save):
|
||||
Call the file handler routine pre/post file read/write, and pass
|
||||
the handler into the backend so that it can report percentage
|
||||
complete.
|
||||
|
||||
* src/app-file/gnc-file.c (gnc_file_export_file):
|
||||
New export function. This is the upper half of the exporting
|
||||
function. This is designed similar to the read/write routines.
|
||||
|
||||
* src/backend/file/gnc-backend-file.c
|
||||
(gnc_file_be_write_accounts_to_file): New export function. This
|
||||
is part of the lower half of the exporting function. This is
|
||||
designed similar to the read/write routines.
|
||||
|
||||
* src/backend/file/io-example-account.c
|
||||
(gnc_write_example_account):New calling arguments. Add counters.
|
||||
Invoke the percentage done callback where appropriate.
|
||||
|
||||
* src/backend/file/io-gncxml-v2.c (add_schedXaction_local)
|
||||
(run_callback) (write_xxx): New calling arguments. Add counters.
|
||||
Invoke the percentage done callback where appropriate.
|
||||
(file_rw_feedback): New function for XML read/write. Computed
|
||||
percentage done then calls the callback function handed in from
|
||||
outside of the backend code. (gnc_sixtp_gdv2_new): New auxiliary
|
||||
function. (gnc_book_write_to_xml_filehandle_v2)
|
||||
(gnc_book_write_accounts_to_xml_filehandle_v2): Remember count of
|
||||
items to process. (gnc_book_write_accounts_to_xml_file_v2): Other
|
||||
part of the lower half of the exporting function.
|
||||
|
||||
* src/backend/file/io-utils.c (write_account_group)
|
||||
(write_accounts):New calling arguments. Add counters. Invoke the
|
||||
percentage done callback where appropriate.
|
||||
|
||||
* src/backend/postgres/PostgresBackend.c:
|
||||
* src/backend/rpc/RpcBackend.c:
|
||||
* src/enfine/Backend.c:
|
||||
Initialize the new pointers in the backend data structure.
|
||||
|
||||
* src/gnome/window-main.c (gnc_main_window_file_export_cb):
|
||||
The file export function was moved into gnc-file.c.
|
||||
|
||||
* src/engine/Makefile.am:
|
||||
* src/engine/gnc-session-scm.[ch]: New files. Moved the scheme
|
||||
session read/write hooks here because of the new callback. Keeps
|
||||
scheme out of the main session sources.
|
||||
|
||||
* src/engine/gnc-session.c (gnc_session_load):
|
||||
(gnc_session_save): Added a callback for percentage done.
|
||||
(gnc_session_export): New export function. This is the middle of
|
||||
the exporting function. This is designed similar to the
|
||||
load/save routines.
|
||||
|
||||
* src/engine/gw-engine-spec.scm: New arguments to session
|
||||
load/save. New session export function.
|
||||
|
||||
* src/gnome/gw-gnc-spec.scm: New function to destroy the splash screen.
|
||||
|
||||
* src/gnome/top-level.c: No longer destroys splash screen.
|
||||
|
||||
* src/scm/main.scm: I18n new splash screen strings. Destroy splash
|
||||
screen after loading data file.
|
||||
|
||||
2002-09-16 Derek Atkins <derek@ihtfp.com>
|
||||
Fix bug #91413 -- Add TaxTable defaults to Customers and Vendors
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ static GNCHistoryAddFileFunc history_add_file_func = NULL;
|
||||
static GNCHistoryGetLastFunc history_get_last_func = NULL;
|
||||
|
||||
static GNCFileDialogFunc file_dialog_func = NULL;
|
||||
static GNCFilePercentageFunc file_percentage_func = NULL;
|
||||
|
||||
|
||||
void
|
||||
@@ -68,6 +69,12 @@ gnc_file_set_handlers (GNCHistoryAddFileFunc history_add_file_func_in,
|
||||
file_dialog_func = file_dialog_func_in;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_file_set_pct_handler (GNCFilePercentageFunc file_percentage_func_in)
|
||||
{
|
||||
file_percentage_func = file_percentage_func_in;
|
||||
}
|
||||
|
||||
static GNCSession *
|
||||
gnc_get_current_session_internal (void)
|
||||
{
|
||||
@@ -427,7 +434,13 @@ gnc_post_file_open (const char * filename)
|
||||
{
|
||||
AccountGroup *new_group;
|
||||
|
||||
gnc_session_load (new_session);
|
||||
if (file_percentage_func) {
|
||||
file_percentage_func(_("Reading file..."), 0.0);
|
||||
gnc_session_load (new_session, file_percentage_func);
|
||||
file_percentage_func(NULL, -1.0);
|
||||
} else {
|
||||
gnc_session_load (new_session, NULL);
|
||||
}
|
||||
|
||||
/* check for i/o error, put up appropriate error dialog */
|
||||
io_err = gnc_session_get_error (new_session);
|
||||
@@ -528,6 +541,82 @@ gnc_file_open_file (const char * newfile)
|
||||
return gnc_post_file_open (newfile);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_file_export_file(const char * newfile)
|
||||
{
|
||||
GNCSession *new_session;
|
||||
gboolean ok;
|
||||
GNCBackendError io_err = ERR_BACKEND_NO_ERR;
|
||||
|
||||
if (!newfile) {
|
||||
if (!file_dialog_func) {
|
||||
PWARN ("no file dialog function");
|
||||
return;
|
||||
}
|
||||
|
||||
newfile = file_dialog_func (_("Export"), NULL, NULL);
|
||||
if (!newfile)
|
||||
return;
|
||||
}
|
||||
|
||||
gnc_engine_suspend_events();
|
||||
|
||||
/* -- this session code is NOT identical in FileOpen and FileSaveAs -- */
|
||||
|
||||
new_session = gnc_session_new ();
|
||||
gnc_session_begin (new_session, newfile, FALSE, FALSE);
|
||||
|
||||
io_err = gnc_session_get_error (new_session);
|
||||
|
||||
/* if file appears to be locked, ask the user ... */
|
||||
if (ERR_BACKEND_LOCKED == io_err)
|
||||
{
|
||||
if (FALSE == show_session_error (io_err, newfile))
|
||||
{
|
||||
/* user told us to ignore locks. So ignore them. */
|
||||
gnc_session_begin (new_session, newfile, TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------- END CORE SESSION CODE -------------- */
|
||||
|
||||
/* oops ... file already exists ... ask user what to do... */
|
||||
if (gnc_session_save_may_clobber_data (new_session))
|
||||
{
|
||||
const char *format = _("The file \n %s\n already exists.\n"
|
||||
"Are you sure you want to overwrite it?");
|
||||
|
||||
/* if user says cancel, we should break out */
|
||||
if (!gnc_verify_dialog (FALSE, format, newfile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Whoa-ok. Blow away the previous file. */
|
||||
}
|
||||
|
||||
/* use the current session to save to file */
|
||||
gnc_set_busy_cursor (NULL, TRUE);
|
||||
if (file_percentage_func) {
|
||||
file_percentage_func(_("Exporting file..."), 0.0);
|
||||
ok = gnc_session_export (new_session, current_session,
|
||||
file_percentage_func);
|
||||
file_percentage_func(NULL, -1.0);
|
||||
} else {
|
||||
ok = gnc_session_export (new_session, current_session, NULL);
|
||||
}
|
||||
gnc_unset_busy_cursor (NULL);
|
||||
gnc_session_destroy (new_session);
|
||||
gnc_engine_resume_events();
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
const char *format = _("There was an error saving the file.\n\n%s");
|
||||
|
||||
gnc_error_dialog_parented (NULL, format, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean been_here_before = FALSE;
|
||||
|
||||
@@ -552,7 +641,13 @@ gnc_file_save (void)
|
||||
|
||||
/* use the current session to save to file */
|
||||
gnc_set_busy_cursor (NULL, TRUE);
|
||||
gnc_session_save (session);
|
||||
if (file_percentage_func) {
|
||||
file_percentage_func(_("Writing file..."), 0.0);
|
||||
gnc_session_save (session, file_percentage_func);
|
||||
file_percentage_func(NULL, -1.0);
|
||||
} else {
|
||||
gnc_session_save (session, NULL);
|
||||
}
|
||||
gnc_unset_busy_cursor (NULL);
|
||||
|
||||
/* Make sure everything's OK - disk could be full, file could have
|
||||
|
||||
@@ -97,6 +97,11 @@
|
||||
* routine, except that the new file to open is passed as a char *
|
||||
* argument.
|
||||
*
|
||||
* The gnc_file_export_file() routine will check for an existing edit
|
||||
* session, and if one exists, it will save just the commodities
|
||||
* and accounts to a file. If an error occurs, a popup dialogue
|
||||
* will inform the user of the error.
|
||||
*
|
||||
* The gnc_file_quit() routine will close out and destroy the current session.
|
||||
* The user WILL NOT BE PROMPTED to confirm this action, or do do
|
||||
* any kind of saving beforehand.
|
||||
@@ -120,6 +125,7 @@ void gnc_file_save (void);
|
||||
void gnc_file_save_as (void);
|
||||
|
||||
gboolean gnc_file_open_file (const char *filename);
|
||||
void gnc_file_export_file(const char * filename);
|
||||
|
||||
gboolean gnc_file_query_save (void);
|
||||
|
||||
@@ -128,4 +134,7 @@ void gnc_file_quit (void);
|
||||
typedef gboolean (*GNCCanCancelSaveCB) (void);
|
||||
void gnc_file_set_can_cancel_callback (GNCCanCancelSaveCB cb);
|
||||
|
||||
typedef void (*GNCFilePercentageFunc) (const char *message, int percent);
|
||||
void gnc_file_set_pct_handler (GNCFilePercentageFunc file_percentage_func);
|
||||
|
||||
#endif /* GNC_FILE_H */
|
||||
|
||||
@@ -66,6 +66,8 @@ static void gnc_file_be_load_from_file(Backend *, GNCBook *);
|
||||
static gboolean gnc_file_be_get_file_lock (FileBackend *be);
|
||||
static gboolean gnc_file_be_write_to_file(FileBackend *be,
|
||||
gboolean make_backup);
|
||||
static void gnc_file_be_write_accounts_to_file(Backend *be,
|
||||
GNCBook *book);
|
||||
static void gnc_file_be_remove_old_files(FileBackend *be);
|
||||
|
||||
void
|
||||
@@ -213,6 +215,7 @@ gnc_backend_new(void)
|
||||
be->process_events = NULL;
|
||||
|
||||
be->sync_all = file_sync_all;
|
||||
be->export = gnc_file_be_write_accounts_to_file;
|
||||
|
||||
fbe->dirname = NULL;
|
||||
fbe->fullpath = NULL;
|
||||
@@ -371,7 +374,7 @@ gnc_file_be_load_from_file (Backend *bend, GNCBook *book)
|
||||
switch (gnc_file_be_determine_file_type(be->fullpath))
|
||||
{
|
||||
case GNC_BOOK_XML2_FILE:
|
||||
rc = gnc_session_load_from_xml_file_v2 (be->session, NULL);
|
||||
rc = gnc_session_load_from_xml_file_v2 (be->session);
|
||||
if (FALSE == rc) error = ERR_FILEIO_PARSE_ERROR;
|
||||
break;
|
||||
|
||||
@@ -708,3 +711,12 @@ gnc_file_be_write_to_file(FileBackend *be, gboolean make_backup)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_file_be_write_accounts_to_file(Backend *be, GNCBook *book)
|
||||
{
|
||||
const gchar *datafile;
|
||||
|
||||
datafile = ((FileBackend *)be)->fullpath;
|
||||
gnc_book_write_accounts_to_xml_file_v2(be, book, datafile);
|
||||
}
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@ gnc_write_example_account(GncExampleAccount *gea, const gchar *filename)
|
||||
|
||||
write_string_part(out, GNC_ACCOUNT_LONG, gea->long_description);
|
||||
|
||||
write_account_group(out, gea->group);
|
||||
write_account_group(out, gea->group, NULL);
|
||||
|
||||
fprintf(out, "</" GNC_ACCOUNT_STRING ">\n\n");
|
||||
|
||||
|
||||
@@ -64,12 +64,12 @@ struct file_backend {
|
||||
#define GNC_V2_STRING "gnc-v2"
|
||||
static const gchar *book_version_string;
|
||||
|
||||
static void
|
||||
void
|
||||
run_callback(sixtp_gdv2 *data, const char *type)
|
||||
{
|
||||
if(data->countCallback)
|
||||
{
|
||||
data->countCallback(type, data->counter);
|
||||
data->countCallback(data, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +298,8 @@ add_schedXaction_local(sixtp_gdv2 *data, SchedXaction *sx)
|
||||
list = g_list_append(list, sx);
|
||||
|
||||
gnc_book_set_schedxactions(data->book, list);
|
||||
data->counter.schedXactions_loaded++;
|
||||
run_callback(data, "schedXactions");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -473,21 +475,56 @@ gnc_counter_sixtp_parser_create(void)
|
||||
|
||||
#if 0
|
||||
static void
|
||||
print_counter_data(load_counter data)
|
||||
print_counter_data(load_counter *data)
|
||||
{
|
||||
PINFO("Transactions: Total: %d, Loaded: %d\n",
|
||||
data.transactions_total, data.transactions_loaded);
|
||||
data->transactions_total, data->transactions_loaded);
|
||||
PINFO("Accounts: Total: %d, Loaded: %d\n",
|
||||
data.accounts_total, data.accounts_loaded);
|
||||
data->accounts_total, data->accounts_loaded);
|
||||
PINFO("Books: Total: %d, Loaded: %d\n",
|
||||
data.books_total, data.books_loaded);
|
||||
data->books_total, data->books_loaded);
|
||||
PINFO("Commodities: Total: %d, Loaded: %d\n",
|
||||
data.commodities_total, data.commodities_loaded);
|
||||
data->commodities_total, data->commodities_loaded);
|
||||
PINFO("Scheduled Tansactions: Total: %d, Loaded: %d\n",
|
||||
data.schedXactions_total, data.schedXactions_loaded);
|
||||
data->schedXactions_total, data->schedXactions_loaded);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
file_rw_feedback (sixtp_gdv2 *gd, const char *type)
|
||||
{
|
||||
load_counter *counter;
|
||||
int loaded, total, percentage;
|
||||
|
||||
g_assert(gd != NULL);
|
||||
if (!gd->gui_display_fn)
|
||||
return;
|
||||
|
||||
counter = &gd->counter;
|
||||
loaded = counter->transactions_loaded + counter->accounts_loaded +
|
||||
counter->books_loaded + counter->commodities_loaded +
|
||||
counter->schedXactions_loaded;
|
||||
total = counter->transactions_total + counter->accounts_total +
|
||||
counter->books_total + counter->commodities_total +
|
||||
counter->schedXactions_total;
|
||||
|
||||
percentage = (loaded * 100)/total;
|
||||
if (percentage > 100) {
|
||||
printf("Transactions: Total: %d, Loaded: %d\n",
|
||||
counter->transactions_total, counter->transactions_loaded);
|
||||
printf("Accounts: Total: %d, Loaded: %d\n",
|
||||
counter->accounts_total, counter->accounts_loaded);
|
||||
printf("Books: Total: %d, Loaded: %d\n",
|
||||
counter->books_total, counter->books_loaded);
|
||||
printf("Commodities: Total: %d, Loaded: %d\n",
|
||||
counter->commodities_total, counter->commodities_loaded);
|
||||
printf("Scheduled Tansactions: Total: %d, Loaded: %d\n",
|
||||
counter->schedXactions_total, counter->schedXactions_loaded);
|
||||
}
|
||||
percentage = MIN(percentage, 100);
|
||||
gd->gui_display_fn(NULL, percentage);
|
||||
}
|
||||
|
||||
static const char *BOOK_TAG = "gnc:book";
|
||||
static const char *BOOK_ID_TAG = "book:id";
|
||||
static const char *BOOK_SLOTS_TAG = "book:slots";
|
||||
@@ -605,21 +642,15 @@ add_parser_cb (const char *type, gpointer data_p, gpointer be_data_p)
|
||||
be_data->ok = FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_session_load_from_xml_file_v2(
|
||||
GNCSession *session,
|
||||
void (*countcallback)(const char *type, load_counter count))
|
||||
static sixtp_gdv2 *
|
||||
gnc_sixtp_gdv2_new (
|
||||
GNCBook *book,
|
||||
countCallbackFn countcallback,
|
||||
GNCBePercentageFunc gui_display_fn)
|
||||
{
|
||||
GNCBook *book;
|
||||
sixtp_gdv2 *gd;
|
||||
sixtp *top_parser;
|
||||
sixtp *main_parser;
|
||||
sixtp *book_parser;
|
||||
struct file_backend be_data;
|
||||
sixtp_gdv2 *gd = g_new0(sixtp_gdv2, 1);
|
||||
|
||||
gd = g_new0(sixtp_gdv2, 1);
|
||||
|
||||
book = gnc_session_get_book (session);
|
||||
if (gd == NULL) return NULL;
|
||||
|
||||
gd->book = book;
|
||||
gd->counter.accounts_loaded = 0;
|
||||
@@ -636,6 +667,24 @@ gnc_session_load_from_xml_file_v2(
|
||||
gd->counter.schedXactions_total = 0;
|
||||
|
||||
gd->countCallback = countcallback;
|
||||
gd->gui_display_fn = gui_display_fn;
|
||||
return gd;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_session_load_from_xml_file_v2(GNCSession *session)
|
||||
{
|
||||
GNCBook *book;
|
||||
Backend *be;
|
||||
sixtp_gdv2 *gd;
|
||||
sixtp *top_parser;
|
||||
sixtp *main_parser;
|
||||
sixtp *book_parser;
|
||||
struct file_backend be_data;
|
||||
|
||||
book = gnc_session_get_book (session);
|
||||
be = (Backend *)gnc_book_get_backend(book);
|
||||
gd = gnc_sixtp_gdv2_new(book, file_rw_feedback, be->percentage);
|
||||
|
||||
top_parser = sixtp_new();
|
||||
main_parser = sixtp_new();
|
||||
@@ -646,7 +695,7 @@ gnc_session_load_from_xml_file_v2(
|
||||
GNC_V2_STRING, main_parser,
|
||||
NULL, NULL))
|
||||
{
|
||||
return FALSE;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(!sixtp_add_some_sub_parsers(
|
||||
@@ -665,7 +714,7 @@ gnc_session_load_from_xml_file_v2(
|
||||
TEMPLATE_TRANSACTION_TAG, gnc_template_transaction_sixtp_parser_create(),
|
||||
NULL, NULL))
|
||||
{
|
||||
return FALSE;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(!sixtp_add_some_sub_parsers(
|
||||
@@ -681,14 +730,14 @@ gnc_session_load_from_xml_file_v2(
|
||||
TEMPLATE_TRANSACTION_TAG, gnc_template_transaction_sixtp_parser_create(),
|
||||
NULL, NULL))
|
||||
{
|
||||
return FALSE;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
be_data.ok = TRUE;
|
||||
be_data.parser = book_parser;
|
||||
gncObjectForeachBackend (GNC_FILE_BACKEND, add_parser_cb, &be_data);
|
||||
if (be_data.ok == FALSE)
|
||||
return FALSE;
|
||||
goto bail;
|
||||
|
||||
/* stop logging while we load */
|
||||
xaccLogDisable ();
|
||||
@@ -698,7 +747,7 @@ gnc_session_load_from_xml_file_v2(
|
||||
{
|
||||
sixtp_destroy(top_parser);
|
||||
xaccLogEnable ();
|
||||
return FALSE;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* If the parse succeeded, but there is no pricedb,
|
||||
@@ -729,9 +778,13 @@ gnc_session_load_from_xml_file_v2(
|
||||
|
||||
g_free(gd);
|
||||
/* DEBUG */
|
||||
/* print_counter_data(gd.counter); */
|
||||
/* print_counter_data(&gd->counter); */
|
||||
|
||||
return TRUE;
|
||||
|
||||
bail:
|
||||
g_free(gd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -790,10 +843,10 @@ compare_commodity_ids(gconstpointer a, gconstpointer b)
|
||||
gnc_commodity_get_mnemonic(cb)));
|
||||
}
|
||||
|
||||
static void write_pricedb (FILE *out, GNCBook *book);
|
||||
static void write_transactions (FILE *out, GNCBook *book);
|
||||
static void write_template_transaction_data (FILE *out, GNCBook *book);
|
||||
static void write_schedXactions(FILE *out, GNCBook *book);
|
||||
static void write_pricedb (FILE *out, GNCBook *book, sixtp_gdv2 *gd);
|
||||
static void write_transactions (FILE *out, GNCBook *book, sixtp_gdv2 *gd);
|
||||
static void write_template_transaction_data (FILE *out, GNCBook *book, sixtp_gdv2 *gd);
|
||||
static void write_schedXactions(FILE *out, GNCBook *book, sixtp_gdv2 *gd);
|
||||
|
||||
static void
|
||||
write_counts_cb (const char *type, gpointer data_p, gpointer be_data_p)
|
||||
@@ -824,7 +877,7 @@ write_data_cb (const char *type, gpointer data_p, gpointer be_data_p)
|
||||
}
|
||||
|
||||
static void
|
||||
write_book(FILE *out, GNCBook *book)
|
||||
write_book(FILE *out, GNCBook *book, sixtp_gdv2 *gd)
|
||||
{
|
||||
struct file_backend be_data;
|
||||
|
||||
@@ -860,7 +913,7 @@ write_book(FILE *out, GNCBook *book)
|
||||
gnc_commodity_table_get_size(
|
||||
gnc_book_get_commodity_table(book)),
|
||||
"account",
|
||||
xaccGroupGetNumSubAccounts(gnc_book_get_group(book)),
|
||||
1 + xaccGroupGetNumSubAccounts(gnc_book_get_group(book)),
|
||||
"transaction",
|
||||
gnc_book_count_transactions(book),
|
||||
"schedxaction",
|
||||
@@ -869,12 +922,12 @@ write_book(FILE *out, GNCBook *book)
|
||||
|
||||
gncObjectForeachBackend (GNC_FILE_BACKEND, write_counts_cb, &be_data);
|
||||
|
||||
write_commodities(out, book);
|
||||
write_pricedb(out, book);
|
||||
write_accounts(out, book);
|
||||
write_transactions(out, book);
|
||||
write_template_transaction_data(out, book);
|
||||
write_schedXactions(out, book);
|
||||
write_commodities(out, book, gd);
|
||||
write_pricedb(out, book, gd);
|
||||
write_accounts(out, book, gd);
|
||||
write_transactions(out, book, gd);
|
||||
write_template_transaction_data(out, book, gd);
|
||||
write_schedXactions(out, book, gd);
|
||||
|
||||
gncObjectForeachBackend (GNC_FILE_BACKEND, write_data_cb, &be_data);
|
||||
|
||||
@@ -882,7 +935,7 @@ write_book(FILE *out, GNCBook *book)
|
||||
}
|
||||
|
||||
void
|
||||
write_commodities(FILE *out, GNCBook *book)
|
||||
write_commodities(FILE *out, GNCBook *book, sixtp_gdv2 *gd)
|
||||
{
|
||||
gnc_commodity_table *tbl;
|
||||
GList *namespaces;
|
||||
@@ -916,6 +969,8 @@ write_commodities(FILE *out, GNCBook *book)
|
||||
fprintf(out, "\n");
|
||||
|
||||
xmlFreeNode(comnode);
|
||||
gd->counter.commodities_loaded++;
|
||||
run_callback(gd, "commodities");
|
||||
}
|
||||
|
||||
g_list_free (comms);
|
||||
@@ -926,7 +981,7 @@ write_commodities(FILE *out, GNCBook *book)
|
||||
}
|
||||
|
||||
static void
|
||||
write_pricedb(FILE *out, GNCBook *book)
|
||||
write_pricedb(FILE *out, GNCBook *book, sixtp_gdv2 *gd)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
|
||||
@@ -946,27 +1001,34 @@ write_pricedb(FILE *out, GNCBook *book)
|
||||
static gboolean
|
||||
xml_add_trn_data(Transaction *t, gpointer data)
|
||||
{
|
||||
struct file_backend *be_data = data;
|
||||
xmlNodePtr node;
|
||||
|
||||
node = gnc_transaction_dom_tree_create(t);
|
||||
|
||||
xmlElemDump((FILE*)data, NULL, node);
|
||||
fprintf((FILE*)data, "\n");
|
||||
xmlElemDump(be_data->out, NULL, node);
|
||||
fprintf(be_data->out, "\n");
|
||||
|
||||
xmlFreeNode(node);
|
||||
be_data->gd->counter.transactions_loaded++;
|
||||
run_callback(be_data->gd, "transaction");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
write_transactions(FILE *out, GNCBook *book)
|
||||
write_transactions(FILE *out, GNCBook *book, sixtp_gdv2 *gd)
|
||||
{
|
||||
struct file_backend be_data;
|
||||
|
||||
be_data.out = out;
|
||||
be_data.gd = gd;
|
||||
xaccGroupForEachTransaction(gnc_book_get_group(book),
|
||||
xml_add_trn_data,
|
||||
(gpointer) out);
|
||||
(gpointer) &be_data);
|
||||
}
|
||||
|
||||
static void
|
||||
write_template_transaction_data( FILE *out, GNCBook *book )
|
||||
write_template_transaction_data( FILE *out, GNCBook *book, sixtp_gdv2 *gd )
|
||||
{
|
||||
AccountGroup *ag;
|
||||
|
||||
@@ -974,14 +1036,14 @@ write_template_transaction_data( FILE *out, GNCBook *book )
|
||||
if ( xaccGroupGetNumSubAccounts(ag) > 0 )
|
||||
{
|
||||
fprintf( out, "<%s>\n", TEMPLATE_TRANSACTION_TAG );
|
||||
write_account_group( out, ag );
|
||||
write_account_group( out, ag, gd );
|
||||
xaccGroupForEachTransaction( ag, xml_add_trn_data, (gpointer)out );
|
||||
fprintf( out, "</%s>\n", TEMPLATE_TRANSACTION_TAG );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_schedXactions( FILE *out, GNCBook *book )
|
||||
write_schedXactions( FILE *out, GNCBook *book, sixtp_gdv2 *gd)
|
||||
{
|
||||
GList *schedXactions;
|
||||
SchedXaction *tmpSX;
|
||||
@@ -999,6 +1061,8 @@ write_schedXactions( FILE *out, GNCBook *book )
|
||||
xmlElemDump( out, NULL, node );
|
||||
fprintf( out, "\n" );
|
||||
xmlFreeNode( node );
|
||||
gd->counter.schedXactions_loaded++;
|
||||
run_callback(gd, "schedXactions");
|
||||
} while ( (schedXactions = schedXactions->next) );
|
||||
}
|
||||
|
||||
@@ -1032,6 +1096,9 @@ write_v2_header (FILE *out)
|
||||
gboolean
|
||||
gnc_book_write_to_xml_filehandle_v2(GNCBook *book, FILE *out)
|
||||
{
|
||||
Backend *be;
|
||||
sixtp_gdv2 *gd;
|
||||
|
||||
if (!out) return FALSE;
|
||||
|
||||
write_v2_header (out);
|
||||
@@ -1040,19 +1107,34 @@ gnc_book_write_to_xml_filehandle_v2(GNCBook *book, FILE *out)
|
||||
"book", 1,
|
||||
NULL);
|
||||
|
||||
write_book(out, book);
|
||||
be = (Backend *)gnc_book_get_backend(book);
|
||||
gd = gnc_sixtp_gdv2_new(book, file_rw_feedback, be->percentage);
|
||||
gd->counter.commodities_total =
|
||||
gnc_commodity_table_get_size(gnc_book_get_commodity_table(book));
|
||||
gd->counter.accounts_total = 1 +
|
||||
xaccGroupGetNumSubAccounts(gnc_book_get_group(book));
|
||||
gd->counter.transactions_total = gnc_book_count_transactions(book);
|
||||
gd->counter.schedXactions_total =
|
||||
g_list_length( gnc_book_get_schedxactions(book));
|
||||
|
||||
write_book(out, book, gd);
|
||||
|
||||
fprintf(out, "</" GNC_V2_STRING ">\n\n");
|
||||
|
||||
g_free(gd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called by the "export" code.
|
||||
*/
|
||||
gboolean
|
||||
gnc_book_write_accounts_to_xml_filehandle_v2(GNCBook *book, FILE *out)
|
||||
gnc_book_write_accounts_to_xml_filehandle_v2(Backend *be, GNCBook *book, FILE *out)
|
||||
{
|
||||
sixtp_gdv2 *gd;
|
||||
|
||||
if (!out) return FALSE;
|
||||
|
||||
PWARN ("huhhhh ???? Who is using this thing ??? \n");
|
||||
write_v2_header (out);
|
||||
|
||||
write_counts(out,
|
||||
@@ -1060,20 +1142,29 @@ PWARN ("huhhhh ???? Who is using this thing ??? \n");
|
||||
gnc_commodity_table_get_size(
|
||||
gnc_book_get_commodity_table(book)),
|
||||
"account",
|
||||
xaccGroupGetNumSubAccounts(gnc_book_get_group(book)),
|
||||
1 + xaccGroupGetNumSubAccounts(gnc_book_get_group(book)),
|
||||
NULL);
|
||||
|
||||
write_commodities(out, book);
|
||||
gd = gnc_sixtp_gdv2_new(book, file_rw_feedback, be->percentage);
|
||||
gd->counter.commodities_total =
|
||||
gnc_commodity_table_get_size(gnc_book_get_commodity_table(book));
|
||||
gd->counter.accounts_total = 1 +
|
||||
xaccGroupGetNumSubAccounts(gnc_book_get_group(book));
|
||||
|
||||
write_accounts(out, book);
|
||||
write_commodities(out, book, gd);
|
||||
|
||||
write_accounts(out, book, gd);
|
||||
|
||||
fprintf(out, "</" GNC_V2_STRING ">\n\n");
|
||||
|
||||
g_free(gd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_book_write_to_xml_file_v2(GNCBook *book, const char *filename)
|
||||
gnc_book_write_to_xml_file_v2(
|
||||
GNCBook *book,
|
||||
const char *filename)
|
||||
{
|
||||
FILE *out;
|
||||
|
||||
@@ -1095,6 +1186,37 @@ gnc_book_write_to_xml_file_v2(GNCBook *book, const char *filename)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Have to pass in the backend as this routine needs the temporary
|
||||
* backend for file export, not the real backend which could be
|
||||
* postgress or anything else.
|
||||
*/
|
||||
gboolean
|
||||
gnc_book_write_accounts_to_xml_file_v2(
|
||||
Backend *be,
|
||||
GNCBook *book,
|
||||
const char *filename)
|
||||
{
|
||||
FILE *out;
|
||||
|
||||
out = fopen(filename, "w");
|
||||
if (out == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gnc_book_write_accounts_to_xml_filehandle_v2 (be, book, out);
|
||||
|
||||
write_emacs_trailer(out);
|
||||
|
||||
if (fclose(out) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
gboolean
|
||||
gnc_is_xml_data_file_v2(const gchar *name)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <glib.h>
|
||||
|
||||
#include "Account.h"
|
||||
#include "Backend.h"
|
||||
#include "Transaction.h"
|
||||
#include "gnc-book.h"
|
||||
#include "gnc-commodity.h"
|
||||
@@ -64,12 +65,15 @@ typedef struct
|
||||
int schedXactions_loaded;
|
||||
} load_counter;
|
||||
|
||||
typedef struct
|
||||
typedef struct sixtp_gdv2 sixtp_gdv2;
|
||||
typedef void (*countCallbackFn)(sixtp_gdv2 *gd, const char *type);
|
||||
struct sixtp_gdv2
|
||||
{
|
||||
GNCBook *book;
|
||||
load_counter counter;
|
||||
void (*countCallback)(const char *type, load_counter counter);
|
||||
} sixtp_gdv2;
|
||||
countCallbackFn countCallback;
|
||||
GNCBePercentageFunc gui_display_fn;
|
||||
};
|
||||
|
||||
/**
|
||||
* Struct used to pass in a new data type for XML storage. This contains
|
||||
@@ -114,18 +118,20 @@ typedef struct
|
||||
GNCBook *book;
|
||||
} gnc_template_xaction_data;
|
||||
|
||||
/* Call after loading each record */
|
||||
void run_callback(sixtp_gdv2 *data, const char *type);
|
||||
|
||||
/* read in an account group from a file */
|
||||
gboolean gnc_session_load_from_xml_file_v2(
|
||||
GNCSession *session,
|
||||
void (*countcallback)(const char *type, load_counter count));
|
||||
gboolean gnc_session_load_from_xml_file_v2(GNCSession *session);
|
||||
|
||||
/* write all book info to a file */
|
||||
gboolean gnc_book_write_to_xml_filehandle_v2(GNCBook *book, FILE *fh);
|
||||
gboolean gnc_book_write_to_xml_file_v2(GNCBook *book, const char *filename);
|
||||
|
||||
/* write just the commodities and accounts to a file */
|
||||
gboolean gnc_book_write_accounts_to_xml_filehandle_v2(GNCBook *book,
|
||||
FILE *out);
|
||||
gboolean gnc_book_write_accounts_to_xml_filehandle_v2(Backend *be, GNCBook *book, FILE *fh);
|
||||
gboolean gnc_book_write_accounts_to_xml_file_v2(Backend * be, GNCBook *book,
|
||||
const char *filename);
|
||||
|
||||
/* The is_gncxml_file() routine checks to see if the first few
|
||||
* chars of the file look like gnc-xml data.
|
||||
|
||||
@@ -53,7 +53,7 @@ write_emacs_trailer(FILE *out)
|
||||
}
|
||||
|
||||
void
|
||||
write_account_group(FILE *out, AccountGroup *grp)
|
||||
write_account_group(FILE *out, AccountGroup *grp, sixtp_gdv2 *gd)
|
||||
{
|
||||
GList *list;
|
||||
GList *node;
|
||||
@@ -71,18 +71,20 @@ write_account_group(FILE *out, AccountGroup *grp)
|
||||
fprintf(out, "\n");
|
||||
|
||||
xmlFreeNode(accnode);
|
||||
gd->counter.accounts_loaded++;
|
||||
run_callback(gd, "account");
|
||||
|
||||
newgrp = xaccAccountGetChildren((Account*)(node->data));
|
||||
|
||||
if (newgrp)
|
||||
{
|
||||
write_account_group(out, newgrp);
|
||||
write_account_group(out, newgrp, gd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
write_accounts(FILE *out, GNCBook *book)
|
||||
write_accounts(FILE *out, GNCBook *book, sixtp_gdv2 *gd)
|
||||
{
|
||||
write_account_group(out, gnc_book_get_group(book));
|
||||
write_account_group(out, gnc_book_get_group(book), gd);
|
||||
}
|
||||
|
||||
@@ -29,11 +29,12 @@
|
||||
|
||||
#include "gnc-book.h"
|
||||
#include "Group.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
void write_account_group(FILE *out, AccountGroup *grp);
|
||||
void write_accounts(FILE *out, GNCBook *book);
|
||||
void write_account_group(FILE *out, AccountGroup *grp, sixtp_gdv2 *gd);
|
||||
void write_accounts(FILE *out, GNCBook *book, sixtp_gdv2 *gd);
|
||||
void write_book_parts(FILE *out, GNCBook *book);
|
||||
void write_commodities(FILE *out, GNCBook *book);
|
||||
void write_commodities(FILE *out, GNCBook *book, sixtp_gdv2 *gd);
|
||||
|
||||
void write_emacs_trailer(FILE *out);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ test_load_file(const char *filename)
|
||||
ignore_lock = (strcmp(getenv("SRCDIR"), ".") != 0);
|
||||
gnc_session_begin(session, filename, ignore_lock, FALSE);
|
||||
|
||||
gnc_session_load_from_xml_file_v2(session, NULL);
|
||||
gnc_session_load_from_xml_file_v2(session);
|
||||
|
||||
book = gnc_session_get_book (session);
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ test_file(const char *filename)
|
||||
return g_strdup_printf("gnc_session_begin errorid %d", err);
|
||||
}
|
||||
|
||||
gnc_session_load(session);
|
||||
gnc_session_load(session, NULL);
|
||||
err = gnc_session_pop_error (session);
|
||||
if(err)
|
||||
{
|
||||
@@ -109,7 +109,7 @@ test_file(const char *filename)
|
||||
possible_envs[i]);
|
||||
}
|
||||
|
||||
gnc_session_save(new_session);
|
||||
gnc_session_save(new_session, NULL);
|
||||
|
||||
cmd = g_strdup_printf(diff_command, filename, new_file);
|
||||
|
||||
|
||||
@@ -2108,6 +2108,8 @@ pgend_session_begin (Backend *backend,
|
||||
be->be.sync_all = pgendSyncSingleFile;
|
||||
be->be.sync_group = NULL;
|
||||
be->be.sync_price = pgendSyncPriceDBSingleFile;
|
||||
be->be.export = NULL;
|
||||
be->be.percentage = NULL;
|
||||
be->be.events_pending = NULL;
|
||||
be->be.process_events = NULL;
|
||||
PWARN ("mode=single-file is final beta -- \n"
|
||||
@@ -2133,6 +2135,8 @@ pgend_session_begin (Backend *backend,
|
||||
be->be.sync_all = pgendSync;
|
||||
be->be.sync_group = NULL;
|
||||
be->be.sync_price = pgendSyncPriceDB;
|
||||
be->be.export = NULL;
|
||||
be->be.percentage = NULL;
|
||||
be->be.events_pending = NULL;
|
||||
be->be.process_events = NULL;
|
||||
PWARN ("mode=single-update is final beta -- \n"
|
||||
@@ -2158,6 +2162,8 @@ pgend_session_begin (Backend *backend,
|
||||
be->be.sync_all = pgendSync;
|
||||
be->be.sync_group = NULL;
|
||||
be->be.sync_price = pgendSyncPriceDB;
|
||||
be->be.export = NULL;
|
||||
be->be.percentage = NULL;
|
||||
be->be.events_pending = NULL;
|
||||
be->be.process_events = NULL;
|
||||
|
||||
@@ -2188,6 +2194,8 @@ pgend_session_begin (Backend *backend,
|
||||
be->be.sync_all = pgendSync;
|
||||
be->be.sync_group = NULL;
|
||||
be->be.sync_price = pgendSyncPriceDB;
|
||||
be->be.export = NULL;
|
||||
be->be.percentage = NULL;
|
||||
be->be.events_pending = pgendEventsPending;
|
||||
be->be.process_events = pgendProcessEvents;
|
||||
|
||||
@@ -2239,6 +2247,8 @@ pgendDisable (PGBackend *be)
|
||||
be->snr.sync_all = be->be.sync_all;
|
||||
be->snr.sync_group = be->be.sync_group;
|
||||
be->snr.sync_price = be->be.sync_price;
|
||||
be->snr.export = be->be.export;
|
||||
be->snr.percentage = be->be.percentage;
|
||||
be->snr.events_pending = be->be.events_pending;
|
||||
be->snr.process_events = be->be.process_events;
|
||||
|
||||
@@ -2260,6 +2270,8 @@ pgendDisable (PGBackend *be)
|
||||
be->be.sync_all = NULL;
|
||||
be->be.sync_group = NULL;
|
||||
be->be.sync_price = NULL;
|
||||
be->be.export = NULL;
|
||||
be->be.percentage = NULL;
|
||||
be->be.events_pending = NULL;
|
||||
be->be.process_events = NULL;
|
||||
}
|
||||
@@ -2296,6 +2308,8 @@ pgendEnable (PGBackend *be)
|
||||
be->be.sync_all = be->snr.sync_all;
|
||||
be->be.sync_group = be->snr.sync_group;
|
||||
be->be.sync_price = be->snr.sync_price;
|
||||
be->be.export = be->snr.export;
|
||||
be->be.percentage = be->snr.percentage;
|
||||
be->be.events_pending = be->snr.events_pending;
|
||||
be->be.process_events = be->snr.process_events;
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@ static void rpcendEnable (RPCBackend *be)
|
||||
be->be.price_lookup = be->snr.price_lookup;
|
||||
be->be.sync_all = be->snr.sync_all;
|
||||
be->be.sync_price = be->snr.sync_price;
|
||||
be->be.export = be->snr.export;
|
||||
be->be.percentage = be->snr.percentage;
|
||||
}
|
||||
|
||||
static void rpcendDisable (RPCBackend *be)
|
||||
@@ -127,6 +129,8 @@ static void rpcendDisable (RPCBackend *be)
|
||||
be->snr.price_lookup = be->be.price_lookup;
|
||||
be->snr.sync_all = be->be.sync_all;
|
||||
be->snr.sync_price = be->be.sync_price;
|
||||
be->snr.export = be->be.export;
|
||||
be->snr.percentage = be->be.percentage;
|
||||
|
||||
/* And turn off future calls */
|
||||
be->be.account_begin_edit = NULL;
|
||||
@@ -140,6 +144,8 @@ static void rpcendDisable (RPCBackend *be)
|
||||
be->be.price_lookup = NULL;
|
||||
be->be.sync_all = NULL;
|
||||
be->be.sync_price = NULL;
|
||||
be->be.export = NULL;
|
||||
be->be.percentage = NULL;
|
||||
}
|
||||
|
||||
static void myClose (void *arg)
|
||||
@@ -977,6 +983,8 @@ rpcend_session_begin (Backend *backend,
|
||||
be->be.price_lookup = rpcend_price_lookup;
|
||||
be->be.sync_all = rpcend_sync_all;
|
||||
be->be.sync_price = rpcend_sync_price;
|
||||
be->be.export = NULL;
|
||||
be->be.percentage = NULL;
|
||||
be->be.events_pending = rpcend_events_pending;
|
||||
be->be.process_events = rpcend_process_events;
|
||||
|
||||
|
||||
@@ -121,6 +121,8 @@ xaccInitBackend(Backend *be)
|
||||
be->sync_all = NULL;
|
||||
be->sync_group = NULL;
|
||||
be->sync_price = NULL;
|
||||
be->export = NULL;
|
||||
be->percentage = NULL;
|
||||
|
||||
be->events_pending = NULL;
|
||||
be->process_events = NULL;
|
||||
|
||||
@@ -95,4 +95,6 @@ typedef enum {
|
||||
|
||||
typedef struct backend_s Backend;
|
||||
|
||||
typedef void (*GNCBePercentageFunc) (const char *message, int percent);
|
||||
|
||||
#endif /* XACC_BACKEND_H */
|
||||
|
||||
@@ -245,6 +245,10 @@ struct backend_s
|
||||
void (*sync_group) (Backend *, GNCBook *);
|
||||
void (*sync_price) (Backend *, GNCBook *);
|
||||
|
||||
void (*export) (Backend *, GNCBook *);
|
||||
|
||||
GNCBePercentageFunc percentage;
|
||||
|
||||
gint64 (*counter) (Backend *, const char *counter_name);
|
||||
|
||||
gboolean (*events_pending) (Backend *be);
|
||||
|
||||
@@ -35,6 +35,7 @@ libgncmod_engine_la_SOURCES = \
|
||||
gnc-numeric.c \
|
||||
gnc-pricedb.c \
|
||||
gnc-session.c \
|
||||
gnc-session-scm.c \
|
||||
gncmod-engine.c \
|
||||
guid.c \
|
||||
gncObject.c \
|
||||
@@ -73,6 +74,7 @@ gncinclude_HEADERS = \
|
||||
gnc-numeric.h \
|
||||
gnc-pricedb.h \
|
||||
gnc-session.h \
|
||||
gnc-session-scm.h \
|
||||
guid.h \
|
||||
gncObject.h \
|
||||
kvp_frame.h \
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
(gnc:session-begin session url
|
||||
ignore-lock?
|
||||
create-if-needed?)
|
||||
(gnc:session-load session)
|
||||
(gnc:session-load session #f)
|
||||
session)))
|
||||
(or result
|
||||
(begin (gnc:session-destroy session) #f))))
|
||||
|
||||
@@ -269,6 +269,13 @@ gnc_book_set_backend (GNCBook *book, Backend *be)
|
||||
book->backend = be;
|
||||
}
|
||||
|
||||
gpointer gnc_book_get_backend (GNCBook *book)
|
||||
{
|
||||
if (!book) return NULL;
|
||||
return (gpointer)book->backend;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gnc_book_set_pricedb(GNCBook *book, GNCPriceDB *db)
|
||||
{
|
||||
|
||||
@@ -73,6 +73,8 @@ AccountGroup * gnc_book_get_template_group( GNCBook *book );
|
||||
void gnc_book_set_data (GNCBook *book, const char *key, gpointer data);
|
||||
gpointer gnc_book_get_data (GNCBook *book, const char *key);
|
||||
|
||||
gpointer gnc_book_get_backend (GNCBook *book);
|
||||
|
||||
/*
|
||||
* The gnc_book_not_saved() subroutine will return TRUE if any
|
||||
* data in the book hasn't been saved to long-term storage.
|
||||
|
||||
104
src/engine/gnc-session-scm.c
Normal file
104
src/engine/gnc-session-scm.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/********************************************************************\
|
||||
* gnc-sesssion.c -- session access (connection to backend) *
|
||||
* Scheme specific code. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
/*
|
||||
* FILE:
|
||||
* gnc-session-scm.c
|
||||
*
|
||||
* FUNCTION:
|
||||
* Encapsulate a connection to a GnuCash backend.
|
||||
*
|
||||
* HISTORY:
|
||||
* Created by David Hampton, September 2002
|
||||
* Copyright (c) 2002 Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "BackendP.h"
|
||||
#include "TransLog.h"
|
||||
#include "gnc-engine-util.h"
|
||||
#include "DateUtils.h"
|
||||
#include "gnc-book-p.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-engine-util.h"
|
||||
#include "gnc-module.h"
|
||||
#include "gnc-session-p.h"
|
||||
#include "gnc-session-scm.h"
|
||||
|
||||
//static short module = MOD_IO;
|
||||
|
||||
static SCM gnc_session_scm_gui_cb = SCM_BOOL_F;
|
||||
|
||||
static void
|
||||
gnc_session_scm_gui_cb_helper (const char *message, int percent)
|
||||
{
|
||||
if (gnc_session_scm_gui_cb != SCM_BOOL_F) {
|
||||
SCM string = gh_str02scm(message);
|
||||
SCM scm_percent = gh_long2scm(percent);
|
||||
gh_call2 (gnc_session_scm_gui_cb, string, scm_percent);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gnc_session_scm_load (GNCSession *session)
|
||||
{
|
||||
gnc_session_load (session, gnc_session_scm_gui_cb_helper);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_session_scm_save (GNCSession *session)
|
||||
{
|
||||
gnc_session_save (session, gnc_session_scm_gui_cb_helper);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_session_scm_export (GNCSession *tmp_session, GNCSession *real_session)
|
||||
{
|
||||
return gnc_session_export(tmp_session, real_session,
|
||||
gnc_session_scm_gui_cb_helper);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the callback that will be used for any calls to the session
|
||||
* load/save functions from the scheme side of the code.
|
||||
*/
|
||||
void
|
||||
gnc_session_scm_set_callback (SCM percentage_cb)
|
||||
{
|
||||
if (gnc_session_scm_gui_cb != SCM_BOOL_F)
|
||||
scm_unprotect_object(gnc_session_scm_gui_cb);
|
||||
|
||||
gnc_session_scm_gui_cb = percentage_cb;
|
||||
if (gnc_session_scm_gui_cb != SCM_BOOL_F)
|
||||
scm_protect_object(gnc_session_scm_gui_cb);
|
||||
}
|
||||
|
||||
50
src/engine/gnc-session-scm.h
Normal file
50
src/engine/gnc-session-scm.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/********************************************************************\
|
||||
* gnc-session-scm.h -- session access (connection to backend) *
|
||||
* Scheme specific code. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
/*
|
||||
* FILE:
|
||||
* gnc-session-scm.h
|
||||
*
|
||||
* FUNCTION:
|
||||
* Encapsulates a connection to a GnuCash backend. That is, it
|
||||
* manages the connection to a persistant data store; whereas
|
||||
* the backend is the thing that performs the actual datastore
|
||||
* access.
|
||||
*
|
||||
* HISTORY:
|
||||
* Created by David Hampton, September 2002
|
||||
* Copyright (c) 2002 Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
|
||||
#ifndef GNC_SESSION_SCM_H
|
||||
#define GNC_SESSION_SCM_H
|
||||
|
||||
#include <guile/gh.h>
|
||||
|
||||
void gnc_session_scm_load (GNCSession *session);
|
||||
gboolean gnc_session_scm_export (GNCSession *tmp_session,
|
||||
GNCSession *real_session);
|
||||
void gnc_session_scm_save (GNCSession *session);
|
||||
void gnc_session_scm_set_callback (SCM percentage_cb);
|
||||
|
||||
#endif /* GNC_SESSION_SCM_H */
|
||||
@@ -415,7 +415,8 @@ gnc_session_begin (GNCSession *session, const char * book_id,
|
||||
/* ====================================================================== */
|
||||
|
||||
void
|
||||
gnc_session_load (GNCSession *session)
|
||||
gnc_session_load (GNCSession *session,
|
||||
GNCPercentageFunc percentage_func)
|
||||
{
|
||||
GNCBook *newbook;
|
||||
BookList *oldbooks, *node;
|
||||
@@ -448,6 +449,7 @@ gnc_session_load (GNCSession *session)
|
||||
* generic, backend-independent operation.
|
||||
*/
|
||||
be = session->backend;
|
||||
gnc_book_set_backend(newbook, be);
|
||||
|
||||
/* Starting the session should result in a bunch of accounts
|
||||
* and currencies being downloaded, but probably no transactions;
|
||||
@@ -456,6 +458,7 @@ gnc_session_load (GNCSession *session)
|
||||
if (be)
|
||||
{
|
||||
xaccLogDisable();
|
||||
be->percentage = percentage_func;
|
||||
|
||||
if (be->book_load)
|
||||
{
|
||||
@@ -471,8 +474,6 @@ gnc_session_load (GNCSession *session)
|
||||
gnc_session_push_error(session, xaccBackendGetError(be), NULL);
|
||||
}
|
||||
|
||||
gnc_book_set_backend (newbook, be);
|
||||
|
||||
/* we just got done loading, it can't possibly be dirty !! */
|
||||
gnc_book_mark_saved (newbook);
|
||||
|
||||
@@ -566,7 +567,8 @@ save_error_handler(Backend *be, GNCSession *session)
|
||||
}
|
||||
|
||||
void
|
||||
gnc_session_save (GNCSession *session)
|
||||
gnc_session_save (GNCSession *session,
|
||||
GNCPercentageFunc percentage_func)
|
||||
{
|
||||
GList *node;
|
||||
Backend *be;
|
||||
@@ -596,6 +598,7 @@ gnc_session_save (GNCSession *session)
|
||||
|
||||
/* if invoked as SaveAs(), then backend not yet set */
|
||||
gnc_book_set_backend (abook, be);
|
||||
be->percentage = percentage_func;
|
||||
|
||||
if (be->sync_all)
|
||||
{
|
||||
@@ -636,6 +639,42 @@ gnc_session_save (GNCSession *session)
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
gboolean
|
||||
gnc_session_export (GNCSession *tmp_session,
|
||||
GNCSession *real_session,
|
||||
GNCPercentageFunc percentage_func)
|
||||
{
|
||||
GNCBook *book;
|
||||
Backend *be;
|
||||
|
||||
if ((!tmp_session) || (!real_session)) return FALSE;
|
||||
|
||||
book = gnc_session_get_book (real_session);
|
||||
ENTER ("tmp_session=%p real_session=%p book=%p book_id=%s",
|
||||
tmp_session, real_session, book,
|
||||
gnc_session_get_url(tmp_session)
|
||||
? gnc_session_get_url(tmp_session) : "(null)");
|
||||
|
||||
/* There must be a backend or else. (It should always be the file
|
||||
* backend too.)
|
||||
*/
|
||||
be = tmp_session->backend;
|
||||
if (!be)
|
||||
return FALSE;
|
||||
|
||||
be->percentage = percentage_func;
|
||||
if (be->export)
|
||||
{
|
||||
|
||||
(be->export)(be, book);
|
||||
if (save_error_handler(be, tmp_session)) return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
void
|
||||
gnc_session_end (GNCSession *session)
|
||||
{
|
||||
|
||||
@@ -148,7 +148,12 @@ void gnc_session_begin (GNCSession *session, const char * book_id,
|
||||
* to make the book actually usable; it would not cause *all* of the
|
||||
* data to be loaded.
|
||||
*/
|
||||
void gnc_session_load (GNCSession *session);
|
||||
typedef void (*GNCPercentageFunc) (const char *message, int percent);
|
||||
void gnc_session_load (GNCSession *session,
|
||||
GNCPercentageFunc percentage_func);
|
||||
gboolean gnc_session_export (GNCSession *tmp_session,
|
||||
GNCSession *real_session,
|
||||
GNCPercentageFunc percentage_func);
|
||||
|
||||
/* The gnc_session_get_error() routine can be used to obtain the reason
|
||||
* for any failure. Calling this routine returns the current error.
|
||||
@@ -208,7 +213,8 @@ gboolean gnc_session_save_may_clobber_data (GNCSession *session);
|
||||
* been written out before this, and so this routines wouldn't
|
||||
* roll-back anything; it would just shut the connection.
|
||||
*/
|
||||
void gnc_session_save (GNCSession *session);
|
||||
void gnc_session_save (GNCSession *session,
|
||||
GNCPercentageFunc percentage_func);
|
||||
void gnc_session_end (GNCSession *session);
|
||||
|
||||
/* The gnc_session_events_pending() method will return TRUE if the backend
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"#include <Group.h>\n"
|
||||
"#include <gnc-book.h>\n"
|
||||
"#include <gnc-session.h>\n"
|
||||
"#include <gnc-session-scm.h>\n"
|
||||
"#include <gnc-engine-util.h>\n"
|
||||
"#include <gnc-event.h>\n"
|
||||
"#include <gnc-lot.h>\n"
|
||||
@@ -1362,7 +1363,7 @@ when no longer needed.")
|
||||
ws
|
||||
'gnc:session-load
|
||||
'<gw:void>
|
||||
"gnc_session_load"
|
||||
"gnc_session_scm_load"
|
||||
'((<gnc:Session*> session))
|
||||
"Load the data associated with the given session.")
|
||||
|
||||
@@ -1370,10 +1371,28 @@ when no longer needed.")
|
||||
ws
|
||||
'gnc:session-save
|
||||
'<gw:void>
|
||||
"gnc_session_save"
|
||||
"gnc_session_scm_save"
|
||||
'((<gnc:Session*> session))
|
||||
"Save the data in the session.")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:session-export
|
||||
'<gw:bool>
|
||||
"gnc_session_scm_export"
|
||||
'((<gnc:Session*> tmp_session) (<gnc:Session*> real_session))
|
||||
"Export the accounts in the session.")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:session-set-callback
|
||||
'<gw:void>
|
||||
"gnc_session_scm_set_callback"
|
||||
'((<gw:scm> callback))
|
||||
"Setup a callback for the load/save functions to provide progress
|
||||
reports. This function will be called with a string and an integer
|
||||
argument between 0 and 100 (inclusive).")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:session-end
|
||||
|
||||
@@ -6,6 +6,7 @@ AM_CFLAGS = \
|
||||
-I${top_srcdir}/src/gnc-module \
|
||||
-I${top_srcdir}/src/engine \
|
||||
-I${top_srcdir}/src/network-utils \
|
||||
-I${top_srcdir}/src/app-file \
|
||||
-I${top_srcdir}/src/app-utils \
|
||||
-I${top_srcdir}/src \
|
||||
${GUILE_INCS} \
|
||||
@@ -85,6 +86,7 @@ libgncmod_gnome_utils_la_LIBADD = \
|
||||
${top_builddir}/src/engine/libgncmod-engine.la \
|
||||
${top_builddir}/src/calculation/libgncmod-calculation.la \
|
||||
${top_builddir}/src/network-utils/libgncmod-network-utils.la \
|
||||
${top_builddir}/src/app-file/libgncmod-app-file.la \
|
||||
${top_builddir}/src/app-utils/libgncmod-app-utils.la \
|
||||
${GUILE_LIBS} \
|
||||
${GUPPI_LIBS} \
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "dialog-utils.h"
|
||||
#include "global-options.h"
|
||||
#include "gnc-component-manager.h"
|
||||
#include "gnc-file.h"
|
||||
#include "gnc-html.h"
|
||||
#include "gnc-mdi-utils.h"
|
||||
#include "gnc-ui-util.h"
|
||||
@@ -96,6 +97,34 @@ gnc_mdi_set_toolbar_visibility (gboolean visible)
|
||||
gnc_toolbar_visible = visible;
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_mdi_file_percentage (const char *message, int percentage)
|
||||
{
|
||||
GtkWidget *app;
|
||||
GnomeAppBar *appbar;
|
||||
|
||||
app = gnc_ui_get_toplevel();
|
||||
if (app == NULL)
|
||||
return;
|
||||
if (GNOME_APP(app)->statusbar == NULL)
|
||||
return;
|
||||
|
||||
appbar = GNOME_APPBAR(GNOME_APP(app)->statusbar);
|
||||
|
||||
if (percentage < 0) {
|
||||
gnome_appbar_refresh(appbar);
|
||||
gnome_appbar_set_progress(appbar, 0.0);
|
||||
} else {
|
||||
if (message)
|
||||
gnome_appbar_set_status(appbar, message);
|
||||
gnome_appbar_set_progress(appbar, ((gfloat)percentage)/100);
|
||||
}
|
||||
|
||||
/* make sure new text is up */
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration ();
|
||||
}
|
||||
|
||||
/**
|
||||
* gnc_mdi_widget_show
|
||||
*
|
||||
@@ -490,6 +519,8 @@ gnc_mdi_app_created_cb (GnomeMDI * mdi, GnomeApp * app, gpointer data)
|
||||
/* enable save and restore of menubar positions */
|
||||
gnome_app_enable_layout_config (app, TRUE);
|
||||
|
||||
gnc_file_set_pct_handler (gnc_mdi_file_percentage);
|
||||
|
||||
/* flag the app as gnc mdi created */
|
||||
gtk_object_set_data (GTK_OBJECT (app), "gnc_mdi", mainwin);
|
||||
|
||||
|
||||
@@ -115,6 +115,14 @@
|
||||
'(((<gw:mchars> caller-owned const) string))
|
||||
"Update the progress box on the splash screen dialog.")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:destroy-splash-screen
|
||||
'<gw:void>
|
||||
"gnc_destroy_splash_screen"
|
||||
'()
|
||||
"Destroy the splash screen dialog.")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:gui-shutdown
|
||||
|
||||
@@ -405,7 +405,6 @@ gnc_gui_init (SCM command_line)
|
||||
/* initialize gnome MDI and set up application window defaults */
|
||||
if (!gnc_mdi_get_current ())
|
||||
gnc_main_window_new ();
|
||||
gnc_destroy_splash_screen();
|
||||
|
||||
/* Run the ui startup hooks. */
|
||||
{
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
#include "gnc-menu-extensions.h"
|
||||
#include "gnc-ui.h"
|
||||
#include "guile-util.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
#include "mainwindow-account-tree.h"
|
||||
#include "option-util.h"
|
||||
#include "top-level.h"
|
||||
@@ -173,7 +172,7 @@ gnc_main_window_app_created_cb(GnomeMDI * mdi, GnomeApp * app,
|
||||
}
|
||||
|
||||
/* add the statusbar */
|
||||
statusbar = gnome_appbar_new(FALSE, TRUE, GNOME_PREFERENCES_USER);
|
||||
statusbar = gnome_appbar_new(TRUE, TRUE, GNOME_PREFERENCES_USER);
|
||||
gnome_app_set_statusbar(app, statusbar);
|
||||
|
||||
/* set up extensions menu and hints */
|
||||
@@ -519,71 +518,8 @@ gnc_main_window_file_save_as_cb(GtkWidget * widget, gpointer data)
|
||||
static void
|
||||
gnc_main_window_file_export_cb(GtkWidget * widget, gpointer data)
|
||||
{
|
||||
const char *filename;
|
||||
struct stat statbuf;
|
||||
gboolean ok;
|
||||
FILE *file;
|
||||
int rc;
|
||||
|
||||
filename = gnc_file_dialog (_("Export"), NULL, NULL);
|
||||
if (!filename)
|
||||
return;
|
||||
|
||||
rc = stat (filename, &statbuf);
|
||||
|
||||
/* Check for an error that isn't a non-existent file. */
|
||||
if (rc != 0 && errno != ENOENT)
|
||||
{
|
||||
const char *format = _("You cannot save to that filename.\n\n%s");
|
||||
|
||||
gnc_error_dialog_parented (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
|
||||
format, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for a file that isn't a regular file. */
|
||||
if (rc == 0 && !S_ISREG (statbuf.st_mode))
|
||||
{
|
||||
const char *message = _("You cannot save to that file.");
|
||||
|
||||
gnc_error_dialog_parented (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
|
||||
message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
const char *format = _("The file \n %s\n already exists.\n"
|
||||
"Are you sure you want to overwrite it?");
|
||||
if (!gnc_verify_dialog_parented (gtk_widget_get_toplevel (widget),
|
||||
FALSE, format, filename))
|
||||
return;
|
||||
}
|
||||
|
||||
file = fopen (filename, "w");
|
||||
if (!file)
|
||||
{
|
||||
const char *format = _("You cannot save to that file.\n\n%s");
|
||||
|
||||
gnc_error_dialog_parented (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
|
||||
format, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
ok = gnc_book_write_accounts_to_xml_filehandle_v2 (gnc_get_current_book (),
|
||||
file);
|
||||
|
||||
if (fclose (file) != 0)
|
||||
ok = FALSE;
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
const char *format = _("There was an error saving the file.\n\n%s");
|
||||
|
||||
gnc_error_dialog_parented (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
|
||||
format, strerror(errno));
|
||||
return;
|
||||
}
|
||||
gnc_file_export_file(NULL);
|
||||
gnc_refresh_main_window_info ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
(simple-format #t "using book name='~A'\n" name)
|
||||
(gnc:book-set-group book group)
|
||||
(gnc:session-begin session name #t #t)
|
||||
(gnc:session-save book)
|
||||
(gnc:session-save book #f)
|
||||
(gnc:session-end book)))))
|
||||
0)
|
||||
|
||||
|
||||
@@ -394,7 +394,7 @@ string and 'directories' must be a list of strings."
|
||||
(bootstrap (resolve-module '(gnucash main))))
|
||||
|
||||
(define (load-module name vers optional?)
|
||||
(let ((str (string-append "Loading modules... " name)))
|
||||
(let ((str (string-append (_ "Loading modules... ") name)))
|
||||
(gnc:update-splash-screen str)
|
||||
(if optional?
|
||||
(gnc:module-load-optional name vers)
|
||||
@@ -404,7 +404,6 @@ string and 'directories' must be a list of strings."
|
||||
|
||||
;; right now we have to statically load all these at startup time.
|
||||
;; Hopefully we can gradually make them autoloading.
|
||||
(gnc:update-splash-screen "Loading modules...")
|
||||
(load-module "gnucash/engine" 0 #f)
|
||||
|
||||
(load-module "gnucash/app-file" 0 #f)
|
||||
@@ -432,7 +431,7 @@ string and 'directories' must be a list of strings."
|
||||
;; +jsled - 2002.07.08
|
||||
(load-from-path "fin.scm")
|
||||
|
||||
(gnc:update-splash-screen "Loading tip-of-the-day...")
|
||||
(gnc:update-splash-screen (_ "Loading tip-of-the-day..."))
|
||||
(gnc:initialize-tip-of-the-day)
|
||||
|
||||
(gnc:use-guile-module-here! '(gnucash price-quotes))
|
||||
@@ -456,7 +455,7 @@ string and 'directories' must be a list of strings."
|
||||
(gnc:ui-hierarchy-druid)))))
|
||||
|
||||
;; Load the system configs
|
||||
(gnc:update-splash-screen "Loading configs...")
|
||||
(gnc:update-splash-screen (_ "Loading configs..."))
|
||||
(if (not (gnc:load-system-config-if-needed))
|
||||
(gnc:shutdown 1))
|
||||
|
||||
@@ -520,9 +519,11 @@ string and 'directories' must be a list of strings."
|
||||
|
||||
(define (gnc:load-account-file)
|
||||
(let ((file (gnc:account-file-to-load)))
|
||||
(if file
|
||||
(and (not (gnc:file-open-file file))
|
||||
(gnc:hook-run-danglers gnc:*book-opened-hook* #f))
|
||||
(if file
|
||||
(begin
|
||||
(gnc:update-splash-screen (_ "Loading data..."))
|
||||
(and (not (gnc:file-open-file file))
|
||||
(gnc:hook-run-danglers gnc:*book-opened-hook* #f)))
|
||||
(gnc:hook-run-danglers gnc:*book-opened-hook* #f))))
|
||||
|
||||
(define (gnc:main)
|
||||
@@ -570,7 +571,9 @@ string and 'directories' must be a list of strings."
|
||||
(gnc:option-value
|
||||
(gnc:lookup-global-option "__new_user" "first_startup")))
|
||||
(gnc:new-user-dialog)
|
||||
(gnc:load-account-file))
|
||||
(begin
|
||||
(gnc:load-account-file)
|
||||
(gnc:destroy-splash-screen)))
|
||||
(gnc:start-ui-event-loop)
|
||||
(gnc:hook-remove-dangler gnc:*ui-shutdown-hook* gnc:gui-finish))
|
||||
|
||||
|
||||
@@ -709,7 +709,7 @@ Run 'update-finance-quote' as root to install them.") "\n")))
|
||||
(gnc:session-get-book session)))))
|
||||
|
||||
(if (not quote-ok?) (gnc:msg "book-add-quotes failed"))
|
||||
(and session (gnc:session-save session))
|
||||
(and session (gnc:session-save session #f))
|
||||
(if (not (eq? 'no-err
|
||||
(gw:enum-<gnc:BackendError>-val->sym
|
||||
(gnc:session-get-error session) #f)))
|
||||
|
||||
Reference in New Issue
Block a user