gnucash stable: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Tue Aug 15 01:09:31 EDT 2023


Updated	 via  https://github.com/Gnucash/gnucash/commit/d8a0e294 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/bea6b52d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f10d7a7c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d5b5d016 (commit)
	from  https://github.com/Gnucash/gnucash/commit/f6f305fd (commit)



commit d8a0e294dc8bf113befaa099033eebca6a538675
Merge: f6f305fdee bea6b52d3f
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 15 13:09:05 2023 +0800

    Merge branch 'iter-to-stl' into stable #1745


commit bea6b52d3f981f6d04a26f3a7a66249d82a0841c
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Aug 14 13:27:37 2023 +0800

    [assistant-csv-trans-import.cpp] uses GtkTreeModelContainer

diff --git a/gnucash/import-export/csv-imp/assistant-csv-trans-import.cpp b/gnucash/import-export/csv-imp/assistant-csv-trans-import.cpp
index 55823b93b1..841ab14804 100644
--- a/gnucash/import-export/csv-imp/assistant-csv-trans-import.cpp
+++ b/gnucash/import-export/csv-imp/assistant-csv-trans-import.cpp
@@ -56,6 +56,7 @@
 #include "gnc-csv-gnumeric-popup.h"
 #include "go-charmap-sel.h"
 
+#include "gnc-tree-model-container.hpp"
 #include "gnc-imp-settings-csv-tx.hpp"
 #include "gnc-import-tx.hpp"
 #include "gnc-tokenizer-fw.hpp"
@@ -893,31 +894,25 @@ void
 CsvImpTransAssist::preview_settings_save ()
 {
     auto new_name = tx_imp->settings_name();
+    GncTreeContainer<> tree_model_container{gtk_combo_box_get_model (settings_combo)};
 
     /* Check if the entry text matches an already existing preset */
     GtkTreeIter iter;
     if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
     {
-
-        auto model = gtk_combo_box_get_model (settings_combo);
-        bool valid = gtk_tree_model_get_iter_first (model, &iter);
-        while (valid)
+        for (auto iter : tree_model_container)
         {
             // Walk through the list, reading each row
-            CsvTransImpSettings *preset;
-            gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
-
-            if (preset && (preset->m_name == std::string(new_name)))
+            auto preset = iter.get<CsvTransImpSettings*>(SET_GROUP);
+            if (preset && preset->m_name == new_name)
             {
-                auto response = gnc_ok_cancel_dialog (GTK_WINDOW (csv_imp_asst),
-                        GTK_RESPONSE_OK,
-                        "%s", _("Setting name already exists, overwrite?"));
+                auto response = gnc_ok_cancel_dialog (GTK_WINDOW (csv_imp_asst), GTK_RESPONSE_OK,
+                                                      "%s", _("Setting name already exists, overwrite?"));
                 if (response != GTK_RESPONSE_OK)
                     return;
 
                 break;
             }
-            valid = gtk_tree_model_iter_next (model, &iter);
         }
     }
 
@@ -929,23 +924,14 @@ CsvImpTransAssist::preview_settings_save ()
 
         // Update the settings store
         preview_populate_settings_combo();
-        auto model = gtk_combo_box_get_model (settings_combo);
 
-        // Get the first entry in model
-        GtkTreeIter   iter;
-        bool valid = gtk_tree_model_get_iter_first (model, &iter);
-        while (valid)
+        for (auto iter : tree_model_container)
         {
-            // Walk through the list, reading each row
-            gchar *name = nullptr;
-            gtk_tree_model_get (model, &iter, SET_NAME, &name, -1);
-
-            if (g_strcmp0 (name, new_name.c_str()) == 0) // Set Active, the one Saved.
-                gtk_combo_box_set_active_iter (settings_combo, &iter);
-
-            g_free (name);
-
-            valid = gtk_tree_model_iter_next (model, &iter);
+            if (iter.get_string (SET_NAME) == new_name) // Set Active, the one Saved.
+            {
+                gtk_combo_box_set_active_iter (settings_combo, &iter.get_iter());
+                break;
+            }
         }
     }
     else
@@ -1456,7 +1442,6 @@ CsvImpTransAssist::preview_row_fill_state_cells (GtkListStore *store, GtkTreeIte
 GtkWidget*
 CsvImpTransAssist::preview_cbox_factory (GtkTreeModel* model, uint32_t colnum)
 {
-    GtkTreeIter iter;
     auto cbox = gtk_combo_box_new_with_model(model);
 
     /* Set up a renderer for this combobox. */
@@ -1466,18 +1451,14 @@ CsvImpTransAssist::preview_cbox_factory (GtkTreeModel* model, uint32_t colnum)
     gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(cbox),
             renderer, "text", COL_TYPE_NAME);
 
-    auto valid = gtk_tree_model_get_iter_first (model, &iter);
-    while (valid)
+    for (auto iter : GncTreeContainer (model))
     {
-        gint stored_col_type;
-        gtk_tree_model_get (model, &iter,
-                COL_TYPE_ID, &stored_col_type, -1);
-        if (stored_col_type == static_cast<int>( tx_imp->column_types()[colnum]))
+        if (iter.get_int(COL_TYPE_ID) == static_cast<int>( tx_imp->column_types()[colnum]))
+        {
+            gtk_combo_box_set_active_iter (GTK_COMBO_BOX(cbox), &iter.get_iter());
             break;
-        valid = gtk_tree_model_iter_next(model, &iter);
+        }
     }
-    if (valid)
-        gtk_combo_box_set_active_iter (GTK_COMBO_BOX(cbox), &iter);
 
     g_object_set_data (G_OBJECT(cbox), "col-num", GUINT_TO_POINTER(colnum));
     g_signal_connect (G_OBJECT(cbox), "changed",
@@ -1779,54 +1760,34 @@ void CsvImpTransAssist::acct_match_set_accounts ()
 static void
 csv_tximp_acct_match_load_mappings (GtkTreeModel *mappings_store)
 {
-    // Set iter to first entry of store
-    GtkTreeIter iter;
-    auto valid = gtk_tree_model_get_iter_first (mappings_store, &iter);
-
-    // Walk through the store trying to match to a map
-    while (valid)
+    for (auto iter : GncTreeContainer<>(mappings_store))
     {
         // Walk through the list, reading each row
-        Account *account = nullptr;
-        gchar   *map_string;
-        gtk_tree_model_get (GTK_TREE_MODEL(mappings_store), &iter, MAPPING_STRING, &map_string, MAPPING_ACCOUNT, &account, -1);
+        auto account = iter.get<Account*>(MAPPING_ACCOUNT);
+        auto map_string = iter.get_string(MAPPING_STRING);
 
         // Look for an account matching the map_string
         // It may already be set in the tree model. If not we try to match the map_string with
         // - an entry in our saved account maps
         // - a full name of any of our existing accounts
         if (account ||
-            (account = gnc_account_imap_find_any (gnc_get_current_book(), IMAP_CAT_CSV, map_string)) ||
-            (account = gnc_account_lookup_by_full_name (gnc_get_current_root_account(), map_string)))
+            (account = gnc_account_imap_find_any (gnc_get_current_book(), IMAP_CAT_CSV, map_string.c_str())) ||
+            (account = gnc_account_lookup_by_full_name (gnc_get_current_root_account(), map_string.c_str())))
         {
             auto fullpath = gnc_account_get_full_name (account);
-            gtk_list_store_set (GTK_LIST_STORE(mappings_store), &iter, MAPPING_FULLPATH, fullpath, -1);
-            gtk_list_store_set (GTK_LIST_STORE(mappings_store), &iter, MAPPING_ACCOUNT, account, -1);
+            gtk_list_store_set (GTK_LIST_STORE(mappings_store), &iter.get_iter(), MAPPING_FULLPATH, fullpath, -1);
+            gtk_list_store_set (GTK_LIST_STORE(mappings_store), &iter.get_iter(), MAPPING_ACCOUNT, account, -1);
             g_free (fullpath);
         }
-
-        g_free (map_string);
-        valid = gtk_tree_model_iter_next (mappings_store, &iter);
     }
 }
 
 static bool
 csv_tximp_acct_match_check_all (GtkTreeModel *model)
 {
-    // Set iter to first entry of store
-    GtkTreeIter iter;
-    auto valid = gtk_tree_model_get_iter_first (model, &iter);
-
-    // Walk through the store looking for nullptr accounts
-    while (valid)
-    {
-        Account *account;
-        gtk_tree_model_get (model, &iter, MAPPING_ACCOUNT, &account, -1);
-        if (!account)
+    for (auto iter : GncTreeContainer<>(model))
+        if (!iter.get<Account*>(MAPPING_ACCOUNT))
             return false;
-
-        valid = gtk_tree_model_iter_next (model, &iter);
-    }
     return true;
 }
 

commit f10d7a7c8eb7f3417c587ce687b383f7aafd6757
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Aug 14 12:47:55 2023 +0800

    [assistant-csv-price-import.cpp] uses GtkTreeModelContainer

diff --git a/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp b/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp
index 3e39920cc1..50431eae15 100644
--- a/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp
+++ b/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp
@@ -35,6 +35,7 @@
 #include <glib/gi18n.h>
 #include <stdlib.h>
 
+#include "gnc-tree-model-container.hpp"
 #include "gnc-ui.h"
 #include "gnc-uri-utils.h"
 #include "gnc-ui-util.h"
@@ -921,31 +922,25 @@ void
 CsvImpPriceAssist::preview_settings_save ()
 {
     auto new_name = price_imp->settings_name();
+    GncTreeContainer<> tree_model_container{gtk_combo_box_get_model (settings_combo)};
 
     /* Check if the entry text matches an already existing preset */
     GtkTreeIter iter;
     if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
     {
-
-        auto model = gtk_combo_box_get_model (settings_combo);
-        bool valid = gtk_tree_model_get_iter_first (model, &iter);
-        while (valid)
+        for (auto iter : tree_model_container)
         {
             // Walk through the list, reading each row
-            CsvPriceImpSettings *preset;
-            gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
-
-            if (preset && (preset->m_name == std::string(new_name)))
+            auto preset = iter.get<CsvPriceImpSettings*>(SET_GROUP);
+            if (preset && preset->m_name == new_name)
             {
-                auto response = gnc_ok_cancel_dialog (GTK_WINDOW(csv_imp_asst),
-                        GTK_RESPONSE_OK,
-                        "%s", _("Setting name already exists, overwrite?"));
+                auto response = gnc_ok_cancel_dialog (GTK_WINDOW(csv_imp_asst), GTK_RESPONSE_OK,
+                                                      "%s", _("Setting name already exists, overwrite?"));
                 if (response != GTK_RESPONSE_OK)
                     return;
 
                 break;
             }
-            valid = gtk_tree_model_iter_next (model, &iter);
         }
     }
 
@@ -957,24 +952,13 @@ CsvImpPriceAssist::preview_settings_save ()
 
         // Update the settings store
         preview_populate_settings_combo();
-        auto model = gtk_combo_box_get_model (settings_combo);
-
-        // Get the first entry in model
-        GtkTreeIter   iter;
-        bool valid = gtk_tree_model_get_iter_first (model, &iter);
-        while (valid)
-        {
-            // Walk through the list, reading each row
-            gchar *name = nullptr;
-            gtk_tree_model_get (model, &iter, SET_NAME, &name, -1);
-
-            if (g_strcmp0 (name, new_name.c_str()) == 0) // Set Active, the one Saved.
-                gtk_combo_box_set_active_iter (settings_combo, &iter);
 
-            g_free (name);
-
-            valid = gtk_tree_model_iter_next (model, &iter);
-        }
+        for (auto iter : tree_model_container)
+            if (iter.get_string (SET_NAME) == new_name) // Set Active, the one Saved.
+            {
+                gtk_combo_box_set_active_iter (settings_combo, &iter.get_iter());
+                break;
+            }
     }
     else
         gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
@@ -1516,7 +1500,6 @@ CsvImpPriceAssist::preview_row_fill_state_cells (GtkListStore *store, GtkTreeIte
 GtkWidget*
 CsvImpPriceAssist::preview_cbox_factory (GtkTreeModel* model, uint32_t colnum)
 {
-    GtkTreeIter iter;
     auto cbox = gtk_combo_box_new_with_model(model);
 
     /* Set up a renderer for this combobox. */
@@ -1526,18 +1509,15 @@ CsvImpPriceAssist::preview_cbox_factory (GtkTreeModel* model, uint32_t colnum)
     gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(cbox),
             renderer, "text", COL_TYPE_NAME);
 
-    auto valid = gtk_tree_model_get_iter_first (model, &iter);
-    while (valid)
+    GncTreeContainer<> tree_model_container{model};
+    for (auto iter : tree_model_container)
     {
-        gint stored_col_type;
-        gtk_tree_model_get (model, &iter,
-                COL_TYPE_ID, &stored_col_type, -1);
-        if (stored_col_type == static_cast<int>( price_imp->column_types_price()[colnum]))
+        if (iter.get_int(COL_TYPE_ID) == static_cast<int>( price_imp->column_types_price()[colnum]))
+        {
+            gtk_combo_box_set_active_iter (GTK_COMBO_BOX(cbox), &iter.get_iter());
             break;
-        valid = gtk_tree_model_iter_next(model, &iter);
+        }
     }
-    if (valid)
-        gtk_combo_box_set_active_iter (GTK_COMBO_BOX(cbox), &iter);
 
     g_object_set_data (G_OBJECT(cbox), "col-num", GUINT_TO_POINTER(colnum));
     g_signal_connect (G_OBJECT(cbox), "changed",

commit d5b5d01698e9e863e624219828db5daa02899c00
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Aug 14 09:31:07 2023 +0800

    [gnc-tree-model-container.hpp] GtkTreeModelContainer

diff --git a/gnucash/gnome-utils/CMakeLists.txt b/gnucash/gnome-utils/CMakeLists.txt
index e02b68795e..28eb3607e9 100644
--- a/gnucash/gnome-utils/CMakeLists.txt
+++ b/gnucash/gnome-utils/CMakeLists.txt
@@ -113,6 +113,7 @@ set(gnome_utils_noinst_HEADERS
   gnc-autosave.h
   gnc-gobject-utils.h
   gnc-gtk-utils.h
+  gnc-tree-model-container.hpp
   gnc-option-gtk-ui.hpp
   search-param.h
 )
diff --git a/gnucash/gnome-utils/gnc-tree-model-container.hpp b/gnucash/gnome-utils/gnc-tree-model-container.hpp
new file mode 100644
index 0000000000..57f4179a3a
--- /dev/null
+++ b/gnucash/gnome-utils/gnc-tree-model-container.hpp
@@ -0,0 +1,145 @@
+/********************************************************************\
+ * gnc-tree-model-container.hpp
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_TREE_MODEL_CONTAINER_HPP
+#define GNC_TREE_MODEL_CONTAINER_HPP
+
+#include <string>
+#include <optional>
+
+class GncTreeData
+{
+public:
+    GncTreeData (GtkTreeModel* model, GtkTreeIter iter) : m_model{model}, m_iter{iter} {};
+
+    template <typename T>
+    T get (int column)
+    {
+        gpointer rv;
+        gtk_tree_model_get(m_model, &m_iter, column, &rv, -1);
+        return static_cast<T>(rv);
+    }
+
+    GtkTreeIter& get_iter () { return m_iter; };
+
+    int get_int (int column)
+    {
+        int rv;
+        gtk_tree_model_get(m_model, &m_iter, column, &rv, -1);
+        return rv;
+    }
+
+    std::string get_string (int column)
+    {
+        auto str = get<char*>(column);
+        std::string rv{str};
+        g_free (str);
+        return rv;
+    }
+
+    bool operator==(const GncTreeData& other) const
+    {
+        return (m_model == other.m_model) &&
+            (m_iter.stamp == other.m_iter.stamp) &&
+            (m_iter.user_data == other.m_iter.user_data) &&
+            (m_iter.user_data2 == other.m_iter.user_data2) &&
+            (m_iter.user_data3 == other.m_iter.user_data3);
+    }
+
+private:
+    GtkTreeModel* m_model;
+    GtkTreeIter m_iter;
+};
+
+// Custom iterator class
+template <typename ModelType>
+class GncTreeIter
+{
+public:
+    GncTreeIter(GtkTreeModel* model, std::optional<GtkTreeIter> iter) : m_model(model), m_iter(iter) {}
+
+    GncTreeIter(GtkTreeModel* model) : m_model (model)
+    {
+        GtkTreeIter iter;
+        gtk_tree_model_get_iter_first(m_model, &iter);
+        m_iter = iter;
+    }
+
+    GncTreeIter& operator++()
+    {
+        if (!m_iter.has_value())
+            throw "no value, cannot increment";
+        if (!gtk_tree_model_iter_next(m_model, &m_iter.value()))
+            m_iter = std::nullopt;
+        return *this;
+    }
+
+    ModelType operator*() const
+    {
+        if (!m_iter.has_value())
+            throw "no value, cannot dereference";
+        return ModelType (m_model, *m_iter);
+    }
+
+    bool has_value() { return m_iter.has_value(); };
+
+    bool operator==(const GncTreeIter& other) const
+    {
+        if (!m_iter.has_value() && !other.m_iter.has_value())
+            return true;
+        if (!m_iter.has_value() || !other.m_iter.has_value())
+            return false;
+        return (ModelType (m_model, *m_iter) == ModelType (m_model, *other.m_iter));
+    }
+
+    bool operator!=(const GncTreeIter& other) const { return !(*this == other); }
+
+private:
+    GtkTreeModel* m_model;
+    std::optional<GtkTreeIter> m_iter;
+};
+
+// Custom container class
+template <typename ModelType = GncTreeData>
+class GncTreeContainer
+{
+public:
+    using TreeModelIterator = GncTreeIter<ModelType>;
+
+    GncTreeContainer(GtkTreeModel* model) : m_model(model)
+    {
+        g_return_if_fail (GTK_IS_TREE_MODEL (m_model));
+        g_object_ref (m_model);
+    }
+
+    ~GncTreeContainer () { g_object_unref (m_model); }
+
+    TreeModelIterator begin() { return TreeModelIterator(m_model); };
+
+    TreeModelIterator end() { return TreeModelIterator(m_model, std::nullopt); };
+
+    bool empty() { return begin() == end(); };
+
+private:
+    GtkTreeModel* m_model;
+};
+
+#endif



Summary of changes:
 gnucash/gnome-utils/CMakeLists.txt                 |   1 +
 gnucash/gnome-utils/gnc-tree-model-container.hpp   | 145 +++++++++++++++++++++
 .../csv-imp/assistant-csv-price-import.cpp         |  58 +++------
 .../csv-imp/assistant-csv-trans-import.cpp         |  93 ++++---------
 4 files changed, 192 insertions(+), 105 deletions(-)
 create mode 100644 gnucash/gnome-utils/gnc-tree-model-container.hpp



More information about the gnucash-changes mailing list