diff --git a/gnucash/gnome-utils/dialog-preferences.c b/gnucash/gnome-utils/dialog-preferences.c
index 5b9e1bf8b8..9b8137dccf 100644
--- a/gnucash/gnome-utils/dialog-preferences.c
+++ b/gnucash/gnome-utils/dialog-preferences.c
@@ -90,8 +90,10 @@ static QofLogModule log_module = GNC_MOD_PREFS;
void gnc_preferences_response_cb(GtkDialog *dialog, gint response, GtkDialog *unused);
void gnc_account_separator_pref_changed_cb (GtkEntry *entry, GtkWidget *dialog);
-gboolean gnc_account_separator_validate_cb (GtkEntry *entry, GdkEvent *event, GtkWidget *dialog);
void gnc_save_on_close_expires_cb (GtkToggleButton *button, GtkWidget *dialog);
+gboolean gnc_preferences_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
/** This data structure holds the information for a single addition to
* the preferences dialog. */
@@ -185,23 +187,96 @@ gnc_account_separator_pref_changed_cb (GtkEntry *entry, GtkWidget *dialog)
}
-gboolean
-gnc_account_separator_validate_cb (GtkEntry *entry, GdkEvent *event, GtkWidget *dialog)
+/** Called when the 'Close' button pressed or preference dialog closes
+ * to check if the account separator is valid.
+ * Offers two choices, to reset separator to original value and exit
+ * or go back to the 'Accounts' page to change separator
+ *
+ * @internal
+ *
+ * @param dialog the prefs dialog.
+ */
+static gboolean
+gnc_account_separator_validate (GtkWidget *dialog)
{
+ GtkWidget *entry = g_object_get_data (G_OBJECT(dialog), "account-separator");
+ gboolean ret = TRUE;
gchar *separator;
- gchar *conflict_msg = gnc_account_separator_is_valid (gtk_entry_get_text (entry), &separator);
+ gchar *conflict_msg = gnc_account_separator_is_valid (gtk_entry_get_text (GTK_ENTRY(entry)), &separator);
/* Check if the new separator clashes with existing account names */
-
if (conflict_msg)
{
- gnc_warning_dialog (GTK_WINDOW (dialog), "%s", conflict_msg);
- g_free ( conflict_msg );
+ GtkWidget *msg_dialog;
+ GtkBuilder *builder;
+ GtkWidget *msg_label;
+ gint response;
+
+ builder = gtk_builder_new();
+ gnc_builder_add_from_file (builder, "dialog-preferences.glade", "separator_validation_dialog");
+
+ msg_dialog = GTK_WIDGET(gtk_builder_get_object (builder, "separator_validation_dialog"));
+
+ msg_label = GTK_WIDGET(gtk_builder_get_object (builder, "conflict_message"));
+
+ gtk_label_set_text (GTK_LABEL(msg_label), conflict_msg);
+
+ g_object_unref (G_OBJECT(builder));
+ gtk_widget_show_all (msg_dialog);
+
+ response = gtk_dialog_run (GTK_DIALOG(msg_dialog));
+ if (response == GTK_RESPONSE_ACCEPT) // reset to original
+ {
+ gchar *original_sep = g_object_get_data (G_OBJECT(entry), "original_text");
+
+ if (original_sep != NULL)
+ gtk_entry_set_text (GTK_ENTRY(entry), original_sep);
+ }
+ else
+ ret = FALSE;
+
+ g_free (conflict_msg);
+ gtk_widget_destroy (msg_dialog);
}
g_free (separator);
- return FALSE;
+ return ret;
}
+
+/** Used to select the 'Accounts' page when the user wants
+ * to return from the account separator validation dialog
+ * to the preference dialog.
+ *
+ * @internal
+ *
+ * @param user_data A pointer to the dialog.
+ */
+static void
+gnc_preferences_select_account_page (GtkDialog *dialog)
+{
+ GtkWidget *notebook = g_object_get_data (G_OBJECT(dialog), NOTEBOOK);
+ GList *children = gtk_container_get_children (GTK_CONTAINER(notebook));
+
+ if (children)
+ {
+ GtkWidget *acc_page = NULL;
+ GList *node;
+
+ for (node = children; node; node = node->next)
+ {
+ if (g_strcmp0 (gtk_widget_get_name (GTK_WIDGET(node->data)), "accounts_page") == 0)
+ acc_page = node->data;
+ }
+
+ if (acc_page)
+ gtk_notebook_set_current_page (GTK_NOTEBOOK(notebook),
+ gtk_notebook_page_num (GTK_NOTEBOOK(notebook),
+ acc_page));
+ }
+ g_list_free (children);
+}
+
+
/** Called when the save-on-close checkbutton is toggled.
* @internal
* @param button the toggle button.
@@ -1096,6 +1171,15 @@ gnc_prefs_connect_date_edit (GNCDateEdit *gde , const gchar *boxname )
/* Callbacks */
/********************/
+gboolean
+gnc_preferences_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ /* need to block this for the account separator test */
+ return TRUE;
+}
+
/** Handle a user click on one of the buttons at the bottom of the
* preference dialog. Also handles delete_window events, which have
* conveniently converted to a response by GtkDialog.
@@ -1118,11 +1202,17 @@ gnc_preferences_response_cb(GtkDialog *dialog, gint response, GtkDialog *unused)
gnc_gnome_help(HF_HELP, HL_GLOBPREFS);
break;
+ case GTK_RESPONSE_DELETE_EVENT:
default:
- gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(dialog));
- gnc_unregister_gui_component_by_data(DIALOG_PREFERENCES_CM_CLASS,
- dialog);
- gtk_widget_destroy(GTK_WIDGET(dialog));
+ if (gnc_account_separator_validate (GTK_WIDGET(dialog)))
+ {
+ gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(dialog));
+ gnc_unregister_gui_component_by_data (DIALOG_PREFERENCES_CM_CLASS,
+ dialog);
+ gtk_widget_destroy (GTK_WIDGET(dialog));
+ }
+ else
+ gnc_preferences_select_account_page (dialog);
break;
}
}
@@ -1239,7 +1329,7 @@ static GtkWidget *
gnc_preferences_dialog_create(GtkWindow *parent)
{
GtkBuilder *builder;
- GtkWidget *dialog, *notebook, *label, *image, *spinner;
+ GtkWidget *dialog, *notebook, *label, *image, *spinner, *entry;
GtkWidget *box, *date, *period, *currency, *fcb, *button;
GHashTable *prefs_table;
GDate* gdate = NULL;
@@ -1304,6 +1394,9 @@ gnc_preferences_dialog_create(GtkWindow *parent)
image = GTK_WIDGET(gtk_builder_get_object (builder, "separator_error"));
g_object_set_data(G_OBJECT(dialog), "separator_error", image);
+ entry = GTK_WIDGET(gtk_builder_get_object (builder, "pref/general/account-separator"));
+ g_object_set_data (G_OBJECT(dialog), "account-separator", entry);
+
spinner = GTK_WIDGET(gtk_builder_get_object (builder, "pref/general/save-on-close-wait-time"));
g_object_set_data(G_OBJECT(dialog), "save_on_close_wait_time", spinner);
@@ -1417,6 +1510,11 @@ gnc_preferences_dialog_create(GtkWindow *parent)
g_object_unref(G_OBJECT(builder));
+ /* save the original account separator incase it changes */
+ g_object_set_data_full (G_OBJECT(entry), "original_text",
+ g_strdup (gtk_entry_get_text (GTK_ENTRY(entry))),
+ g_free);
+
LEAVE("dialog %p", dialog);
return dialog;
}
diff --git a/gnucash/gtkbuilder/dialog-preferences.glade b/gnucash/gtkbuilder/dialog-preferences.glade
index 3233c736c0..43c5745083 100644
--- a/gnucash/gtkbuilder/dialog-preferences.glade
+++ b/gnucash/gtkbuilder/dialog-preferences.glade
@@ -113,6 +113,121 @@
1
10
+
1
100
@@ -126,6 +241,7 @@
600
400
normal
+
@@ -449,6 +565,7 @@
+ accounts_page
True
False
6
@@ -739,6 +856,7 @@
False
start
dialog-warning
+ 3
False
@@ -758,7 +876,6 @@
False
False
-
True