diff --git a/src/engine/Account.c b/src/engine/Account.c index 3207baca79..bb1e9b6ed4 100644 --- a/src/engine/Account.c +++ b/src/engine/Account.c @@ -1063,6 +1063,7 @@ static void on_done(QofInstance *inst) static void on_err (QofInstance *inst, QofBackendError errcode) { PERR("commit error: %d", errcode); + gnc_engine_signal_commit_error( errcode ); } static void acc_free (QofInstance *inst) diff --git a/src/engine/SchedXaction.c b/src/engine/SchedXaction.c index 8da9465321..441cd7203d 100644 --- a/src/engine/SchedXaction.c +++ b/src/engine/SchedXaction.c @@ -219,6 +219,7 @@ gnc_sx_begin_edit (SchedXaction *sx) static void commit_err (QofInstance *inst, QofBackendError errcode) { g_critical("Failed to commit: %d", errcode); + gnc_engine_signal_commit_error( errcode ); } static void commit_done(QofInstance *inst) diff --git a/src/engine/Split.c b/src/engine/Split.c index 64b6a16c86..1cf42655da 100644 --- a/src/engine/Split.c +++ b/src/engine/Split.c @@ -498,6 +498,12 @@ xaccSplitSetAccount (Split *s, Account *acc) xaccTransCommitEdit(trans); } +static void commit_err (QofInstance *inst, QofBackendError errcode) +{ + PERR("commit error: %d", errcode); + gnc_engine_signal_commit_error( errcode ); +} + /* An engine-private helper for completing xaccTransCommitEdit(). */ void xaccSplitCommitEdit(Split *s) @@ -551,7 +557,7 @@ xaccSplitCommitEdit(Split *s) original and new transactions, for the _next_ begin/commit cycle. */ s->orig_acc = s->acc; s->orig_parent = s->parent; - qof_commit_edit_part2(QOF_INSTANCE(s), NULL, NULL, + qof_commit_edit_part2(QOF_INSTANCE(s), commit_err, NULL, (void (*) (QofInstance *)) xaccFreeSplit); if (acc) { diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index 83f57cdda9..20293fa418 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -940,6 +940,7 @@ static void trans_on_error(Transaction *trans, QofBackendError errcode) } xaccTransRollbackEdit(trans); + gnc_engine_signal_commit_error( errcode ); } static void trans_cleanup_commit(Transaction *trans) diff --git a/src/engine/gnc-budget.c b/src/engine/gnc-budget.c index 5a610e02c2..9af51bc5b7 100644 --- a/src/engine/gnc-budget.c +++ b/src/engine/gnc-budget.c @@ -232,6 +232,7 @@ gnc_budget_class_init(GncBudgetClass* klass) static void commit_err (QofInstance *inst, QofBackendError errcode) { PERR ("Failed to commit: %d", errcode); + gnc_engine_signal_commit_error( errcode ); } static void diff --git a/src/engine/gnc-commodity.c b/src/engine/gnc-commodity.c index 8f7819398c..8a192d585e 100644 --- a/src/engine/gnc-commodity.c +++ b/src/engine/gnc-commodity.c @@ -519,6 +519,7 @@ gnc_commodity_begin_edit (gnc_commodity *cm) static void commit_err (QofInstance *inst, QofBackendError errcode) { PERR ("Failed to commit: %d", errcode); + gnc_engine_signal_commit_error( errcode ); } static void noop (QofInstance *inst) {} diff --git a/src/engine/gnc-engine.c b/src/engine/gnc-engine.c index 0f0f53a84a..f80c58d37d 100644 --- a/src/engine/gnc-engine.c +++ b/src/engine/gnc-engine.c @@ -43,6 +43,10 @@ static GList * engine_init_hooks = NULL; static int engine_is_initialized = 0; + +EngineCommitErrorCallback g_error_cb; +gpointer g_error_cb_data; + // static QofLogModule log_module = GNC_MOD_ENGINE; /* GnuCash version functions */ @@ -165,3 +169,17 @@ void gnc_log_default(void) qof_log_set_level(GNC_MOD_TEST, QOF_LOG_DEBUG); } +void +gnc_engine_add_commit_error_callback( EngineCommitErrorCallback cb, gpointer data ) +{ + g_error_cb = cb; + g_error_cb_data = data; +} + +void +gnc_engine_signal_commit_error( QofBackendError errcode ) +{ + if( g_error_cb != NULL ) { + (*g_error_cb)( g_error_cb_data, errcode ); + } +} diff --git a/src/engine/gnc-engine.h b/src/engine/gnc-engine.h index b9627f244c..bc22b200c1 100644 --- a/src/engine/gnc-engine.h +++ b/src/engine/gnc-engine.h @@ -208,6 +208,7 @@ typedef GList AccountGUIDList; /** GList of GUIDs of a GNCBook */ typedef GList BookGUIDList; +typedef void (*EngineCommitErrorCallback)( gpointer data, QofBackendError errcode ); typedef gint (*SplitCallback)(Split *s, gpointer data); typedef gint (*TransactionCallback)(Transaction *t, void *data); @@ -244,5 +245,11 @@ void gnc_log_default(void); * it will be called during the evaluation of gnc_engine_init */ void gnc_engine_add_init_hook(gnc_engine_init_hook_t hook); +/** Set a callback function to be called in case an engine commit + * fails */ +void gnc_engine_add_commit_error_callback( EngineCommitErrorCallback cb, gpointer data ); + +void gnc_engine_signal_commit_error( QofBackendError errcode ); + #endif /** @} */ diff --git a/src/engine/gnc-lot.c b/src/engine/gnc-lot.c index a5ae770a7e..9e92264c1f 100644 --- a/src/engine/gnc-lot.c +++ b/src/engine/gnc-lot.c @@ -143,6 +143,7 @@ gnc_lot_begin_edit (GNCLot *lot) static void commit_err (QofInstance *inst, QofBackendError errcode) { PERR ("Failed to commit: %d", errcode); + gnc_engine_signal_commit_error( errcode ); } static void lot_free(QofInstance* inst) diff --git a/src/engine/gnc-pricedb.c b/src/engine/gnc-pricedb.c index 45062dce61..dc0f9bc4c0 100644 --- a/src/engine/gnc-pricedb.c +++ b/src/engine/gnc-pricedb.c @@ -160,6 +160,7 @@ gnc_price_begin_edit (GNCPrice *p) static void commit_err (QofInstance *inst, QofBackendError errcode) { PERR ("Failed to commit: %d", errcode); + gnc_engine_signal_commit_error( errcode ); } static void noop (QofInstance *inst) {} diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c index 028fe0762e..8ff55b6e35 100644 --- a/src/gnome-utils/gnc-main-window.c +++ b/src/gnome-utils/gnc-main-window.c @@ -122,6 +122,7 @@ static void gnc_main_window_page_reordered (GtkNotebook *notebook, GtkWidget *ch #endif static void gnc_main_window_plugin_added (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window); static void gnc_main_window_plugin_removed (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window); +static void gnc_main_window_engine_commit_error_callback( gpointer data, QofBackendError errcode ); /* Command callbacks */ #ifdef HAVE_GTK_2_10 @@ -2039,6 +2040,9 @@ gnc_main_window_new (void) active_windows = g_list_append (active_windows, window); gnc_main_window_update_title(window); gnc_main_window_update_all_menu_items(); + + gnc_engine_add_commit_error_callback( gnc_main_window_engine_commit_error_callback, window ); + return window; } @@ -2046,6 +2050,23 @@ gnc_main_window_new (void) * Utility Functions * ************************************************************/ +static void +gnc_main_window_engine_commit_error_callback( gpointer data, + QofBackendError errcode ) +{ + GncMainWindow* window = GNC_MAIN_WINDOW(data); + GtkWidget* dialog; + + dialog = gtk_message_dialog_new( GTK_WINDOW(window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Unable to save to database" ); + gtk_dialog_run(GTK_DIALOG (dialog)); + gtk_widget_destroy(dialog); + +} + /** Connect a GncPluginPage to the window. This function will insert * the page in to the window's notebook and its list of active pages. * It will also emit the "inserted" signal on the page, and the