Blob Blame History Raw
From 1a81dffea39196993144d73123055bdaef1eb0e2 Mon Sep 17 00:00:00 2001
From: Robert Fewell <14uBobIT@gmail.com>
Date: Thu, 28 Dec 2023 10:31:57 +0000
Subject: [PATCH 1/5] Bug 799179 - SLR won't allow change from "Reminder" to
 any other state

This was due to a previous commit to remove empty instances. It was not
realised that the GtkTreeModel needed to be in sync with the GList of
instances as the location in the model was being used to find the
location in the GList.

To fix this, a new column 'PTR' was added to the model and populated
with instances, instance or variable depending on depth and these are
used to the required objects.
---
 gnucash/gnome/dialog-sx-since-last-run.c | 318 +++++++++++++++++------
 1 file changed, 237 insertions(+), 81 deletions(-)

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 306238a9724..10b6a1a6820 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -124,7 +124,7 @@ void gnc_sx_slr_model_effect_change (GncSxSlrTreeModelAdapter *model,
                                      GList **created_transaction_guids,
                                      GList **creation_errors);
 
-GtkTreeModel* gnc_sx_get_slr_state_model(void);
+GtkTreeModel* gnc_sx_get_slr_state_model (void);
 
 #define GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER            (gnc_sx_slr_tree_model_adapter_get_type ())
 #define GNC_SX_SLR_TREE_MODEL_ADAPTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_SLR_TREE_MODEL_ADAPTER, GncSxSlrTreeModelAdapter))
@@ -141,6 +141,12 @@ static void close_handler (gpointer user_data);
 static void dialog_destroy_cb (GtkWidget *object, GncSxSinceLastRunDialog *app_dialog);
 static void dialog_response_cb (GtkDialog *dialog, gint response_id, GncSxSinceLastRunDialog *app_dialog);
 
+#define debug_path(fn, text, path) {\
+    gchar *path_string = gtk_tree_path_to_string (path);\
+    fn("%s %s", text, path_string? path_string : "NULL");\
+    g_free (path_string);\
+}
+
 /* ------------------------------------------------------------ */
 
 static void
@@ -334,6 +340,7 @@ gsslrtma_proxy_rows_reordered (GtkTreeModel *treemodel,
 enum
 {
     SLR_MODEL_COL_NAME = 0,
+    SLR_MODEL_COL_INSTANCE_PTR,
     SLR_MODEL_COL_INSTANCE_STATE,
     SLR_MODEL_COL_VARAIBLE_VALUE,
     SLR_MODEL_COL_INSTANCE_VISIBILITY,
@@ -345,11 +352,11 @@ enum
 static void
 gnc_sx_slr_tree_model_adapter_init (GncSxSlrTreeModelAdapter *adapter)
 {
-    // columns:    thing-name, instance-state, variable-value, instance-visible, variable-visible, instance_state_sensitivity, date
-    // at depth=0: <sx>,       N/A,            N/A,            N/A               N/A,              N/A                         N/A
-    // at depth=1: <instance>, <state>,        N/A,            <valid>,          N/A,              <valid>                     <date>
-    // at depth=2: <variable>, N/A,            <value>,        N/A,              <valid>,          N/A                         N/A
-    adapter->real = gtk_tree_store_new (7, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT64);
+    // columns:    thing-name, ptr,       instance-state, variable-value, instance-visible, variable-visible, instance_state_sensitivity, date
+    // at depth=0: <sx>,       instances, N/A,            N/A             N/A,              N/A               N/A                         N/A
+    // at depth=1: <instance>, instance,  <state>,        N/A,            <valid>,          N/A,              <valid>                     <date>
+    // at depth=2: <variable>, var,       N/A,            <value>,        N/A,              <valid>,          N/A                         N/A
+    adapter->real = gtk_tree_store_new (8, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT64);
 
     g_signal_connect (adapter->real, "row-changed", G_CALLBACK(gsslrtma_proxy_row_changed), adapter);
     g_signal_connect (adapter->real, "row-deleted", G_CALLBACK(gsslrtma_proxy_row_deleted), adapter);
@@ -454,8 +461,16 @@ gsslrtma_populate_tree_store (GncSxSlrTreeModelAdapter *model)
                             SLR_MODEL_COL_VARIABLE_VISIBILITY, FALSE,
                             SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, FALSE,
                             SLR_MODEL_COL_INSTANCE_DATE, INT64_MAX,
+                            SLR_MODEL_COL_INSTANCE_PTR, instances,
                             -1);
 
+        if (qof_log_check (GNC_MOD_GUI_SX, QOF_LOG_DEBUG))
+        {
+            gchar *path_str = gtk_tree_path_to_string (gtk_tree_model_get_path (GTK_TREE_MODEL(model->real), &sx_tree_iter));
+            DEBUG("Add schedule [%s], instances %p at path [%s]", xaccSchedXactionGetName (instances->sx), instances, path_str);
+            g_free (path_str);
+        }
+
         // Insert instance information
         {
             GList *inst_iter;
@@ -481,6 +496,7 @@ gsslrtma_populate_tree_store (GncSxSlrTreeModelAdapter *model)
                                     SLR_MODEL_COL_VARIABLE_VISIBILITY, FALSE,
                                     SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, inst->state != SX_INSTANCE_STATE_CREATED,
                                     SLR_MODEL_COL_INSTANCE_DATE, t,
+                                    SLR_MODEL_COL_INSTANCE_PTR, inst,
                                     -1);
 
                 // Insert variable information
@@ -521,6 +537,7 @@ gsslrtma_populate_tree_store (GncSxSlrTreeModelAdapter *model)
                                             SLR_MODEL_COL_VARIABLE_VISIBILITY, TRUE,
                                             SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, FALSE,
                                             SLR_MODEL_COL_INSTANCE_DATE, INT64_MAX,
+                                            SLR_MODEL_COL_INSTANCE_PTR, var,
                                             -1);
                         g_string_free (tmp_str, TRUE);
                     }
@@ -552,19 +569,37 @@ gnc_sx_slr_tree_model_adapter_get_sx_instances (GncSxSlrTreeModelAdapter *model,
 static GncSxInstances*
 _gnc_sx_slr_tree_model_adapter_get_sx_instances (GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth)
 {
-    GtkTreePath *path;
-    gint *indices, index;
-    path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), iter);
-    if (check_depth && gtk_tree_path_get_depth (path) != 1)
+    GtkTreePath *model_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), iter);
+    gint *indices, instances_index;
+    GncSxInstances *instances = NULL;
+    GtkTreeIter new_iter;
+
+    debug_path (DEBUG, "model path is:", model_path);
+
+    if (check_depth && gtk_tree_path_get_depth (model_path) != 1)
     {
-        gtk_tree_path_free (path);
+        DEBUG("path depth not equal to 1");
+        gtk_tree_path_free (model_path);
         return NULL;
     }
-    indices = gtk_tree_path_get_indices (path);
-    index = indices[0];
-    gtk_tree_path_free (path);
 
-    return (GncSxInstances*)g_list_nth_data (gnc_sx_instance_model_get_sx_instances_list (model->instances), index);
+    indices = gtk_tree_path_get_indices (model_path);
+    instances_index = indices[0];
+
+    gtk_tree_path_free (model_path);
+
+    model_path = gtk_tree_path_new_from_indices (instances_index, -1);
+
+    debug_path (DEBUG, "new model path is:", model_path);
+
+    if (gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &new_iter, model_path))
+        gtk_tree_model_get (GTK_TREE_MODEL(model), &new_iter, SLR_MODEL_COL_INSTANCE_PTR, &instances, -1);
+
+    gtk_tree_path_free (model_path);
+
+    DEBUG("instances is %p", instances);
+
+    return instances;
 }
 
 GncSxInstance*
@@ -576,33 +611,51 @@ gnc_sx_slr_model_get_instance (GncSxSlrTreeModelAdapter *model, GtkTreeIter *ite
 static GncSxInstance*
 _gnc_sx_slr_model_get_instance (GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth)
 {
-    GtkTreePath *path;
+    GtkTreePath *model_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), iter);
     gint *indices, instances_index, instance_index;
-    GncSxInstances *instances;
-    path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), iter);
-    if (check_depth && gtk_tree_path_get_depth (path) != 2)
+    GncSxInstance *instance = NULL;
+    GtkTreeIter new_iter;
+
+    debug_path (DEBUG, "model path is:", model_path);
+
+    if (check_depth && gtk_tree_path_get_depth (model_path) != 2)
     {
-        gtk_tree_path_free (path);
+        PWARN("path depth not equal to 2");
+        gtk_tree_path_free (model_path);
         return NULL;
     }
-    indices = gtk_tree_path_get_indices (path);
-    instances_index = indices[0];
-    instance_index = indices[1];
-    gtk_tree_path_free (path);
 
-    instances = (GncSxInstances*)g_list_nth_data (gnc_sx_instance_model_get_sx_instances_list (model->instances), instances_index);
-    if (instance_index < 0 || instance_index >= g_list_length (instances->instance_list))
+    if (gtk_tree_path_get_depth (model_path) == 1)
     {
+        PWARN("path depth equal to 1");
+        gtk_tree_path_free (model_path);
         return NULL;
     }
 
-    return (GncSxInstance*)g_list_nth_data (instances->instance_list, instance_index);
+    indices = gtk_tree_path_get_indices (model_path);
+    instances_index = indices[0];
+    instance_index = indices[1];
+
+    gtk_tree_path_free (model_path);
+
+    model_path = gtk_tree_path_new_from_indices (instances_index, instance_index, -1);
+
+    debug_path (DEBUG, "new model path is:", model_path);
+
+    if (gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &new_iter, model_path))
+        gtk_tree_model_get (GTK_TREE_MODEL(model), &new_iter, SLR_MODEL_COL_INSTANCE_PTR, &instance, -1);
+
+    gtk_tree_path_free (model_path);
+
+    DEBUG("instance is %p", instance);
+
+    return instance;
 }
 
 gboolean
 gnc_sx_slr_model_get_instance_and_variable (GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, GncSxInstance **instance_loc, GncSxVariable **var_loc)
 {
-    GtkTreePath *path;
+    GtkTreePath *model_path;
     gint *indices, variable_index;
     GncSxInstance *instance;
     GList *variables;
@@ -610,22 +663,33 @@ gnc_sx_slr_model_get_instance_and_variable (GncSxSlrTreeModelAdapter *model, Gtk
     instance = _gnc_sx_slr_model_get_instance (model, iter, FALSE);
     if (instance == NULL)
     {
+        gchar *iter_str = gtk_tree_model_get_string_from_iter (GTK_TREE_MODEL(model), iter);
+        PWARN("instance is NULL for iter %s", iter_str);
+        g_free (iter_str);
         return FALSE;
     }
     variables = gnc_sx_instance_get_variables (instance);
 
-    path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), iter);
-    if (gtk_tree_path_get_depth (path) != 3)
+    model_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), iter);
+    if (gtk_tree_path_get_depth (model_path) != 3)
     {
-        gtk_tree_path_free (path);
+        gchar *path_str = gtk_tree_path_to_string (model_path);
+        PWARN("invalid path [%s] for variable, not at depth 3", path_str);
+        gtk_tree_path_free (model_path);
+        g_free (path_str);
         return FALSE;
     }
-    indices = gtk_tree_path_get_indices (path);
+
+    debug_path (DEBUG, "model path is:", model_path);
+
+    indices = gtk_tree_path_get_indices (model_path);
     variable_index = indices[2];
-    gtk_tree_path_free (path);
+
+    gtk_tree_path_free (model_path);
 
     if (variable_index < 0 || variable_index >= g_list_length (variables))
     {
+        PWARN("variable index %d out of range", variable_index);
         g_list_free (variables);
         return FALSE;
     }
@@ -637,21 +701,12 @@ gnc_sx_slr_model_get_instance_and_variable (GncSxSlrTreeModelAdapter *model, Gtk
 
     if (var_loc != NULL)
     {
-        // *var_loc = (GncSxVariable*)g_list_nth_data(variables, variable_index);
-        GList *list_iter = variables;
-        for (; list_iter != NULL; list_iter = list_iter->next)
-        {
-            GncSxVariable *var = (GncSxVariable*)list_iter->data;
-            if (!var->editable)
-                continue;
-            if (variable_index-- == 0)
-            {
-                *var_loc = var;
-                break;
-            }
-        }
-    }
+        GncSxVariable *var;
+
+        gtk_tree_model_get (GTK_TREE_MODEL(model), iter, SLR_MODEL_COL_INSTANCE_PTR, &var, -1);
 
+        *var_loc = var;
+    }
     g_list_free (variables);
     return TRUE;
 }
@@ -675,30 +730,102 @@ _variable_list_index (GList *variables, GncSxVariable *variable)
     return -1;
 }
 
+typedef struct _findInstanceData
+{
+    gpointer     find_item;
+    GtkTreePath *found_path;
+} FindInstanceData;
+
+static gboolean
+for_each_find_item (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
+{
+    FindInstanceData* to_find = (FindInstanceData*)user_data;
+    gpointer item;
+
+    gtk_tree_model_get (model, iter, SLR_MODEL_COL_INSTANCE_PTR, &item, -1);
+
+    if (item == to_find->find_item)
+    {
+        to_find->found_path = gtk_tree_path_copy (path);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static GtkTreePath*
+_get_model_path_for_item (GtkTreeModel *model, gpointer find_item)
+{
+    GtkTreePath *model_path = NULL;
+    FindInstanceData* to_find_data;
+
+    to_find_data = (FindInstanceData*)g_new0 (FindInstanceData, 1);
+    to_find_data->find_item = find_item;
+    to_find_data->found_path = NULL;
+
+    gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc)for_each_find_item, to_find_data);
+
+    if (to_find_data->found_path)
+    {
+        model_path = gtk_tree_path_copy (to_find_data->found_path);
+        gtk_tree_path_free (to_find_data->found_path);
+    }
+    g_free (to_find_data);
+
+    return model_path;
+}
+
+static GtkTreePath*
+_get_model_path_for_instance (GtkTreeModel *model, GncSxInstance *instance)
+{
+    return _get_model_path_for_item (model, instance);
+}
+
+static GtkTreePath*
+_get_model_path_for_instances (GtkTreeModel *model, GncSxInstances *instances)
+{
+    return _get_model_path_for_item (model, instances);
+}
+
 static GtkTreePath*
 _get_path_for_variable (GncSxSinceLastRunDialog *app_dialog, GncSxInstance *instance, GncSxVariable *variable)
 {
-    GList *variables;
-    int indices[3];
-    GtkTreePath *path, *child_path;
     GncSxSlrTreeModelAdapter *model = app_dialog->editing_model;
     GtkTreeModel *sort_model = gtk_tree_view_get_model (app_dialog->instance_view);
+    gint *indices, instances_index, instance_index, variable_index;
+    GtkTreePath *view_path, *model_path;
+    GList *variables;
 
-    indices[0] = g_list_index (gnc_sx_instance_model_get_sx_instances_list (model->instances), instance->parent);
-    if (indices[0] == -1)
-        return NULL;
-    indices[1] = g_list_index (instance->parent->instance_list, instance);
-    if (indices[1] == -1)
+    model_path = _get_model_path_for_instance (GTK_TREE_MODEL(model), instance);
+
+    if (!model_path)
+    {
+        PWARN("model path is NULL for instance %p", instance);
         return NULL;
+    }
+
+    debug_path (DEBUG, "instance model path is:", model_path);
+
+    indices = gtk_tree_path_get_indices (model_path);
+    instances_index = indices[0];
+    instance_index = indices[1];
+
+    gtk_tree_path_free (model_path);
+
     variables = gnc_sx_instance_get_variables (instance);
-    indices[2] = _variable_list_index (variables, variable);
+    variable_index = _variable_list_index (variables, variable);
     g_list_free (variables);
-    if (indices[2] == -1)
+    if (variable_index == -1)
         return NULL;
-    child_path = gtk_tree_path_new_from_indices (indices[0], indices[1], indices[2], -1);
-    path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT(sort_model), child_path);
-    gtk_tree_path_free (child_path);
-    return path;
+
+    model_path = gtk_tree_path_new_from_indices (instances_index, instance_index, variable_index, -1);
+    debug_path (DEBUG, "model variable path is:", model_path);
+
+    view_path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT(sort_model), model_path);
+    gtk_tree_path_free (model_path);
+
+    debug_path (DEBUG, "return view variable path is:", view_path);
+
+    return view_path;
 }
 
 static void
@@ -718,26 +845,45 @@ gsslrtma_updated_cb (GncSxInstanceModel *instances, SchedXaction *updated_sx, gp
 }
 
 static void
-gsslrtma_removing_cb (GncSxInstanceModel *instances, SchedXaction *to_remove_sx, gpointer user_data)
+gsslrtma_removing_cb (GncSxInstanceModel *inst_model, SchedXaction *to_remove_sx, gpointer user_data)
 {
     GncSxSlrTreeModelAdapter *model = GNC_SX_SLR_TREE_MODEL_ADAPTER(user_data);
+    GtkTreePath *model_path;
     GtkTreeIter tree_iter;
     GList *iter;
     int index = 0;
+    GncSxInstances *instances;
+
     // get index, create path, remove
-    for (iter = gnc_sx_instance_model_get_sx_instances_list (instances); iter != NULL; iter = iter->next, index++)
+    for (iter = gnc_sx_instance_model_get_sx_instances_list (inst_model); iter != NULL; iter = iter->next, index++)
     {
-        GncSxInstances *instances = (GncSxInstances*)iter->data;
+        instances = (GncSxInstances*)iter->data;
         if (instances->sx == to_remove_sx)
             break;
     }
     if (iter == NULL)
+    {
+        PWARN("could not find sx %p in the model", to_remove_sx);
         return; // couldn't find sx in our model, which is weird.
-    if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(model->real), &tree_iter, NULL, index))
-        return; // perr(couldn't get something that should exist.
+    }
+
+    model_path = _get_model_path_for_instances (GTK_TREE_MODEL(model), instances);
+
+    debug_path (DEBUG, "remove model_path", model_path);
+
+    if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model->real), &tree_iter, model_path))
+    {
+        gchar *path_str = gtk_tree_path_to_string (model_path);
+        PWARN("invalid path [%s] for instances %p to remove", path_str, instances);
+        gtk_tree_path_free (model_path);
+        g_free (path_str);
+        return;
+    }
+    gtk_tree_path_free (model_path);
+
     gtk_tree_store_remove (model->real, &tree_iter);
 
-    gnc_sx_instance_model_remove_sx_instances (instances, to_remove_sx);
+    gnc_sx_instance_model_remove_sx_instances (inst_model, to_remove_sx);
 }
 
 static void
@@ -858,11 +1004,12 @@ gnc_sx_sxsincelast_book_opened (void)
 static GtkTreePath *
 instance_get_model_path (GtkTreeView *view, const gchar *path)
 {
-    GtkTreePath *sort_path = gtk_tree_path_new_from_string (path);
+    GtkTreePath *view_path = gtk_tree_path_new_from_string (path);
     GtkTreeModelSort *sort_model = GTK_TREE_MODEL_SORT(gtk_tree_view_get_model (view));
-    GtkTreePath *model_path = gtk_tree_model_sort_convert_path_to_child_path (sort_model, sort_path);
 
-    gtk_tree_path_free (sort_path);
+    GtkTreePath *model_path = gtk_tree_model_sort_convert_path_to_child_path (sort_model, view_path);
+
+    gtk_tree_path_free (view_path);
 
     return model_path;
 }
@@ -873,11 +1020,15 @@ instance_state_changed_cb (GtkCellRendererText *cell,
                            const gchar *value,
                            GncSxSinceLastRunDialog *dialog)
 {
-    GtkTreeIter tree_iter;
     GncSxInstance *inst;
     int i;
     GncSxInstanceState new_state;
     GtkTreePath *model_path = instance_get_model_path (dialog->instance_view, path);
+    GtkTreeIter tree_iter;
+
+    DEBUG("change instance state to [%s] at path [%s]", value, path);
+
+    debug_path (DEBUG, "instance model path is:", model_path);
 
     for (i = 0; i < SX_INSTANCE_STATE_CREATED; i++)
     {
@@ -886,7 +1037,7 @@ instance_state_changed_cb (GtkCellRendererText *cell,
     }
     if (i == SX_INSTANCE_STATE_CREATED)
     {
-        g_warning ("unknown value [%s]", value);
+        PWARN("unknown value [%s]", value);
         return;
     }
     new_state = i;
@@ -894,18 +1045,21 @@ instance_state_changed_cb (GtkCellRendererText *cell,
     if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(dialog->editing_model), &tree_iter, model_path))
     {
         gtk_tree_path_free (model_path);
-        g_warning ("unknown path [%s]", path);
+        PWARN("unknown path [%s]", path);
         return;
     }
     gtk_tree_path_free (model_path);
 
     inst = gnc_sx_slr_model_get_instance (dialog->editing_model, &tree_iter);
+
     if (inst == NULL)
     {
-        g_warning ("invalid path [%s]", path);
+        PWARN("invalid path [%s]", path);
         return;
     }
 
+    DEBUG("instance is %p", inst);
+
     gnc_sx_instance_model_change_instance_state (dialog->editing_model->instances, inst, new_state);
 }
 
@@ -931,12 +1085,14 @@ variable_value_changed_cb (GtkCellRendererText *cell,
 {
     GncSxVariable *var = NULL;
     GncSxInstance *inst;
-    GtkTreeIter tree_iter;
     gnc_numeric parsed_num;
     char *endStr = NULL;
     GtkTreePath *model_path = instance_get_model_path (dialog->instance_view, path);
+    GtkTreeIter tree_iter;
+
+    DEBUG("change variable to [%s] at view path [%s]", value, path);
 
-    DEBUG ("variable to [%s] at path [%s]", value, path);
+    debug_path (DEBUG, "instance model path is:", model_path);
 
     dialog->temp_ce = NULL;
     control_scroll_bars (dialog);
@@ -944,14 +1100,14 @@ variable_value_changed_cb (GtkCellRendererText *cell,
     if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(dialog->editing_model), &tree_iter, model_path))
     {
         gtk_tree_path_free (model_path);
-        g_warning ("invalid path [%s]", path);
+        PWARN("invalid path [%s]", path);
         return;
     }
     gtk_tree_path_free (model_path);
 
     if (!gnc_sx_slr_model_get_instance_and_variable (dialog->editing_model, &tree_iter, &inst, &var))
     {
-        g_critical ("path [%s] doesn't correspond to a valid variable", path);
+        PWARN("path [%s] doesn't correspond to a valid variable", path);
         return;
     }
 
@@ -967,7 +1123,7 @@ variable_value_changed_cb (GtkCellRendererText *cell,
         }
         else
         {
-            g_warning ("error parsing value [%s]", value);
+            PWARN("error parsing value [%s]", value);
         }
         g_free (value_copy);
         return;
@@ -1361,7 +1517,7 @@ dialog_response_cb (GtkDialog *dialog, gint response_id, GncSxSinceLastRunDialog
             gint unbound_len;
             unbound_variables = gnc_sx_instance_model_check_variables (app_dialog->editing_model->instances);
             unbound_len = g_list_length (unbound_variables);
-            PINFO ("%d variables unbound", unbound_len);
+            PINFO("%d variables unbound", unbound_len);
             if (unbound_len > 0)
             {
                 // focus first variable
@@ -1408,7 +1564,7 @@ dialog_response_cb (GtkDialog *dialog, gint response_id, GncSxSinceLastRunDialog
         gnc_close_gui_component (app_dialog->component_id);
         break;
     default:
-        g_error ("unknown response id [%d]", response_id);
+        PWARN("unknown response id [%d]", response_id);
         break;
     }
 }

From 6ae0ae99c34d3d03433fb9afd8d46986b5ed881b Mon Sep 17 00:00:00 2001
From: Robert Fewell <14uBobIT@gmail.com>
Date: Wed, 3 Jan 2024 10:29:09 +0000
Subject: [PATCH 2/5] Remove a couple of unused function from SLR

---
 gnucash/gnome/dialog-sx-since-last-run.c | 47 +-----------------------
 1 file changed, 1 insertion(+), 46 deletions(-)

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 10b6a1a6820..e6ea6bb3ca2 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -103,10 +103,7 @@ static void gnc_sx_slr_tree_model_adapter_dispose (GObject *obj);
 static void gnc_sx_slr_tree_model_adapter_finalize (GObject *obj);
 
 GncSxInstanceModel* gnc_sx_slr_tree_model_adapter_get_instance_model (GncSxSlrTreeModelAdapter *slr_model);
-GncSxInstances* gnc_sx_slr_tree_model_adapter_get_sx_instances (GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter);
-static GncSxInstances* _gnc_sx_slr_tree_model_adapter_get_sx_instances (GncSxSlrTreeModelAdapter *model,
-                                                                        GtkTreeIter *iter,
-                                                                        gboolean check_depth);
+
 /** @return null if the iter is not actually an GncSxInstance. **/
 GncSxInstance* gnc_sx_slr_model_get_instance (GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter);
 static GncSxInstance* _gnc_sx_slr_model_get_instance (GncSxSlrTreeModelAdapter *model,
@@ -560,48 +557,6 @@ gnc_sx_slr_tree_model_adapter_get_instance_model (GncSxSlrTreeModelAdapter *slr_
     return slr_model->instances;
 }
 
-GncSxInstances*
-gnc_sx_slr_tree_model_adapter_get_sx_instances (GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter)
-{
-    return _gnc_sx_slr_tree_model_adapter_get_sx_instances (model, iter, TRUE);
-}
-
-static GncSxInstances*
-_gnc_sx_slr_tree_model_adapter_get_sx_instances (GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter, gboolean check_depth)
-{
-    GtkTreePath *model_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), iter);
-    gint *indices, instances_index;
-    GncSxInstances *instances = NULL;
-    GtkTreeIter new_iter;
-
-    debug_path (DEBUG, "model path is:", model_path);
-
-    if (check_depth && gtk_tree_path_get_depth (model_path) != 1)
-    {
-        DEBUG("path depth not equal to 1");
-        gtk_tree_path_free (model_path);
-        return NULL;
-    }
-
-    indices = gtk_tree_path_get_indices (model_path);
-    instances_index = indices[0];
-
-    gtk_tree_path_free (model_path);
-
-    model_path = gtk_tree_path_new_from_indices (instances_index, -1);
-
-    debug_path (DEBUG, "new model path is:", model_path);
-
-    if (gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &new_iter, model_path))
-        gtk_tree_model_get (GTK_TREE_MODEL(model), &new_iter, SLR_MODEL_COL_INSTANCE_PTR, &instances, -1);
-
-    gtk_tree_path_free (model_path);
-
-    DEBUG("instances is %p", instances);
-
-    return instances;
-}
-
 GncSxInstance*
 gnc_sx_slr_model_get_instance (GncSxSlrTreeModelAdapter *model, GtkTreeIter *iter)
 {

From b5451132db2953f9653ef4cbdd65fc519eba1ebb Mon Sep 17 00:00:00 2001
From: Robert Fewell <14uBobIT@gmail.com>
Date: Wed, 3 Jan 2024 10:52:32 +0000
Subject: [PATCH 3/5] Follow the selection in SLR when sorting changed

---
 gnucash/gnome/dialog-sx-since-last-run.c | 30 ++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index e6ea6bb3ca2..6eedd833a1a 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -1241,6 +1241,33 @@ scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
         return FALSE;
 }
 
+static gboolean
+follow_select_tree_path (GtkTreeView *view)
+{
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
+    GtkTreeModel *sort_model;
+    GtkTreeIter iter;
+
+    if (gtk_tree_selection_get_selected (selection, &sort_model, &iter))
+    {
+        GtkTreePath *view_path = gtk_tree_model_get_path (sort_model, &iter);
+
+        gtk_tree_view_scroll_to_cell (view, view_path, NULL, TRUE, 0.5, 0.0);
+
+        gtk_tree_path_free (view_path);
+    }
+    return FALSE;
+}
+
+static void
+sort_column_changed (GtkTreeSortable* self, gpointer user_data)
+{
+    // this is triggered before a sort change
+    GncSxSinceLastRunDialog *dialog = user_data;
+
+    g_idle_add ((GSourceFunc)follow_select_tree_path, dialog->instance_view);
+}
+
 GncSxSinceLastRunDialog*
 gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_instances, GList *auto_created_txn_guids)
 {
@@ -1329,6 +1356,9 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
         gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sort_model), SLR_MODEL_COL_INSTANCE_STATE,
                                          _status_sort_func, dialog, NULL);
 
+        g_signal_connect (G_OBJECT(sort_model), "sort-column-changed",
+                          G_CALLBACK(sort_column_changed), dialog);
+
         renderer = gtk_cell_renderer_pixbuf_new ();
         g_object_set (G_OBJECT(renderer),
                       "icon-name", "pan-down-symbolic",

From 8af24e9ea87e549a00ccb102f555bb519bc6f8bc Mon Sep 17 00:00:00 2001
From: Robert Fewell <14uBobIT@gmail.com>
Date: Wed, 3 Jan 2024 10:53:13 +0000
Subject: [PATCH 4/5] Change the SLR sorting of the transaction column

As a tree model is being used, the transaction column displays either
the schedule name at depth 1 or the occurrence date at depth 2. This
allows for the sorting function to be changed on path depth so that the
sorting can be done by schedule name or occurrence date.

To sort by schedule name, a schedule name is first selected and then
the column header is pressed to change order.

To sort by occurrence date, a date is selected and then the column
header is pressed to change order based on the date of the first
occurrence.

A tool tip has been added to indicate the sort order being used.
---
 gnucash/gnome/dialog-sx-since-last-run.c      | 148 +++++++++++++++---
 ...gnucash.GnuCash.dialogs.sxs.gschema.xml.in |   5 +
 2 files changed, 134 insertions(+), 19 deletions(-)

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 6eedd833a1a..a9b5ea4f794 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -63,6 +63,7 @@ G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_GUI_SX;
 #define GNC_PREF_SET_REVIEW     "review-transactions"
 #define GNC_PREF_SLR_SORT_COL   "sort-column"
 #define GNC_PREF_SLR_SORT_ASC   "sort-ascending"
+#define GNC_PREF_SLR_SORT_DEPTH "sort-depth"
 
 struct _GncSxSinceLastRunDialog
 {
@@ -74,6 +75,7 @@ struct _GncSxSinceLastRunDialog
     GList *created_txns;
 
     GtkCellEditable *temp_ce; // used when editing values
+    gint sort_selection_depth; // used when sorting transaction column
 };
 
 /* ------------------------------------------------------------ */
@@ -1110,31 +1112,41 @@ variable_value_cancel_changed_cb (GtkCellRenderer *renderer, gpointer user_data)
 }
 
 static gint
-_transaction_sort_func (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
+_sort_text (const gchar *text_a, const gchar *text_b)
 {
+    gchar *a_caseless, *b_caseless;
     gint rtn = 0;
-    GtkTreePath *path_a = gtk_tree_model_get_path (model, iter_a);
 
-    if (gtk_tree_path_get_depth (path_a) != 1)
-    {
-        gtk_tree_path_free (path_a);
-        return rtn;
-    }
+    if (text_a == NULL && text_b == NULL) return 0;
+    if (text_a == NULL) return 1;
+    if (text_b == NULL) return -1;
 
-    gint child_num_a = gtk_tree_model_iter_has_child (model, iter_a) ? 1 : 0;
-    gint child_num_b = gtk_tree_model_iter_has_child (model, iter_b) ? 1 : 0;
+    a_caseless = g_utf8_casefold (text_a, -1);
+    b_caseless = g_utf8_casefold (text_b, -1);
+    rtn = g_strcmp0 (a_caseless, b_caseless);
+    g_free (a_caseless);
+    g_free (b_caseless);
+
+    return rtn;
+}
+
+static gint
+_transaction_sort_func_date (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b)
+{
+    GtkTreePath *path_a = gtk_tree_model_get_path (model, iter_a);
+    gint depth = gtk_tree_path_get_depth (path_a);
+    gint64 date_a = 0, date_b = 0;
+    gint rtn = 0;
 
     gtk_tree_path_free (path_a);
 
-    if (child_num_a > child_num_b)
-        rtn = -1;
-    if (child_num_b > child_num_a)
-        rtn = 1;
+    if (depth == 3)
+        return rtn;
 
-    if ((child_num_a == 1) && (child_num_b == 1))
+    // if top level, look at the first date for order
+    if (depth == 1)
     {
         GtkTreeIter child_iter_a, child_iter_b;
-        gint64 date_a = 0, date_b = 0;
 
         if (gtk_tree_model_iter_nth_child (model, &child_iter_a, iter_a, 0))
             gtk_tree_model_get (model, &child_iter_a, SLR_MODEL_COL_INSTANCE_DATE, &date_a, -1);
@@ -1146,23 +1158,83 @@ _transaction_sort_func (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *i
             rtn = 1;
         if (date_b > date_a)
             rtn = -1;
+
+        if (rtn == 0) // if dates are equal, look at name
+        {
+            gchar *name_text_a, *name_text_b;
+
+            gtk_tree_model_get (model, iter_a, SLR_MODEL_COL_NAME, &name_text_a, -1);
+            gtk_tree_model_get (model, iter_b, SLR_MODEL_COL_NAME, &name_text_b, -1);
+
+            rtn = _sort_text (name_text_a, name_text_b);
+
+            g_free (name_text_a);
+            g_free (name_text_b);
+        }
+        return rtn;
     }
 
-    if (((child_num_a == 0) && (child_num_b == 0)) || rtn == 0)
-    {
-        gchar *name_text_a, *name_text_b;
+    gtk_tree_model_get (model, iter_a, SLR_MODEL_COL_INSTANCE_DATE, &date_a, -1);
+    gtk_tree_model_get (model, iter_b, SLR_MODEL_COL_INSTANCE_DATE, &date_b, -1);
+
+    if (date_a > date_b)
+        rtn = 1;
+    if (date_b > date_a)
+        rtn = -1;
+
+    return rtn;
+}
+
+static gint
+_transaction_sort_func_desc (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b)
+{
+    GtkTreePath *path_a = gtk_tree_model_get_path (model, iter_a);
+    gint depth = gtk_tree_path_get_depth (path_a);
+    gchar *name_text_a, *name_text_b;
+    gint rtn = 0;
 
+    gtk_tree_path_free (path_a);
+
+    if (depth == 3)
+        return rtn;
+
+    if (depth == 1)
+    {
         gtk_tree_model_get (model, iter_a, SLR_MODEL_COL_NAME, &name_text_a, -1);
         gtk_tree_model_get (model, iter_b, SLR_MODEL_COL_NAME, &name_text_b, -1);
 
-        rtn = safe_utf8_collate (name_text_a, name_text_b);
+        rtn = _sort_text (name_text_a, name_text_b);
 
         g_free (name_text_a);
         g_free (name_text_b);
     }
+
+    if (depth == 2)
+    {
+        gint64 date_a = 0, date_b = 0;
+
+        gtk_tree_model_get (model, iter_a, SLR_MODEL_COL_INSTANCE_DATE, &date_a, -1);
+        gtk_tree_model_get (model, iter_b, SLR_MODEL_COL_INSTANCE_DATE, &date_b, -1);
+
+        if (date_a > date_b)
+            rtn = 1;
+        if (date_b > date_a)
+            rtn = -1;
+    }
     return rtn;
 }
 
+static gint
+_transaction_sort_func (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
+{
+    GncSxSinceLastRunDialog *dialog = user_data;
+
+    if (dialog->sort_selection_depth == 1)
+        return _transaction_sort_func_desc (model, iter_a, iter_b);
+    else
+        return _transaction_sort_func_date (model, iter_a, iter_b);
+}
+
 static gint
 _status_sort_func (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
 {
@@ -1241,6 +1313,23 @@ scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
         return FALSE;
 }
 
+static void
+set_transaction_sort_column_tooltip (GncSxSinceLastRunDialog *dialog)
+{
+    GtkTreeViewColumn *col = gtk_tree_view_get_column (GTK_TREE_VIEW(dialog->instance_view), 0);
+    const gchar *date_text = _("Highlight a date first to sort by occurrence date.");
+    const gchar *sched_text = _("Highlight a schedule first to sort by schedule name.");
+    gchar *tooltip;
+
+    if (dialog->sort_selection_depth == 1)
+        tooltip = g_strconcat (sched_text, " *\n", date_text, NULL);
+    else
+        tooltip = g_strconcat (sched_text, "\n", date_text, " *", NULL);
+
+    gtk_widget_set_tooltip_text (gtk_tree_view_column_get_button (col), tooltip);
+    g_free (tooltip);
+}
+
 static gboolean
 follow_select_tree_path (GtkTreeView *view)
 {
@@ -1264,6 +1353,22 @@ sort_column_changed (GtkTreeSortable* self, gpointer user_data)
 {
     // this is triggered before a sort change
     GncSxSinceLastRunDialog *dialog = user_data;
+    GtkTreeIter iter;
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (dialog->instance_view);
+    GtkTreeModel *sort_model;
+
+    if (gtk_tree_selection_get_selected (selection, &sort_model, &iter))
+    {
+        GtkTreePath *view_path = gtk_tree_model_get_path (sort_model, &iter);
+
+        dialog->sort_selection_depth = gtk_tree_path_get_depth (view_path);
+
+        gtk_tree_path_free (view_path);
+    }
+    else
+        dialog->sort_selection_depth = 1;
+
+    set_transaction_sort_column_tooltip (dialog);
 
     g_idle_add ((GSourceFunc)follow_select_tree_path, dialog->instance_view);
 }
@@ -1310,6 +1415,7 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
         g_object_unref (sort_model);
 
         /* default sort order */
+        dialog->sort_selection_depth = gnc_prefs_get_int (GNC_PREFS_GROUP_STARTUP, GNC_PREF_SLR_SORT_DEPTH);
         gboolean sort_ascending = gnc_prefs_get_bool (GNC_PREFS_GROUP_STARTUP, GNC_PREF_SLR_SORT_ASC);
         gint sort_column = gnc_prefs_get_int (GNC_PREFS_GROUP_STARTUP, GNC_PREF_SLR_SORT_COL);
         GtkSortType sort_type = sort_ascending ? GTK_SORT_ASCENDING : GTK_SORT_DESCENDING;
@@ -1330,6 +1436,8 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
         gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sort_model), SLR_MODEL_COL_NAME,
                                          _transaction_sort_func, dialog, NULL);
 
+        set_transaction_sort_column_tooltip (dialog);
+
         renderer = gtk_cell_renderer_combo_new ();
         g_object_set (G_OBJECT(renderer),
                       "model", gnc_sx_get_slr_state_model (),
@@ -1466,6 +1574,8 @@ close_handler (gpointer user_data)
 
         gnc_prefs_set_bool (GNC_PREFS_GROUP_STARTUP, GNC_PREF_SLR_SORT_ASC, sort_ascending);
         gnc_prefs_set_int (GNC_PREFS_GROUP_STARTUP, GNC_PREF_SLR_SORT_COL, column);
+        gnc_prefs_set_int (GNC_PREFS_GROUP_STARTUP, GNC_PREF_SLR_SORT_DEPTH,
+                           app_dialog->sort_selection_depth);
     }
 
     gnc_save_window_size (GNC_PREFS_GROUP_STARTUP, GTK_WINDOW(app_dialog->dialog));
diff --git a/gnucash/gschemas/org.gnucash.GnuCash.dialogs.sxs.gschema.xml.in b/gnucash/gschemas/org.gnucash.GnuCash.dialogs.sxs.gschema.xml.in
index a92bd5a3b81..b1ebf3d55c1 100644
--- a/gnucash/gschemas/org.gnucash.GnuCash.dialogs.sxs.gschema.xml.in
+++ b/gnucash/gschemas/org.gnucash.GnuCash.dialogs.sxs.gschema.xml.in
@@ -37,6 +37,11 @@
       <summary>Set the sort direction in the "since last run" dialog.</summary>
       <description>This settings sets the sort direction in the "since last run" dialog.</description>
     </key>
+    <key name="sort-depth" type="i">
+      <default>1</default>
+      <summary>The depth used in the tree to sort in the "since last run" dialog.</summary>
+      <description>The depth used in the tree to sort in the "since last run" dialog.</description>
+    </key>
   </schema>
   <schema id="org.gnucash.GnuCash.dialogs.sxs.transaction-editor" path="/org/gnucash/GnuCash/dialogs/scheduled-trans/transaction-editor/">
     <key name="create-auto" type="b">

From 78239c38d0a682e56599914770f00550f3b39ea6 Mon Sep 17 00:00:00 2001
From: Robert Fewell <14uBobIT@gmail.com>
Date: Wed, 3 Jan 2024 11:10:11 +0000
Subject: [PATCH 5/5] Remove the SLR status sort as it is too confusing

---
 gnucash/gnome/dialog-sx-since-last-run.c | 63 ++----------------------
 1 file changed, 4 insertions(+), 59 deletions(-)

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index a9b5ea4f794..bc82fea28e2 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -1235,60 +1235,6 @@ _transaction_sort_func (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *i
         return _transaction_sort_func_date (model, iter_a, iter_b);
 }
 
-static gint
-_status_sort_func (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
-{
-    gint rtn = 0;
-    GtkTreePath *path_a = gtk_tree_model_get_path (model, iter_a);
-
-    if (gtk_tree_path_get_depth (path_a) != 1)
-    {
-        gtk_tree_path_free (path_a);
-        return rtn;
-    }
-
-    gint child_num_a = gtk_tree_model_iter_has_child (model, iter_a) ? 1 : 0;
-    gint child_num_b = gtk_tree_model_iter_has_child (model, iter_b) ? 1 : 0;
-
-    gtk_tree_path_free (path_a);
-
-    if (child_num_a > child_num_b)
-        rtn = -1;
-    if (child_num_b > child_num_a)
-        rtn = 1;
-
-    if ((child_num_a == 1) && (child_num_b == 1))
-    {
-        GtkTreeIter child_iter_a, child_iter_b;
-        gchar *state_text_a = NULL, *state_text_b = NULL;
-
-        if (gtk_tree_model_iter_nth_child (model, &child_iter_a, iter_a, 0))
-            gtk_tree_model_get (model, &child_iter_a, SLR_MODEL_COL_INSTANCE_STATE, &state_text_a, -1);
-
-        if (gtk_tree_model_iter_nth_child (model, &child_iter_b, iter_b, 0))
-            gtk_tree_model_get (model, &child_iter_b, SLR_MODEL_COL_INSTANCE_STATE, &state_text_b, -1);
-
-        rtn = safe_utf8_collate (state_text_a, state_text_b);
-
-        g_free (state_text_a);
-        g_free (state_text_b);
-    }
-
-    if (((child_num_a == 0) && (child_num_b == 0)) || rtn == 0)
-    {
-        gchar *name_text_a, *name_text_b;
-
-        gtk_tree_model_get (model, iter_a, SLR_MODEL_COL_NAME, &name_text_a, -1);
-        gtk_tree_model_get (model, iter_b, SLR_MODEL_COL_NAME, &name_text_b, -1);
-
-        rtn = safe_utf8_collate (name_text_a, name_text_b);
-
-        g_free (name_text_a);
-        g_free (name_text_b);
-    }
-    return rtn;
-}
-
 static gboolean
 finish_editing_before_ok_cb (GtkWidget *button, GdkEvent *event,
                              GncSxSinceLastRunDialog *dialog)
@@ -1419,6 +1365,10 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
         gboolean sort_ascending = gnc_prefs_get_bool (GNC_PREFS_GROUP_STARTUP, GNC_PREF_SLR_SORT_ASC);
         gint sort_column = gnc_prefs_get_int (GNC_PREFS_GROUP_STARTUP, GNC_PREF_SLR_SORT_COL);
         GtkSortType sort_type = sort_ascending ? GTK_SORT_ASCENDING : GTK_SORT_DESCENDING;
+
+        if (sort_column != 0)
+            sort_column = 0;
+
         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sort_model),
                                               sort_column, sort_type);
 
@@ -1459,11 +1409,6 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
                 "sensitive", SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
                 NULL);
 
-        gtk_tree_view_column_set_sort_column_id (col, SLR_MODEL_COL_INSTANCE_STATE);
-
-        gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sort_model), SLR_MODEL_COL_INSTANCE_STATE,
-                                         _status_sort_func, dialog, NULL);
-
         g_signal_connect (G_OBJECT(sort_model), "sort-column-changed",
                           G_CALLBACK(sort_column_changed), dialog);