gnucash stable: Multiple changes pushed

Robert Fewell bobit at code.gnucash.org
Mon Nov 20 04:36:27 EST 2023


Updated	 via  https://github.com/Gnucash/gnucash/commit/af48ab7c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/78ab605e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/5b8d29a7 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/16c1244a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/71feea06 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3deb4940 (commit)
	from  https://github.com/Gnucash/gnucash/commit/b0321973 (commit)



commit af48ab7cc243ccca14645267c8bd968f2b2e8078
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Thu Nov 16 10:11:30 2023 +0000

    Bug 798025 - SLR Value entry not tied to location
    
    When you enter a value in the SLR tree view, the cell renderer text
    entry box gets the focus ready for keyboard entry. In this state, the
    tree view can be scrolled underneath by the mouse wheel or using the
    vertical scrollbar, the row is still high lighted but still may be
    confusing.
    
    This commit disables the scrolling while an entry has focus and also
    disables the horizontal scroll bar to be more effective.

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 18dc703040..306238a972 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -909,6 +909,20 @@ instance_state_changed_cb (GtkCellRendererText *cell,
     gnc_sx_instance_model_change_instance_state (dialog->editing_model->instances, inst, new_state);
 }
 
+static void
+control_scroll_bars (GncSxSinceLastRunDialog *dialog)
+{
+    GtkWidget *sw = gtk_widget_get_parent (GTK_WIDGET(dialog->instance_view));
+    GtkWidget *vsbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW(sw));
+    gboolean enable = TRUE;
+
+    if (dialog->temp_ce)
+        enable = FALSE;
+
+    gtk_widget_set_sensitive (vsbar, enable);
+    gtk_widget_set_visible (vsbar, enable);
+}
+
 static void
 variable_value_changed_cb (GtkCellRendererText *cell,
                            const gchar *path,
@@ -925,6 +939,7 @@ variable_value_changed_cb (GtkCellRendererText *cell,
     DEBUG ("variable to [%s] at path [%s]", value, path);
 
     dialog->temp_ce = NULL;
+    control_scroll_bars (dialog);
 
     if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(dialog->editing_model), &tree_iter, model_path))
     {
@@ -972,6 +987,7 @@ variable_value_start_changed_cb (GtkCellRenderer *renderer, GtkCellEditable *edi
 {
     GncSxSinceLastRunDialog *dialog = user_data;
     dialog->temp_ce = editable;
+    control_scroll_bars (dialog);
 }
 
 static void
@@ -979,6 +995,7 @@ variable_value_cancel_changed_cb (GtkCellRenderer *renderer, gpointer user_data)
 {
     GncSxSinceLastRunDialog *dialog = user_data;
     dialog->temp_ce = NULL;
+    control_scroll_bars (dialog);
 }
 
 static gint
@@ -1100,7 +1117,18 @@ finish_editing_before_ok_cb (GtkWidget *button, GdkEvent *event,
     dialog->temp_ce = NULL;
 
     return FALSE;
-} 
+}
+
+static gboolean
+scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
+{
+    GncSxSinceLastRunDialog *dialog = user_data;
+
+    if (dialog->temp_ce)
+        return TRUE;
+    else
+        return FALSE;
+}
 
 GncSxSinceLastRunDialog*
 gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_instances, GList *auto_created_txn_guids)
@@ -1150,6 +1178,9 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sort_model),
                                               sort_column, sort_type);
 
+        g_signal_connect (G_OBJECT(dialog->instance_view), "scroll-event",
+                          G_CALLBACK(scroll_event), dialog);
+
         renderer = gtk_cell_renderer_text_new ();
         col = gtk_tree_view_column_new_with_attributes (_("Transaction"), renderer,
                 "text", SLR_MODEL_COL_NAME,
@@ -1197,7 +1228,7 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
                 "sensitive", SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
                 NULL);
         gtk_tree_view_append_column (dialog->instance_view, col);
-        gtk_tree_view_column_set_resizable (col, TRUE);
+        gtk_tree_view_column_set_resizable (col, FALSE);
 
         renderer = gtk_cell_renderer_text_new ();
         g_object_set (G_OBJECT(renderer),
diff --git a/gnucash/gtkbuilder/dialog-sx.glade b/gnucash/gtkbuilder/dialog-sx.glade
index 73bb00f1d1..45e94d8a33 100644
--- a/gnucash/gtkbuilder/dialog-sx.glade
+++ b/gnucash/gtkbuilder/dialog-sx.glade
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 -->
+<!-- Generated with glade 3.40.0 -->
 <interface>
   <requires lib="gtk+" version="3.22"/>
   <object class="GtkDialog" id="account_deletion_dialog">
@@ -1554,6 +1554,7 @@
                 <property name="visible">True</property>
                 <property name="can-focus">True</property>
                 <property name="vexpand">True</property>
+                <property name="hscrollbar-policy">never</property>
                 <property name="shadow-type">in</property>
                 <child>
                   <object class="GtkTreeView" id="instance_view">

commit 78ab605e91d4c9d5db98a97062e6dd20a59246e1
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Nov 15 16:01:06 2023 +0000

    Bug 798760 - SLR change reminder with value entry
    
    If the scheduled transaction state is 'Reminder' and also requires
    values which have been entered but the state has not been changed to
    'To Create' the values are lost when OK button pressed.
    
    This change adds a check of state to the 'variable_value_changed_cb'
    and if 'Reminder' changes it to 'To Create'.

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 1441d56bf6..18dc703040 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -957,6 +957,12 @@ variable_value_changed_cb (GtkCellRendererText *cell,
         g_free (value_copy);
         return;
     }
+
+    if (inst->state == SX_INSTANCE_STATE_REMINDER)
+    {
+        gnc_sx_instance_model_change_instance_state (dialog->editing_model->instances, inst,
+                                                     SX_INSTANCE_STATE_TO_CREATE);
+    }
     gnc_sx_instance_model_set_variable (dialog->editing_model->instances, inst, var, &parsed_num);
 }
 

commit 5b8d29a7d07b56f5ffbe6022440e85aebbc288ed
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Nov 15 15:52:59 2023 +0000

    Bug 798760 - SLR OK button to complete value entry
    
    When in the SLR dialog and you are adding a value to a scheduled
    transaction, if you do not complete the entry with a tab or enter but
    press the 'OK' button the value changes back to 'Need Value'.
    
    This change also completes the entry with the 'OK' button and will move
    to the next value to be entered or if none complete the dialog.

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 8ccb6e827f..1441d56bf6 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -72,6 +72,8 @@ struct _GncSxSinceLastRunDialog
     GtkTreeView *instance_view;
     GtkToggleButton *review_created_txns_toggle;
     GList *created_txns;
+
+    GtkCellEditable *temp_ce; // used when editing values
 };
 
 /* ------------------------------------------------------------ */
@@ -922,6 +924,8 @@ variable_value_changed_cb (GtkCellRendererText *cell,
 
     DEBUG ("variable to [%s] at path [%s]", value, path);
 
+    dialog->temp_ce = NULL;
+
     if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(dialog->editing_model), &tree_iter, model_path))
     {
         gtk_tree_path_free (model_path);
@@ -956,6 +960,21 @@ variable_value_changed_cb (GtkCellRendererText *cell,
     gnc_sx_instance_model_set_variable (dialog->editing_model->instances, inst, var, &parsed_num);
 }
 
+static void
+variable_value_start_changed_cb (GtkCellRenderer *renderer, GtkCellEditable *editable,
+                                 gchar *path, gpointer user_data)
+{
+    GncSxSinceLastRunDialog *dialog = user_data;
+    dialog->temp_ce = editable;
+}
+
+static void
+variable_value_cancel_changed_cb (GtkCellRenderer *renderer, gpointer user_data)
+{
+    GncSxSinceLastRunDialog *dialog = user_data;
+    dialog->temp_ce = NULL;
+}
+
 static gint
 _transaction_sort_func (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
 {
@@ -1064,11 +1083,25 @@ _status_sort_func (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b
     return rtn;
 }
 
+static gboolean
+finish_editing_before_ok_cb (GtkWidget *button, GdkEvent *event,
+                             GncSxSinceLastRunDialog *dialog)
+{
+    // finish editing
+    if (dialog->temp_ce)
+        gtk_cell_editable_editing_done (dialog->temp_ce);
+
+    dialog->temp_ce = NULL;
+
+    return FALSE;
+} 
+
 GncSxSinceLastRunDialog*
 gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_instances, GList *auto_created_txn_guids)
 {
     GncSxSinceLastRunDialog *dialog;
     GtkBuilder *builder;
+    GtkWidget *ok_button;
 
     dialog = g_new0 (GncSxSinceLastRunDialog, 1);
 
@@ -1090,6 +1123,11 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
 
     dialog->created_txns = auto_created_txn_guids;
 
+    ok_button = GTK_WIDGET(gtk_builder_get_object (builder, "okbutton2"));
+
+    g_signal_connect (G_OBJECT(ok_button), "button-press-event",
+                      G_CALLBACK(finish_editing_before_ok_cb), dialog);
+
     {
         GtkCellRenderer *renderer;
         GtkTreeViewColumn *col;
@@ -1163,6 +1201,17 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
                           "edited",
                           G_CALLBACK(variable_value_changed_cb),
                           dialog);
+
+        g_signal_connect (G_OBJECT(renderer),
+                          "editing-started",
+                          G_CALLBACK(variable_value_start_changed_cb),
+                          dialog);
+
+        g_signal_connect (G_OBJECT(renderer),
+                          "editing-canceled",
+                          (GCallback)variable_value_cancel_changed_cb,
+                          dialog);
+
         col = gtk_tree_view_column_new_with_attributes (_("Value"), renderer,
                 "text", SLR_MODEL_COL_VARAIBLE_VALUE,
                 "visible", SLR_MODEL_COL_VARIABLE_VISIBILITY,

commit 16c1244a63458c58dd3e18c37a08ccc5c67a8f79
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Nov 15 14:49:06 2023 +0000

    Bug 607000 - SLR visible transactions
    
    Change the Since Last Run dialog to show only transactions with a
    non-empty Status.

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 2b3903cfe9..8ccb6e827f 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -435,6 +435,10 @@ gsslrtma_populate_tree_store (GncSxSlrTreeModelAdapter *model)
             }
         }
 
+        // if there are no instances for the instance skip adding
+        if (g_list_length (instances->instance_list) == 0)
+            continue;
+
         if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(model->real), &sx_tree_iter, NULL, ++instances_index))
         {
             gtk_tree_store_append (model->real, &sx_tree_iter, NULL);

commit 71feea06a99301200a02a226e0b8959a2b2c37ea
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Nov 15 14:24:26 2023 +0000

    Allow saving the sorting in the SLR

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 6e36b02382..2b3903cfe9 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -60,6 +60,10 @@ G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_GUI_SX;
 
 #define DIALOG_SX_SINCE_LAST_RUN_CM_CLASS "dialog-sx-since-last-run"
 
+#define GNC_PREF_SET_REVIEW     "review-transactions"
+#define GNC_PREF_SLR_SORT_COL   "sort-column"
+#define GNC_PREF_SLR_SORT_ASC   "sort-ascending"
+
 struct _GncSxSinceLastRunDialog
 {
     GtkWidget *dialog;
@@ -1092,8 +1096,11 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
         g_object_unref (sort_model);
 
         /* default sort order */
+        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;
         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sort_model),
-                                              SLR_MODEL_COL_NAME, GTK_SORT_ASCENDING);
+                                              sort_column, sort_type);
 
         renderer = gtk_cell_renderer_text_new ();
         col = gtk_tree_view_column_new_with_attributes (_("Transaction"), renderer,
@@ -1215,6 +1222,20 @@ static void
 close_handler (gpointer user_data)
 {
     GncSxSinceLastRunDialog *app_dialog = user_data;
+    GtkSortType order;
+    gint column;
+
+    if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE(
+                                              gtk_tree_view_get_model (app_dialog->instance_view)),
+                                              &column, &order))
+    {
+        gboolean sort_ascending = TRUE;
+        if (order == GTK_SORT_DESCENDING)
+            sort_ascending = FALSE;
+
+        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_save_window_size (GNC_PREFS_GROUP_STARTUP, GTK_WINDOW(app_dialog->dialog));
     gtk_widget_destroy (app_dialog->dialog);
diff --git a/gnucash/gnome/dialog-sx-since-last-run.h b/gnucash/gnome/dialog-sx-since-last-run.h
index 6add435289..e2f8f5a70e 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.h
+++ b/gnucash/gnome/dialog-sx-since-last-run.h
@@ -34,7 +34,6 @@
 #define GNC_PREFS_GROUP_STARTUP "dialogs.sxs.since-last-run"
 #define GNC_PREF_RUN_AT_FOPEN   "show-at-file-open"
 #define GNC_PREF_SHOW_AT_FOPEN  "show-notify-window-at-file-open"
-#define GNC_PREF_SET_REVIEW     "review-transactions"
 
 typedef struct _GncSxSlrTreeModelAdapter GncSxSlrTreeModelAdapter;
 typedef struct _GncSxSinceLastRunDialog GncSxSinceLastRunDialog;
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 641e64ce4f..a92bd5a3b8 100644
--- a/gnucash/gschemas/org.gnucash.GnuCash.dialogs.sxs.gschema.xml.in
+++ b/gnucash/gschemas/org.gnucash.GnuCash.dialogs.sxs.gschema.xml.in
@@ -27,8 +27,17 @@
       <summary>Set "Review Created Transactions" as the default for the "since last run" dialog.</summary>
       <description>This setting controls whether as default the "review created transactions" is set for the "since last run" dialog.</description>
     </key>
+    <key name="sort-column" type="i">
+      <default>0</default>
+      <summary>Set the sort column in the "since last run" dialog.</summary>
+      <description>This settings sets the sort column in the "since last run" dialog.</description>
+    </key>
+    <key name="sort-ascending" type="b">
+      <default>true</default>
+      <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>
   </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">
       <default>false</default>

commit 3deb49402c33a18c278fe74ddda4aedf1ee64c09
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Nov 15 13:35:04 2023 +0000

    Bug 792241 - Allow sorting scheduled transactions
    
    Allow sorting in the SLR by date and by status.

diff --git a/gnucash/gnome/dialog-sx-since-last-run.c b/gnucash/gnome/dialog-sx-since-last-run.c
index 5248bdb628..6e36b02382 100644
--- a/gnucash/gnome/dialog-sx-since-last-run.c
+++ b/gnucash/gnome/dialog-sx-since-last-run.c
@@ -333,16 +333,17 @@ enum
     SLR_MODEL_COL_INSTANCE_VISIBILITY,
     SLR_MODEL_COL_VARIABLE_VISIBILITY,
     SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY,
+    SLR_MODEL_COL_INSTANCE_DATE,
 };
 
 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
-    // at depth=0: <sx>,       N/A,            N/A,            N/A               N/A,              N/A
-    // at depth=1: <instance>, <state>,        N/A,            <valid>,          N/A,              <valid>
-    // at depth=2: <variable>, N/A,            <value>,        N/A,              <valid>,          N/A
-    adapter->real = gtk_tree_store_new (6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+    // 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);
 
     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);
@@ -442,6 +443,7 @@ gsslrtma_populate_tree_store (GncSxSlrTreeModelAdapter *model)
                             SLR_MODEL_COL_INSTANCE_VISIBILITY, FALSE,
                             SLR_MODEL_COL_VARIABLE_VISIBILITY, FALSE,
                             SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, FALSE,
+                            SLR_MODEL_COL_INSTANCE_DATE, INT64_MAX,
                             -1);
 
         // Insert instance information
@@ -455,6 +457,7 @@ gsslrtma_populate_tree_store (GncSxSlrTreeModelAdapter *model)
             {
                 GncSxInstance *inst = (GncSxInstance*)inst_iter->data;
                 qof_print_gdate (instance_date_buf, MAX_DATE_LENGTH, &inst->date);
+                time64 t = gdate_to_time64 (inst->date);
 
                 if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(model->real), &inst_tree_iter, &sx_tree_iter, ++instance_index))
                 {
@@ -467,6 +470,7 @@ gsslrtma_populate_tree_store (GncSxSlrTreeModelAdapter *model)
                                     SLR_MODEL_COL_INSTANCE_VISIBILITY, TRUE,
                                     SLR_MODEL_COL_VARIABLE_VISIBILITY, FALSE,
                                     SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, inst->state != SX_INSTANCE_STATE_CREATED,
+                                    SLR_MODEL_COL_INSTANCE_DATE, t,
                                     -1);
 
                 // Insert variable information
@@ -506,6 +510,7 @@ gsslrtma_populate_tree_store (GncSxSlrTreeModelAdapter *model)
                                             SLR_MODEL_COL_INSTANCE_VISIBILITY, FALSE,
                                             SLR_MODEL_COL_VARIABLE_VISIBILITY, TRUE,
                                             SLR_MODEL_COL_INSTANCE_STATE_SENSITIVITY, FALSE,
+                                            SLR_MODEL_COL_INSTANCE_DATE, INT64_MAX,
                                             -1);
                         g_string_free (tmp_str, TRUE);
                     }
@@ -661,11 +666,13 @@ _variable_list_index (GList *variables, GncSxVariable *variable)
 }
 
 static GtkTreePath*
-_get_path_for_variable (GncSxSlrTreeModelAdapter *model, GncSxInstance *instance, GncSxVariable *variable)
+_get_path_for_variable (GncSxSinceLastRunDialog *app_dialog, GncSxInstance *instance, GncSxVariable *variable)
 {
     GList *variables;
     int indices[3];
-    GtkTreePath *path;
+    GtkTreePath *path, *child_path;
+    GncSxSlrTreeModelAdapter *model = app_dialog->editing_model;
+    GtkTreeModel *sort_model = gtk_tree_view_get_model (app_dialog->instance_view);
 
     indices[0] = g_list_index (gnc_sx_instance_model_get_sx_instances_list (model->instances), instance->parent);
     if (indices[0] == -1)
@@ -678,7 +685,9 @@ _get_path_for_variable (GncSxSlrTreeModelAdapter *model, GncSxInstance *instance
     g_list_free (variables);
     if (indices[2] == -1)
         return NULL;
-    path = gtk_tree_path_new_from_indices (indices[0], indices[1], indices[2], -1);
+    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;
 }
 
@@ -836,6 +845,18 @@ gnc_sx_sxsincelast_book_opened (void)
         gnc_ui_sx_creation_error_dialog (&creation_errors);
 }
 
+static GtkTreePath *
+instance_get_model_path (GtkTreeView *view, const gchar *path)
+{
+    GtkTreePath *sort_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);
+
+    return model_path;
+}
+
 static void
 instance_state_changed_cb (GtkCellRendererText *cell,
                            const gchar *path,
@@ -846,6 +867,7 @@ instance_state_changed_cb (GtkCellRendererText *cell,
     GncSxInstance *inst;
     int i;
     GncSxInstanceState new_state;
+    GtkTreePath *model_path = instance_get_model_path (dialog->instance_view, path);
 
     for (i = 0; i < SX_INSTANCE_STATE_CREATED; i++)
     {
@@ -859,11 +881,13 @@ instance_state_changed_cb (GtkCellRendererText *cell,
     }
     new_state = i;
 
-    if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(dialog->editing_model), &tree_iter, path))
+    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);
         return;
     }
+    gtk_tree_path_free (model_path);
 
     inst = gnc_sx_slr_model_get_instance (dialog->editing_model, &tree_iter);
     if (inst == NULL)
@@ -886,13 +910,17 @@ variable_value_changed_cb (GtkCellRendererText *cell,
     GtkTreeIter tree_iter;
     gnc_numeric parsed_num;
     char *endStr = NULL;
+    GtkTreePath *model_path = instance_get_model_path (dialog->instance_view, path);
 
     DEBUG ("variable to [%s] at path [%s]", value, path);
-    if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(dialog->editing_model), &tree_iter, path))
+
+    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);
         return;
     }
+    gtk_tree_path_free (model_path);
 
     if (!gnc_sx_slr_model_get_instance_and_variable (dialog->editing_model, &tree_iter, &inst, &var))
     {
@@ -920,6 +948,114 @@ variable_value_changed_cb (GtkCellRendererText *cell,
     gnc_sx_instance_model_set_variable (dialog->editing_model->instances, inst, var, &parsed_num);
 }
 
+static gint
+_transaction_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;
+        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);
+
+        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_DATE, &date_b, -1);
+
+        if (date_a > date_b)
+            rtn = 1;
+        if (date_b > date_a)
+            rtn = -1;
+    }
+
+    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 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;
+}
+
 GncSxSinceLastRunDialog*
 gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_instances, GList *auto_created_txn_guids)
 {
@@ -949,9 +1085,15 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
     {
         GtkCellRenderer *renderer;
         GtkTreeViewColumn *col;
+        GtkTreeModel *sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(dialog->editing_model));
 
         dialog->instance_view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "instance_view"));
-        gtk_tree_view_set_model (dialog->instance_view, GTK_TREE_MODEL(dialog->editing_model));
+        gtk_tree_view_set_model (dialog->instance_view, GTK_TREE_MODEL(sort_model));
+        g_object_unref (sort_model);
+
+        /* default sort order */
+        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sort_model),
+                                              SLR_MODEL_COL_NAME, GTK_SORT_ASCENDING);
 
         renderer = gtk_cell_renderer_text_new ();
         col = gtk_tree_view_column_new_with_attributes (_("Transaction"), renderer,
@@ -959,6 +1101,11 @@ gnc_ui_sx_since_last_run_dialog (GtkWindow *parent, GncSxInstanceModel *sx_insta
                 NULL);
         gtk_tree_view_append_column (dialog->instance_view, col);
 
+        gtk_tree_view_column_set_sort_column_id (col, SLR_MODEL_COL_NAME);
+
+        gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sort_model), SLR_MODEL_COL_NAME,
+                                         _transaction_sort_func, dialog, NULL);
+
         renderer = gtk_cell_renderer_combo_new ();
         g_object_set (G_OBJECT(renderer),
                       "model", gnc_sx_get_slr_state_model (),
@@ -980,6 +1127,11 @@ 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);
+
         renderer = gtk_cell_renderer_pixbuf_new ();
         g_object_set (G_OBJECT(renderer),
                       "icon-name", "pan-down-symbolic",
@@ -1109,7 +1261,8 @@ dialog_response_cb (GtkDialog *dialog, gint response_id, GncSxSinceLastRunDialog
                 gboolean start_editing = TRUE;
 
                 first_unbound = (GncSxVariableNeeded*)unbound_variables->data;
-                variable_path = _get_path_for_variable (app_dialog->editing_model, first_unbound->instance, first_unbound->variable);
+
+                variable_path = _get_path_for_variable (app_dialog, first_unbound->instance, first_unbound->variable);
                 variable_col = gtk_tree_view_get_column (app_dialog->instance_view, variable_view_column);
 
                 gtk_tree_view_set_cursor (app_dialog->instance_view, variable_path, variable_col, start_editing);



Summary of changes:
 gnucash/gnome/dialog-sx-since-last-run.c           | 290 ++++++++++++++++++++-
 gnucash/gnome/dialog-sx-since-last-run.h           |   1 -
 .../org.gnucash.GnuCash.dialogs.sxs.gschema.xml.in |  11 +-
 gnucash/gtkbuilder/dialog-sx.glade                 |   3 +-
 4 files changed, 289 insertions(+), 16 deletions(-)



More information about the gnucash-changes mailing list