q tree model bindings: recursively insert rows

On rowsMoved and modelReset recursively insert all the existing children
of the top nodes. This is because rowsMoved is handled by deleting
all of the moved rows during the rowsAboutToBeMoved signal and then
re-inserting them on the rowsMoved signal. In this case, any children
of the moved rows must be re-inserted as well.

Issue: #80698
Change-Id: Ice7c8d453039acd91a55652c802fdf3e427f96e0
diff --git a/src/models/gtkqtreemodel.cpp b/src/models/gtkqtreemodel.cpp
index 0a18e77..c6a4a22 100644
--- a/src/models/gtkqtreemodel.cpp
+++ b/src/models/gtkqtreemodel.cpp
@@ -229,6 +229,28 @@
 }
 
 /**
+ * helper method which recursively adds all the children of the given QModelIndex
+ */
+static void
+insert_children(const QModelIndex &idx, GtkQTreeModel *gtk_model)
+{
+    const auto children = gtk_model->priv->model->rowCount(idx);
+    for (int i = 0; i < children; ++i) {
+        GtkTreeIter iter_child;
+        auto idx_child = gtk_model->priv->model->index(i, 0, idx);
+        if (idx_child.isValid()) {
+            iter_child.stamp = gtk_model->priv->stamp;
+            qmodelindex_to_iter(idx_child, &iter_child);
+            if (auto path_child = gtk_q_tree_model_get_path(GTK_TREE_MODEL(gtk_model), &iter_child)) {
+                gtk_tree_model_row_inserted(GTK_TREE_MODEL(gtk_model), path_child, &iter_child);
+                gtk_tree_path_free(path_child);
+            }
+            insert_children(idx_child, gtk_model);
+        }
+    }
+}
+
+/**
  * gtk_q_tree_model_new:
  * @model: QAbstractItemModel to which this model will bind.
  * @n_columns: number of columns in the list store
@@ -333,6 +355,7 @@
                 GtkTreePath *path_new = gtk_q_tree_model_get_path(GTK_TREE_MODEL(retval), &iter_new);
                 gtk_tree_model_row_inserted(GTK_TREE_MODEL(retval), path_new, &iter_new);
                 gtk_tree_path_free(path_new);
+                insert_children(idx, retval);
                 destinationRow++;
             }
         }
@@ -421,18 +444,8 @@
         &QAbstractItemModel::modelReset,
         [=] () {
             // g_debug("model reset");
-            /* now add all the (new) rows */
-            int row_count = proxy_model->rowCount();
-            for (int row = 0; row < row_count; row++) {
-                // g_debug("adding row %d", row);
-                GtkTreeIter iter_new;
-                QModelIndex idx = proxy_model->index(row, 0);
-                iter_new.stamp = stamp;
-                qmodelindex_to_iter(idx, &iter_new);
-                GtkTreePath *path_new = gtk_q_tree_model_get_path(GTK_TREE_MODEL(retval), &iter_new);
-                gtk_tree_model_row_inserted(GTK_TREE_MODEL(retval), path_new, &iter_new);
-                gtk_tree_path_free(path_new);
-            }
+            /* now recursively add all the (new) rows */
+            insert_children(QModelIndex(), retval);
         }
     );