gnucash master: Multiple changes pushed

Robert Fewell bobit at code.gnucash.org
Mon Nov 25 14:26:35 EST 2019


Updated	 via  https://github.com/Gnucash/gnucash/commit/574d1a99 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8afbe897 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/789339c4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3ac44012 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d50d3de8 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/161bb5f6 (commit)
	from  https://github.com/Gnucash/gnucash/commit/6c3b24a9 (commit)



commit 574d1a99f21a3b9af58515bc869f7426e15ad7d6
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Fri Aug 23 15:06:05 2019 +0100

    Add warning label in Import Account Matcher for Commodity
    
    When an account is selected for matching the incoming source, at the
    moment any account can be selected apart from a place holder account.
    If the required commodity is passed in, display a warning if the
    selected account is a different commodity and disable the OK button.

diff --git a/gnucash/gtkbuilder/dialog-import.glade b/gnucash/gtkbuilder/dialog-import.glade
index 4b64b0600..6423aa4a0 100644
--- a/gnucash/gtkbuilder/dialog-import.glade
+++ b/gnucash/gtkbuilder/dialog-import.glade
@@ -123,14 +123,14 @@
           </packing>
         </child>
         <child>
-          <object class="GtkBox" id="placeholder_warning_hbox">
+          <object class="GtkBox" id="warning_hbox">
             <property name="can_focus">False</property>
             <property name="margin_left">6</property>
             <property name="margin_right">6</property>
             <property name="margin_top">6</property>
             <property name="spacing">6</property>
             <child>
-              <object class="GtkImage" id="placeholder_warning_image">
+              <object class="GtkImage" id="warning_image">
                 <property name="can_focus">False</property>
                 <property name="halign">start</property>
                 <property name="icon_name">dialog-warning</property>
@@ -142,7 +142,7 @@
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="placeholder_warning_label">
+              <object class="GtkLabel" id="warning_label">
                 <property name="can_focus">False</property>
                 <property name="halign">start</property>
                 <property name="wrap">True</property>
diff --git a/gnucash/import-export/import-account-matcher.c b/gnucash/import-export/import-account-matcher.c
index 0837150d4..3c65a8bdb 100644
--- a/gnucash/import-export/import-account-matcher.c
+++ b/gnucash/import-export/import-account-matcher.c
@@ -168,24 +168,53 @@ gnc_import_add_account(GtkWidget *button, AccountPickerDialog *picker)
 }
 
 
+/***********************************************************
+ * show_warning
+ *
+ * show the warning and disable OK button
+ ************************************************************/
+static void
+show_warning (AccountPickerDialog *picker, gchar *text)
+{
+    gtk_label_set_text (GTK_LABEL(picker->warning), text);
+    gnc_label_set_alignment (picker->warning, 0.0, 0.5);
+    gtk_widget_show_all (GTK_WIDGET(picker->whbox));
+    g_free (text);
+
+    gtk_widget_set_sensitive (picker->ok_button, FALSE); // disable OK button
+}
+
+
 /***********************************************************
  * show_placeholder_warning
  *
- * show the warning when account is a place holder and disable
- * OK button
+ * show the warning when account is a place holder
  ************************************************************/
 static void
 show_placeholder_warning (AccountPickerDialog *picker, const gchar *name)
 {
-    gchar *text = g_strdup_printf (_("The account %s is a placeholder account and does not allow "
+    gchar *text = g_strdup_printf (_("The account '%s' is a placeholder account and does not allow "
                                      "transactions. Please choose a different account."), name);
 
-    gtk_label_set_text (GTK_LABEL(picker->pwarning), text);
-    gnc_label_set_alignment (picker->pwarning, 0.0, 0.5);
-    gtk_widget_show_all (GTK_WIDGET(picker->pwhbox));
-    g_free (text);
+    show_warning (picker, text);
+}
 
-    gtk_widget_set_sensitive (picker->ok_button, FALSE); // disable OK button
+
+/***********************************************************
+ * show_commodity_warning
+ *
+ * show the warning when account is a different commodity to that
+ * required
+ ************************************************************/
+static void
+show_commodity_warning (AccountPickerDialog *picker, const gchar *name)
+{
+    const gchar *com_name = gnc_commodity_get_fullname (picker->new_account_default_commodity);
+    gchar *text = g_strdup_printf (_("The account '%s' has a different commodity to the "
+                                     "one required, '%s'. Please choose a different account."),
+                                      name, com_name);
+
+    show_warning (picker, text);
 }
 
 
@@ -198,9 +227,15 @@ static void
 account_tree_row_changed_cb (GtkTreeSelection *selection,
                              AccountPickerDialog *picker)
 {
-
     Account *sel_account = gnc_tree_view_account_get_selected_account (picker->account_tree);
 
+    if (!sel_account)
+    {
+        gtk_widget_hide (GTK_WIDGET(picker->whbox)); // hide the warning
+        gtk_widget_set_sensitive (picker->ok_button, FALSE); // disable OK button
+        return;
+    }
+
     gtk_widget_set_sensitive (picker->ok_button, TRUE); // enable OK button
 
     /* See if the selected account is a placeholder. */
@@ -210,8 +245,15 @@ account_tree_row_changed_cb (GtkTreeSelection *selection,
 
         show_placeholder_warning (picker, retval_name);
     }
+    else if (picker->new_account_default_commodity &&
+                (!gnc_commodity_equal (xaccAccountGetCommodity (sel_account),
+                 picker->new_account_default_commodity))) // check commodity
+    {
+        const gchar *retval_name = xaccAccountGetName (sel_account);
+        show_commodity_warning (picker, retval_name);
+    }
     else
-        gtk_widget_hide (GTK_WIDGET(picker->pwhbox)); // hide the placeholder warning
+        gtk_widget_hide (GTK_WIDGET(picker->whbox)); // hide the warning
 }
 
 
@@ -312,8 +354,8 @@ Account * gnc_import_select_account(GtkWidget *parent,
             PERR("Error opening the glade builder interface");
         }
         picker->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "account_picker_dialog"));
-        picker->pwhbox = GTK_WIDGET(gtk_builder_get_object (builder, "placeholder_warning_hbox"));
-        picker->pwarning = GTK_WIDGET(gtk_builder_get_object (builder, "placeholder_warning_label"));
+        picker->whbox = GTK_WIDGET(gtk_builder_get_object (builder, "warning_hbox"));
+        picker->warning = GTK_WIDGET(gtk_builder_get_object (builder, "warning_label"));
         picker->ok_button = GTK_WIDGET(gtk_builder_get_object (builder, "okbutton"));
 
         if (parent)
@@ -387,6 +429,14 @@ Account * gnc_import_select_account(GtkWidget *parent,
                     response = GNC_RESPONSE_NEW;
                     break;
                 }
+                else if (picker->new_account_default_commodity &&
+                            (!gnc_commodity_equal (xaccAccountGetCommodity (retval),
+                             picker->new_account_default_commodity))) // check commodity
+                {
+                    show_commodity_warning (picker, retval_name);
+                    response = GNC_RESPONSE_NEW;
+                    break;
+                }
 
                 if ( account_online_id_value != NULL)
                 {
diff --git a/gnucash/import-export/import-account-matcher.h b/gnucash/import-export/import-account-matcher.h
index d53f0b8f6..4e39515a0 100644
--- a/gnucash/import-export/import-account-matcher.h
+++ b/gnucash/import-export/import-account-matcher.h
@@ -50,8 +50,8 @@ typedef struct
     GNCAccountType       new_account_default_type;       /* new account default type, incoming */
     Account             *default_account;                /* default account for selection, incoming */
     Account             *retAccount;                     /* Account value returned to caller */
-    GtkWidget           *pwhbox;                         /* Placeholder Warning HBox */
-    GtkWidget           *pwarning;                       /* Placeholder Warning Label */
+    GtkWidget           *whbox;                          /* Warning HBox */
+    GtkWidget           *warning;                        /* Warning Label */
 } AccountPickerDialog;
 
 /**  Must be called with a string containing a unique identifier for the

commit 8afbe8977249f221c2ad9f93dbd66fa693b000c1
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Fri Aug 23 14:51:34 2019 +0100

    Change image from a stock to an icon name

diff --git a/gnucash/gtkbuilder/dialog-import.glade b/gnucash/gtkbuilder/dialog-import.glade
index 5843d186b..4b64b0600 100644
--- a/gnucash/gtkbuilder/dialog-import.glade
+++ b/gnucash/gtkbuilder/dialog-import.glade
@@ -133,7 +133,7 @@
               <object class="GtkImage" id="placeholder_warning_image">
                 <property name="can_focus">False</property>
                 <property name="halign">start</property>
-                <property name="stock">gtk-dialog-warning</property>
+                <property name="icon_name">dialog-warning</property>
               </object>
               <packing>
                 <property name="expand">False</property>

commit 789339c4b7be0281cfaa8afca038ccac8d4d45d9
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Fri Aug 23 14:44:55 2019 +0100

    Set ellipsis on Memo column of import matcher
    
    On first load the Description and Memo columns are set to the width of
    the longest piece of text which can force the Info column out of site
    so add the 'ellipsize end' to the memo column which will help keep the
    info column in view.

diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index c84792096..032866d22 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -677,7 +677,7 @@ gnc_gen_trans_onPopupMenu_cb (GtkTreeView *treeview,
 }
 
 static GtkTreeViewColumn *
-add_text_column(GtkTreeView *view, const gchar *title, int col_num)
+add_text_column(GtkTreeView *view, const gchar *title, int col_num, gboolean ellipsize)
 {
     GtkCellRenderer *renderer;
     GtkTreeViewColumn *column;
@@ -689,6 +689,9 @@ add_text_column(GtkTreeView *view, const gchar *title, int col_num)
               "background", DOWNLOADED_COL_COLOR,
               NULL);
 
+    if (ellipsize)
+        g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+
     // If date column, use the time64 value for the sorting.
     if (col_num == DOWNLOADED_COL_DATE_TXT)
         gtk_tree_view_column_set_sort_column_id(column, DOWNLOADED_COL_DATE_INT64);
@@ -759,12 +762,12 @@ gnc_gen_trans_init_view (GNCImportMainMatcher *info,
 
     /* Add the columns *
      * (keep the line break below to avoid a translator comment) */
-    add_text_column (view, _("Date"), DOWNLOADED_COL_DATE_TXT);
-    info->account_column = add_text_column (view, _("Account"), DOWNLOADED_COL_ACCOUNT);
+    add_text_column (view, _("Date"), DOWNLOADED_COL_DATE_TXT, FALSE);
+    info->account_column = add_text_column (view, _("Account"), DOWNLOADED_COL_ACCOUNT, FALSE);
     gtk_tree_view_column_set_visible (info->account_column, show_account);
-    add_text_column (view, _("Amount"), DOWNLOADED_COL_AMOUNT);
-    add_text_column (view, _("Description"), DOWNLOADED_COL_DESCRIPTION);
-    add_text_column (view, _("Memo"), DOWNLOADED_COL_MEMO);
+    add_text_column (view, _("Amount"), DOWNLOADED_COL_AMOUNT, FALSE);
+    add_text_column (view, _("Description"), DOWNLOADED_COL_DESCRIPTION, FALSE);
+    add_text_column (view, _("Memo"), DOWNLOADED_COL_MEMO, TRUE);
     add_toggle_column (view,
                        /* toggle column: add new transaction */
                        _("A"), DOWNLOADED_COL_ACTION_ADD,
@@ -789,7 +792,8 @@ gnc_gen_trans_init_view (GNCImportMainMatcher *info,
 
     gtk_tree_view_append_column (info->view, column);
 
-    add_text_column (view, _("Additional Comments"), DOWNLOADED_COL_ACTION_INFO);
+    column = add_text_column (view, _("Additional Comments"), DOWNLOADED_COL_ACTION_INFO, FALSE);
+    gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
 
     /* default sort order */
     gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(store),

commit 3ac440121d51cc5d6128482e926b84c64dc2cc67
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Fri Aug 23 14:35:36 2019 +0100

    Info column in matcher looks odd if other columns are resized
    
    The Info column has a cell_render_pixbuf and a cell_render_text aligned
    to the left. If the info column is made larger, the text does not keep
    to the left so split them into there own columns.

diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index b9dfed826..c84792096 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -786,19 +786,11 @@ gnc_gen_trans_init_view (GNCImportMainMatcher *info,
              "pixbuf", DOWNLOADED_COL_ACTION_PIXBUF,
              "cell-background", DOWNLOADED_COL_COLOR,
              NULL);
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start (column, renderer, TRUE);
-    gtk_tree_view_column_set_attributes (column, renderer,
-                                         "text", DOWNLOADED_COL_ACTION_INFO,
-                                         "background", DOWNLOADED_COL_COLOR,
-                                         NULL);
-    gtk_tree_view_column_set_sort_column_id (column, DOWNLOADED_COL_ACTION_INFO);
-    g_object_set (G_OBJECT(column),
-                  "reorderable", TRUE,
-                  "resizable", TRUE,
-                  NULL);
+
     gtk_tree_view_append_column (info->view, column);
 
+    add_text_column (view, _("Additional Comments"), DOWNLOADED_COL_ACTION_INFO);
+
     /* default sort order */
     gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(store),
                                           DOWNLOADED_COL_DATE_INT64,

commit d50d3de8b54e2ced3bb53956b0769a59e3818192
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Fri Aug 23 14:20:56 2019 +0100

    Remove a vertical black line from import matcher
    
    When change a row to skipping it, a pixbuf is created with just a
    vertical black line and looks odd. There is no reason to create a
    pixbuf so change the value in the store to NULL. Do the same when
    the 'match missing' is displayed.

diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index dfb63ae64..b9dfed826 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -1171,6 +1171,7 @@ refresh_model_row (GNCImportMainMatcher *gui,
     const gchar *ro_text;
     gchar *int_required_class, *int_prob_required_class, *int_not_required_class;
     gchar *class_extension = NULL;
+    gboolean show_pixbuf = TRUE;
     Split *split;
     time64 date;
     gnc_numeric amount;
@@ -1302,6 +1303,7 @@ refresh_model_row (GNCImportMainMatcher *gui,
             {
                 color = get_required_color (int_required_class);
                 ro_text = _("Match missing!");
+                show_pixbuf = FALSE;
                 remove_child_row (model, iter);
             }
         }
@@ -1327,6 +1329,7 @@ refresh_model_row (GNCImportMainMatcher *gui,
             {
                 color = get_required_color (int_required_class);
                 ro_text = _("Match missing!");
+                show_pixbuf = FALSE;
                 remove_child_row (model, iter);
             }
         }
@@ -1334,11 +1337,13 @@ refresh_model_row (GNCImportMainMatcher *gui,
     case GNCImport_SKIP:
         color = get_required_color (int_required_class);
         ro_text = _("Do not import (no action selected)");
+        show_pixbuf = FALSE;
         remove_child_row (model, iter);
         break;
     default:
         color = "white";
         ro_text = "WRITEME, this is an unknown action";
+        show_pixbuf = FALSE;
         break;
     }
 
@@ -1360,14 +1365,8 @@ refresh_model_row (GNCImportMainMatcher *gui,
                         -1);
     if (gnc_import_TransInfo_get_action (info) == GNCImport_SKIP)
     {
-        /*Show the best match's confidence pixmap in the info column*/
-        gtk_tree_store_set (store, iter,
-                            DOWNLOADED_COL_ACTION_PIXBUF,
-                            gen_probability_pixbuf (gnc_import_MatchInfo_get_probability
-                                    (gnc_import_TransInfo_get_selected_match (info)),
-                                    gui->user_settings,
-                                    GTK_WIDGET(gui->view)),
-                            -1);
+        /*If skipping the row, there is no best match's confidence pixmap*/
+        gtk_tree_store_set (store, iter, DOWNLOADED_COL_ACTION_PIXBUF, NULL, -1);
     }
 
     gtk_tree_store_set (store, iter,
@@ -1377,13 +1376,16 @@ refresh_model_row (GNCImportMainMatcher *gui,
     if (gnc_import_TransInfo_get_action (info) == GNCImport_CLEAR)
     {
         /*Show the best match's confidence pixmap in the info column*/
-        gtk_tree_store_set (store, iter,
-                            DOWNLOADED_COL_ACTION_PIXBUF,
-                            gen_probability_pixbuf (gnc_import_MatchInfo_get_probability
-                                    (gnc_import_TransInfo_get_selected_match (info)),
-                                    gui->user_settings,
-                                    GTK_WIDGET(gui->view)),
-                            -1);
+        if (show_pixbuf)
+            gtk_tree_store_set (store, iter,
+                                DOWNLOADED_COL_ACTION_PIXBUF,
+                                gen_probability_pixbuf (gnc_import_MatchInfo_get_probability
+                                        (gnc_import_TransInfo_get_selected_match (info)),
+                                        gui->user_settings,
+                                        GTK_WIDGET(gui->view)),
+                                -1);
+        else
+            gtk_tree_store_set (store, iter, DOWNLOADED_COL_ACTION_PIXBUF, NULL, -1);
     }
 
     gtk_tree_store_set (store, iter,
@@ -1393,13 +1395,16 @@ refresh_model_row (GNCImportMainMatcher *gui,
     if (gnc_import_TransInfo_get_action (info) == GNCImport_UPDATE)
     {
         /*Show the best match's confidence pixmap in the info column*/
-        gtk_tree_store_set (store, iter,
-                            DOWNLOADED_COL_ACTION_PIXBUF,
-                            gen_probability_pixbuf (gnc_import_MatchInfo_get_probability
-                                    (gnc_import_TransInfo_get_selected_match (info)),
-                                    gui->user_settings,
-                                    GTK_WIDGET(gui->view)),
-                            -1);
+        if (show_pixbuf)
+            gtk_tree_store_set (store, iter,
+                                DOWNLOADED_COL_ACTION_PIXBUF,
+                                gen_probability_pixbuf (gnc_import_MatchInfo_get_probability
+                                        (gnc_import_TransInfo_get_selected_match (info)),
+                                        gui->user_settings,
+                                        GTK_WIDGET(gui->view)),
+                                -1);
+        else
+            gtk_tree_store_set (store, iter, DOWNLOADED_COL_ACTION_PIXBUF, NULL, -1);
     }
 
     // show child row if 'show matched info' is toggled

commit 161bb5f65d1d18ee24fac1ed8cbc282345f0dd43
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Fri Aug 23 14:09:27 2019 +0100

    Change import-main-matcher to display matched information
    
    Change the import-main-matcher tree view to use a tree store and add
    the matched information as a child row.

diff --git a/common/debug/valgrind/valgrind-compiz.supp b/common/debug/valgrind/valgrind-compiz.supp
new file mode 100644
index 000000000..4e524e6ca
--- /dev/null
+++ b/common/debug/valgrind/valgrind-compiz.supp
@@ -0,0 +1,919 @@
+# -*- tab-width: 3; indent-tabs-mode: nil -*-
+#
+# GNOME supressions base.supp:
+#  git://github.com/dtrebbien/GNOME.supp.git
+#  Copyright (C) 2012  Daniel Trebbien
+#
+#  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, write to the Free Software
+#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+# Python supressions valgrind-python.supp:
+#  http://hg.python.org/cpython
+#  Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#  2011, 2012 Python Software Foundation; All Rights Reserved
+#  PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+#  --------------------------------------------
+#
+# 1. This LICENSE AGREEMENT is between the Python Software Foundation
+# ("PSF"), and the Individual or Organization ("Licensee") accessing and
+# otherwise using this software ("Python") in source or binary form and
+# its associated documentation.
+
+# 2. Subject to the terms and conditions of this License Agreement, PSF hereby
+# grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+# analyze, test, perform and/or display publicly, prepare derivative works,
+# distribute, and otherwise use Python alone or in any derivative version,
+# provided, however, that PSF's License Agreement and PSF's notice of copyright,
+# i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012 Python Software Foundation; All Rights Reserved" are retained in Python
+# alone or in any derivative version prepared by Licensee.
+
+# 3. In the event Licensee prepares a derivative work that is based on
+# or incorporates Python or any part thereof, and wants to make
+# the derivative work available to others as provided herein, then
+# Licensee hereby agrees to include in any such work a brief summary of
+# the changes made to Python.
+
+# 4. PSF is making Python available to Licensee on an "AS IS"
+# basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+# IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+# DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+# FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+# INFRINGE ANY THIRD PARTY RIGHTS.
+# 
+# 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+# FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+# A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+# OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+# 
+# 6. This License Agreement will automatically terminate upon a material
+# breach of its terms and conditions.
+
+# 7. Nothing in this License Agreement shall be deemed to create any
+# relationship of agency, partnership, or joint venture between PSF and
+# Licensee.  This License Agreement does not grant permission to use PSF
+# trademarks or trade name in a trademark sense to endorse or promote
+# products or services of Licensee, or any third party.
+# 
+# 8. By copying, installing or otherwise using Python, Licensee
+# agrees to be bound by the terms and conditions of this License
+# Agreement.
+#
+# All other supressions:
+#
+#  Copyright © 2012 Canonical Ltd.
+# 
+#  Permission to use, copy, modify, distribute, and sell this software
+#  and its documentation for any purpose is hereby granted without
+#  fee, provided that the above copyright notice appear in all copies
+#  and that both that copyright notice and this permission notice
+#  appear in supporting documentation, and that the name of
+#  Canonical Ltd. not be used in advertising or publicity pertaining to
+#  distribution of the software without specific, written prior permission.
+#  Canonical Ltd. makes no representations about the suitability of this
+#  software for any purpose. It is provided "as is" without express or
+#  implied warranty.
+# 
+#  CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+#  NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+#  OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+#  NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+#  WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+# 
+#  Authored by: Sam Spilsbury <sam.spilsbury at canonical.com>
+# /
+
+{
+    xmlReadFile leaks a string
+    Memcheck:Leak
+    fun:malloc
+    fun:xmlStrndup
+    ...
+    fun:xmlReadFile
+}
+
+{
+    xmlReadFile leaks an xmlNewCharEncodingHandler
+    Memcheck:Leak
+    fun:malloc
+    fun:xmlNewCharEncodingHandler
+    ...
+    fun:xmlReadFile
+}
+
+{
+    xmInitCharEncodingHandlers leaks
+    Memcheck:Leak
+    fun:*alloc*
+    fun:xmlInitCharEncodingHandlers
+}
+
+{
+    xmlReadFile leaks an xmlNewRMutex
+    Memcheck:Leak
+    fun:malloc
+    fun:xmlNewRMutex
+    ...
+    fun:xmlReadFile
+}
+
+{
+    xmlParseDocument leaks an xmlNewMutex
+    Memcheck:Leak
+    fun:malloc
+    fun:xmlNewMutex
+    ...
+    fun:xmlParseDocument
+}
+
+{
+    dlopen leaks some tokens
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:dlopen*
+}
+
+{
+    dlclose calls malloc and leaks
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:dlclose*
+}
+
+{
+    import_submodule
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:import_*module*
+}
+
+{
+    everything from PyInitialize_Ex
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:Py_InitializeEx*
+}
+
+{
+    everything from PySys*
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:PySys*
+}
+
+{
+    everything from PyList
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:PyList_*
+}
+
+{
+    everything from PyThread
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:PyThread*
+}
+
+{
+    everything from PyStructSequence
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:PyStructSequence*
+}
+
+
+
+{
+   don't care about protobuf
+   Memcheck:Leak
+   ...
+   fun:_ZN6google8protobuf24SimpleDescriptorDatabase15DescriptorIndexISt4pairIPKviEE7AddFileERKNS0_19FileDescriptorProtoES6_
+}
+
+{
+    google::protobuf::protobufAddDesc
+    Memcheck:Leak
+    ...
+    fun:*protobuf*AddDesc*
+}
+
+{
+   don't care about protobuf
+   Memcheck:Leak
+   ...
+   fun:_ZN6google8protobuf8internal10OnShutdownEPFvvE
+}
+
+{
+   g_types are never free'd
+   Memcheck:Leak
+   ...
+   fun:g_type*
+}
+
+{
+    g_settings_class_init intentionally leaks signals
+    Memcheck:Leak
+    fun:*alloc
+    ...
+    fun:g_signal_new
+    ...
+    fun:g_type_class_ref
+    ...
+    fun:g_object_new
+}
+
+{
+    g_list_append calls g_slice_alloc can call g_private_get which seems to leave reachable blocks
+    Memcheck:Leak
+    fun:malloc
+    ...
+    fun:g_private_get
+    fun:g_slice_alloc
+    fun:g_list_append
+}
+
+{
+    g_list_append calls g_mutex_lock which calls malloc
+    Memcheck:Leak
+    fun:malloc
+    ...
+    fun:g_mutex*
+    ...
+    fun:g_slice_alloc
+    fun:g_list_append
+}
+
+# not entirely certain about this
+
+{
+    g_list_append calls thread_memory_from_self, but we can't detect it
+    Memcheck:Leak
+    fun:calloc
+    ...
+    fun:g_slice_alloc
+    fun:g_list_append
+}
+
+{
+    g_variant_builder_end calls g_rec_mutex_lock
+    Memcheck:Leak
+    fun:malloc
+    ...
+    fun:g_slice_alloc
+    ...
+    fun:g_rec_mutex_lock
+    fun:g_variant_type_info_get
+    ...
+    fun:g_variant_builder_end
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Cond
+   fun:__GI___strcasecmp_l
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Value8
+   fun:__GI___strcasecmp_l
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Addr8
+   fun:__strspn_sse42
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Cond
+   fun:__strspn_sse42
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Addr4
+   fun:FcConfigFileExists
+}
+
+
+{
+   g_hash_table_insert_node() in ghash.c
+   Memcheck:Leak
+   ...
+   fun:g_memdup
+   fun:g_hash_table_insert_node
+}
+
+{
+   g_hash_table_resize() in ghash.c
+   Memcheck:Leak
+   ...
+   fun:g_hash_table_resize
+}
+
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_application_name
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_home_dir
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_host_name
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_prgname
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_real_name
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_system_config_dirs
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_system_data_dirs
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_tmp_dir
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_user_cache_dir
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_user_config_dir
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_user_data_dir
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_user_name
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_user_runtime_dir
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_get_user_special_dir
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_reload_user_special_dirs_cache
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_set_application_name
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_set_prgname
+}
+
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_random_double
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_random_double_range
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_random_int
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_random_int_range
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_random_set_seed
+}
+
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_bus_get
+   fun:g_bus_own_name
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_hash_table_new
+   fun:g_bus_own_name
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_main_context_ref_thread_default
+   fun:g_bus_own_name
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_hash_table_new
+   fun:g_bus_own_name_on_connection
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:g_variant_new
+   fun:g_bus_unown_name
+}
+
+{
+   _g_dbus_initialize() in gio/gdbusprivate.c
+   Memcheck:Leak
+   ...
+   fun:_g_dbus_initialize
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:FcConfigSubstitute*
+   fun:pango_cairo_fc_font_map_fontset_key_substitute
+}
+
+{
+   _gtk_accessibility_init() in gail.c
+   Memcheck:Leak
+   ...
+   fun:atk_add_focus_tracker
+   fun:_gtk_accessibility_init
+}
+
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:gdk_display_manager_get
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:gdk_display_manager_get_default_display
+}
+
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:gdk_display_get_default
+}
+
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:gtk_clipboard_get_for_display
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:gtk_clipboard_request_contents
+}
+
+{
+   gtk_im_module_initialize() in gtkimmodule.c
+   Memcheck:Leak
+   ...
+   fun:gtk_im_module_initialize
+}
+
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:gtk_widget_get_style_context
+}
+
+{
+    g_main_context_default calls malloc
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_main_context_new
+    fun:g_main_context_default
+}
+
+{
+    g_main_context_default calls g_mutex_lock
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_mutex_lock
+    ...
+    fun:g_main_context_default
+}
+
+{
+    g_main_context_default calls g_cond_broadcast
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_cond_broadcast
+    ...
+    fun:g_main_context_default
+}
+
+{
+    g_main_context_default calls g_slist_prepend
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_slist_prepend
+    ...
+    fun:g_main_context_default
+}
+
+{
+    g_get_worker_context calls malloc
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_main_context_new
+    fun:g_get_worker_context
+}
+
+{
+    g_get_worker_context calls g_thread_new
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_thread_new
+    fun:g_get_worker_context
+}
+
+{
+    g_get_worker_context calls g_mutex_lock
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_mutex_lock
+    ...
+    fun:g_get_worker_context
+}
+
+{
+    g_main_context_iterate calls malloc
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_main_context_iterate*
+}
+
+{
+    g_main_loop_run calls malloc
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_main_loop_run*
+}
+
+{
+    g_thread_proxy calls malloc
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_thread_proxy
+}
+
+{
+    g_unix_signal_add_full calls g_mutex_lock which calls malloc
+    Memcheck:Leak
+    fun:*alloc*
+    ...
+    fun:g_mutex_lock
+    ...
+    fun:g_unix_signal_add_full
+}
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:gtk_source_style_scheme_manager_get_default
+}
+
+
+{
+   <insert_a_suppression_name_here>
+   Memcheck:Leak
+   ...
+   fun:gtk_source_style_scheme_get_style
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 4
+   Memcheck:Addr4
+   fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 4
+   Memcheck:Value4
+   fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64)
+   Memcheck:Value8
+   fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+   ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+   Memcheck:Cond
+   fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+   Suppress leaking the GIL.  Happens once per process, see comment in ceval.c.
+   Memcheck:Leak
+   fun:malloc
+   fun:PyThread_allocate_lock
+   fun:PyEval_InitThreads
+}
+
+{
+   Suppress leaking the GIL after a fork.
+   Memcheck:Leak
+   fun:malloc
+   fun:PyThread_allocate_lock
+   fun:PyEval_ReInitThreads
+}
+
+{
+   Suppress leaking the autoTLSkey.  This looks like it shouldn't leak though.
+   Memcheck:Leak
+   fun:malloc
+   fun:PyThread_create_key
+   fun:_PyGILState_Init
+   fun:Py_InitializeEx
+   fun:Py_Main
+}
+
+{
+   Hmmm, is this a real leak or like the GIL?
+   Memcheck:Leak
+   fun:malloc
+   fun:PyThread_ReInitTLS
+}
+
+{
+   Handle PyMalloc confusing valgrind (possibly leaked)
+   Memcheck:Leak
+   fun:realloc
+   fun:_PyObject_GC_Resize
+}
+
+{
+   Handle PyMalloc confusing valgrind (possibly leaked)
+   Memcheck:Leak
+   fun:malloc
+   fun:_PyObject_GC_New
+}
+
+{
+   Handle PyMalloc confusing valgrind (possibly leaked)
+   Memcheck:Leak
+   fun:malloc
+   fun:*PyObject*Malloc*
+}
+
+{
+   Handle PyMalloc confusing valgrind (possibly leaked)
+   Memcheck:Leak
+   fun:malloc
+   fun:_PyObject_GC_NewVar
+}
+
+{
+    Dictresize confuses valgrind too
+    Memcheck:Leak
+    ...
+    fun:dictresize*
+}
+
+{
+    PyString can confuse it too
+    Memcheck:Leak
+    ...
+    fun:PyString*
+}
+
+#
+# Non-python specific leaks
+#
+
+{
+   Handle pthread issue (possibly leaked)
+   Memcheck:Leak
+   fun:calloc
+   fun:allocate_dtv
+   fun:_dl_allocate_tls_storage
+   fun:_dl_allocate_tls
+}
+
+{
+   Handle pthread issue (possibly leaked)
+   Memcheck:Leak
+   fun:memalign
+   fun:_dl_allocate_tls_storage
+   fun:_dl_allocate_tls
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 4
+   Memcheck:Addr4
+   fun:PyObject_Free
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 4
+   Memcheck:Value4
+   fun:PyObject_Free
+}
+
+{
+   ADDRESS_IN_RANGE/Use of uninitialised value of size 8
+   Memcheck:Addr8
+   fun:PyObject_Free
+}
+
+{
+   ADDRESS_IN_RANGE/Use of uninitialised value of size 8
+   Memcheck:Value8
+   fun:PyObject_Free
+}
+
+{
+   ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+   Memcheck:Cond
+   fun:PyObject_Free
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 4
+   Memcheck:Addr4
+   fun:PyObject_Realloc*
+}
+
+{
+   ADDRESS_IN_RANGE/Invalid read of size 4
+   Memcheck:Value4
+   fun:PyObject_Realloc*
+}
+
+{
+   ADDRESS_IN_RANGE/Use of uninitialised value of size 8
+   Memcheck:Addr8
+   fun:PyObject_Realloc*
+}
+
+{
+   ADDRESS_IN_RANGE/Use of uninitialised value of size 8
+   Memcheck:Value8
+   fun:PyObject_Realloc*
+}
+
+{
+   ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+   Memcheck:Cond
+   fun:PyObject_Realloc*
+}
+
+# Additional suppressions for the unified decimal tests:
+{
+   test_decimal
+   Memcheck:Addr4
+   fun:PyUnicodeUCS2_FSConverter
+}
+
+{
+   test_decimal2
+   Memcheck:Addr4
+   fun:PyUnicode_FSConverter
+}
diff --git a/gnucash/gtkbuilder/dialog-import.glade b/gnucash/gtkbuilder/dialog-import.glade
index 8a457f18c..5843d186b 100644
--- a/gnucash/gtkbuilder/dialog-import.glade
+++ b/gnucash/gtkbuilder/dialog-import.glade
@@ -1153,7 +1153,7 @@
       <object class="GtkLabel" id="heading_label">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="label" translatable="yes">List of downloaded transactions (source split shown)</property>
+        <property name="label" translatable="yes">List of downloaded transactions (source split and matched information shown)</property>
         <property name="justify">center</property>
       </object>
       <packing>
@@ -1190,18 +1190,46 @@
       </packing>
     </child>
     <child>
-      <object class="GtkCheckButton" id="show_source_account_button">
-        <property name="label" translatable="yes">Show the Source Account column</property>
+      <object class="GtkBox">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">False</property>
+        <property name="can_focus">False</property>
         <property name="halign">center</property>
-        <property name="draw_indicator">True</property>
+        <child>
+          <object class="GtkCheckButton" id="show_source_account_button">
+            <property name="label" translatable="yes">Show the _Account column</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="halign">center</property>
+            <property name="use_underline">True</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="show_matched_info_button">
+            <property name="label" translatable="yes">Show _matched information</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="use_underline">True</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
       </object>
       <packing>
         <property name="expand">False</property>
         <property name="fill">True</property>
-        <property name="position">3</property>
+        <property name="position">2</property>
       </packing>
     </child>
   </object>
diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index b42c497d7..dfb63ae64 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -66,6 +66,8 @@ struct _main_matcher_info
     gpointer user_data;
     GNCImportPendingMatches *pending_matches;
     GtkTreeViewColumn *account_column;
+    GtkWidget         *show_account_column;
+    GtkWidget         *show_matched_info;
     gboolean add_toggled;   // flag to indicate that add has been toggled to stop selection
 };
 
@@ -85,6 +87,7 @@ enum downloaded_cols
     DOWNLOADED_COL_ACTION_PIXBUF,
     DOWNLOADED_COL_DATA,
     DOWNLOADED_COL_COLOR,
+    DOWNLOADED_COL_ENABLE,
     NUM_DOWNLOADED_COLS
 };
 
@@ -433,6 +436,11 @@ gnc_gen_trans_assign_transfer_account (GtkTreeView *treeview,
     DEBUG("path  = %s", path_str);
     g_free (path_str);
     DEBUG("account passed in = %s", gnc_get_account_name_for_register (*new_acc));
+
+    // only allow response at the top level
+    if (gtk_tree_path_get_depth (path) != 1)
+        return;
+
     model = gtk_tree_view_get_model (treeview);
     if (gtk_tree_model_get_iter (model, &iter, path))
     {
@@ -713,6 +721,8 @@ add_toggle_column (GtkTreeView *view, const gchar *title, int col_num,
              (title, renderer,
               "active", col_num,
               "cell-background", DOWNLOADED_COL_COLOR,
+              "activatable", DOWNLOADED_COL_ENABLE,
+              "visible", DOWNLOADED_COL_ENABLE,
               NULL);
     gtk_tree_view_column_set_sort_column_id (column, col_num);
     g_object_set (G_OBJECT(column),
@@ -729,17 +739,18 @@ gnc_gen_trans_init_view (GNCImportMainMatcher *info,
                          gboolean show_update)
 {
     GtkTreeView *view;
-    GtkListStore *store;
+    GtkTreeStore *store;
     GtkCellRenderer *renderer;
     GtkTreeViewColumn *column;
     GtkTreeSelection *selection;
 
     view = info->view;
-    store = gtk_list_store_new (NUM_DOWNLOADED_COLS, G_TYPE_STRING, G_TYPE_INT64,
+    store = gtk_tree_store_new (NUM_DOWNLOADED_COLS, G_TYPE_STRING, G_TYPE_INT64,
                                 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_DOUBLE,
                                 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN,
                                 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING,
-                                GDK_TYPE_PIXBUF, G_TYPE_POINTER, G_TYPE_STRING);
+                                GDK_TYPE_PIXBUF, G_TYPE_POINTER, G_TYPE_STRING,
+                                G_TYPE_BOOLEAN);
     gtk_tree_view_set_model (view, GTK_TREE_MODEL(store));
     g_object_unref (store);
 
@@ -831,6 +842,11 @@ view_selection_function (GtkTreeSelection *selection,
     GNCImportMainMatcher *info = data;
 
     ENTER("view_selection_function");
+
+    // only allow response at the top level
+    if (gtk_tree_path_get_depth (path) != 1)
+        return FALSE;
+
     if (gtk_tree_model_get_iter(model, &iter, path))
     {
         gtk_tree_model_get (model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1);
@@ -890,7 +906,24 @@ show_account_column_toggled_cb (GtkToggleButton *togglebutton,
                                 GNCImportMainMatcher *info)
 {
     gtk_tree_view_column_set_visible (info->account_column,
-         gtk_toggle_button_get_active (togglebutton));
+        gtk_toggle_button_get_active (togglebutton));
+}
+
+static void
+show_matched_info_toggled_cb (GtkToggleButton *togglebutton,
+                                GNCImportMainMatcher *info)
+{
+    if (gtk_toggle_button_get_active (togglebutton))
+    {
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->show_account_column), TRUE);
+        gtk_tree_view_expand_all (info->view);
+    }
+    else
+    {
+        gtk_tree_view_column_set_visible (info->account_column,
+            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->show_account_column)));
+        gtk_tree_view_collapse_all (info->view);
+    }
 }
 
 GNCImportMainMatcher *gnc_gen_trans_list_new (GtkWidget *parent,
@@ -905,7 +938,6 @@ GNCImportMainMatcher *gnc_gen_trans_list_new (GtkWidget *parent,
     gboolean show_update;
     GtkStyleContext *stylectxt;
     GdkRGBA color;
-    GtkWidget *button;
 
     info = g_new0 (GNCImportMainMatcher, 1);
     info->pending_matches = gnc_import_PendingMatches_new();
@@ -934,11 +966,15 @@ GNCImportMainMatcher *gnc_gen_trans_list_new (GtkWidget *parent,
     info->view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "downloaded_view"));
     g_assert (info->view != NULL);
 
-    button = GTK_WIDGET(gtk_builder_get_object (builder, "show_source_account_button"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), all_from_same_account);
-    g_signal_connect (G_OBJECT(button), "toggled",
+    info->show_account_column = GTK_WIDGET(gtk_builder_get_object (builder, "show_source_account_button"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->show_account_column), all_from_same_account);
+    g_signal_connect (G_OBJECT(info->show_account_column), "toggled",
                       G_CALLBACK(show_account_column_toggled_cb), info);
 
+    info->show_matched_info = GTK_WIDGET(gtk_builder_get_object (builder, "show_matched_info_button"));
+    g_signal_connect (G_OBJECT(info->show_matched_info), "toggled",
+                      G_CALLBACK(show_matched_info_toggled_cb), info);
+
     show_update = gnc_import_Settings_get_action_update_enabled (info->user_settings);
     gnc_gen_trans_init_view (info, all_from_same_account, show_update);
     heading_label = GTK_WIDGET(gtk_builder_get_object (builder, "heading_label"));
@@ -978,7 +1014,6 @@ GNCImportMainMatcher * gnc_gen_trans_assist_new (GtkWidget *parent,
     gboolean show_update;
     GtkStyleContext *stylectxt;
     GdkRGBA color;
-    GtkWidget *button;
 
     info = g_new0 (GNCImportMainMatcher, 1);
     info->pending_matches = gnc_import_PendingMatches_new();
@@ -1007,11 +1042,15 @@ GNCImportMainMatcher * gnc_gen_trans_assist_new (GtkWidget *parent,
     info->view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "downloaded_view"));
     g_assert (info->view != NULL);
 
-    button = GTK_WIDGET(gtk_builder_get_object (builder, "show_source_account_button"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), all_from_same_account);
-    g_signal_connect (G_OBJECT(button), "toggled",
+    info->show_account_column = GTK_WIDGET(gtk_builder_get_object (builder, "show_source_account_button"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->show_account_column), all_from_same_account);
+    g_signal_connect (G_OBJECT(info->show_account_column), "toggled",
                       G_CALLBACK(show_account_column_toggled_cb), info);
 
+    info->show_matched_info = GTK_WIDGET(gtk_builder_get_object (builder, "show_matched_info_button"));
+    g_signal_connect (G_OBJECT(info->show_matched_info), "toggled",
+                      G_CALLBACK(show_matched_info_toggled_cb), info);
+
     show_update = gnc_import_Settings_get_action_update_enabled (info->user_settings);
     gnc_gen_trans_init_view (info, all_from_same_account, show_update);
     heading_label = GTK_WIDGET(gtk_builder_get_object (builder, "heading_label"));
@@ -1072,13 +1111,61 @@ get_required_color (const gchar *class_name)
     return gdk_rgba_to_string (&color);
 }
 
+static void
+remove_child_row (GtkTreeModel *model, GtkTreeIter *iter)
+{
+    if (gtk_tree_model_iter_has_child (model, iter))
+    {
+        GtkTreeIter  child;
+        gtk_tree_model_iter_nth_child (model, &child, iter, 0);
+        gtk_tree_store_remove (GTK_TREE_STORE(model), &child);
+    }
+}
+
+static void
+update_child_row (GNCImportMatchInfo *sel_match, GtkTreeModel *model, GtkTreeIter *iter)
+{
+    GtkTreeStore *store;
+    GtkTreeIter  child;
+    gchar *text = qof_print_date (xaccTransGetDate (sel_match->trans));
+    const gchar *ro_text;
+
+    const gchar *desc = xaccTransGetDescription (sel_match->trans);
+    const gchar *memo = xaccSplitGetMemo (sel_match->split);
+
+    store = GTK_TREE_STORE(model);
+
+    if (!gtk_tree_model_iter_has_child (model, iter))
+        gtk_tree_store_append (GTK_TREE_STORE(model), &child, iter);
+    else
+        gtk_tree_model_iter_nth_child (model, &child, iter, 0);
+
+    gtk_tree_store_set (store, &child, DOWNLOADED_COL_DATE_TXT, text, -1);
+
+    if (xaccTransCountSplits(sel_match->trans) == 2)
+        gtk_tree_store_set (store, &child, DOWNLOADED_COL_ACCOUNT, xaccAccountGetName (
+                            xaccSplitGetAccount (xaccSplitGetOtherSplit (sel_match->split))), -1);
+    else
+        gtk_tree_store_set (store, &child, DOWNLOADED_COL_ACCOUNT, _("-- Split Transaction --"), -1);
+
+    ro_text = xaccPrintAmount (xaccSplitGetAmount (sel_match->split),
+                               gnc_split_amount_print_info (sel_match->split, TRUE));
+
+    gtk_tree_store_set (store, &child, DOWNLOADED_COL_AMOUNT, ro_text, -1);
+    gtk_tree_store_set (store, &child, DOWNLOADED_COL_MEMO, memo, -1);
+    gtk_tree_store_set (store, &child, DOWNLOADED_COL_DESCRIPTION, desc, -1);
+
+    gtk_tree_store_set (store, &child, DOWNLOADED_COL_ENABLE, FALSE, -1);
+    g_free (text);
+}
+
 static void
 refresh_model_row (GNCImportMainMatcher *gui,
                    GtkTreeModel *model,
                    GtkTreeIter *iter,
                    GNCImportTransInfo *info)
 {
-    GtkListStore *store;
+    GtkTreeStore *store;
     GtkTreeSelection *selection;
     gchar *tmp, *imbalance, *text, *color;
     const gchar *ro_text;
@@ -1092,8 +1179,8 @@ refresh_model_row (GNCImportMainMatcher *gui,
     g_assert (info);
     /*DEBUG("Begin");*/
 
-    store = GTK_LIST_STORE(model);
-    gtk_list_store_set (store, iter, DOWNLOADED_COL_DATA, info, -1);
+    store = GTK_TREE_STORE(model);
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_DATA, info, -1);
 
     if (gui->dark_theme == TRUE)
         class_extension = "-dark";
@@ -1102,32 +1189,35 @@ refresh_model_row (GNCImportMainMatcher *gui,
     int_prob_required_class = g_strconcat (CSS_INT_PROB_REQUIRED_CLASS, class_extension, NULL);
     int_not_required_class = g_strconcat (CSS_INT_NOT_REQUIRED_CLASS, class_extension, NULL);
 
+    /* This controls the visibility of the toggle cells */
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_ENABLE, TRUE, -1);
+
     /*Account:*/
     split = gnc_import_TransInfo_get_fsplit (info);
     g_assert (split); // Must not be NULL
     ro_text = xaccAccountGetName (xaccSplitGetAccount (split));
-    gtk_list_store_set (store, iter, DOWNLOADED_COL_ACCOUNT, ro_text, -1);
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_ACCOUNT, ro_text, -1);
 
     /*Date*/
     date = xaccTransGetDate (gnc_import_TransInfo_get_trans (info));
     text = qof_print_date (date);
-    gtk_list_store_set (store, iter, DOWNLOADED_COL_DATE_TXT, text, -1);
-    gtk_list_store_set (store, iter, DOWNLOADED_COL_DATE_INT64, date, -1);
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_DATE_TXT, text, -1);
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_DATE_INT64, date, -1);
     g_free(text);
 
     /*Amount*/
     amount = xaccSplitGetAmount (split);
     ro_text = xaccPrintAmount (amount, gnc_split_amount_print_info (split, TRUE));
-    gtk_list_store_set (store, iter, DOWNLOADED_COL_AMOUNT, ro_text, -1);
-    gtk_list_store_set (store, iter, DOWNLOADED_COL_AMOUNT_DOUBLE, gnc_numeric_to_double (amount), -1);
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_AMOUNT, ro_text, -1);
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_AMOUNT_DOUBLE, gnc_numeric_to_double (amount), -1);
 
     /*Description*/
     ro_text = xaccTransGetDescription (gnc_import_TransInfo_get_trans (info) );
-    gtk_list_store_set (store, iter, DOWNLOADED_COL_DESCRIPTION, ro_text, -1);
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_DESCRIPTION, ro_text, -1);
 
     /*Memo*/
     ro_text = xaccSplitGetMemo (split);
-    gtk_list_store_set (store, iter, DOWNLOADED_COL_MEMO, ro_text, -1);
+    gtk_tree_store_set (store, iter, DOWNLOADED_COL_MEMO, ro_text, -1);
 
     /*Actions*/
 
@@ -1186,50 +1276,65 @@ refresh_model_row (GNCImportMainMatcher *gui,
                     g_strdup_printf (_("New, UNBALANCED (need acct to transfer %s)!"),
                                      imbalance);
             }
+            remove_child_row (model, iter);
+
             g_free (imbalance);
         }
         break;
     case GNCImport_CLEAR:
-        if (gnc_import_TransInfo_get_selected_match (info))
         {
-            color = get_required_color (int_not_required_class);
-            if (gnc_import_TransInfo_get_match_selected_manually (info) == TRUE)
+            GNCImportMatchInfo *sel_match = gnc_import_TransInfo_get_selected_match (info);
+
+            if (sel_match)
             {
-                ro_text = _("Reconcile (manual) match");
+                color = get_required_color (int_not_required_class);
+                if (gnc_import_TransInfo_get_match_selected_manually (info))
+                {
+                    ro_text = _("Reconcile (manual) match");
+                }
+                else
+                {
+                    ro_text = _("Reconcile (auto) match");
+                }
+                update_child_row (sel_match, model, iter);
             }
             else
             {
-                ro_text = _("Reconcile (auto) match");
+                color = get_required_color (int_required_class);
+                ro_text = _("Match missing!");
+                remove_child_row (model, iter);
             }
         }
-        else
-        {
-            color = get_required_color (int_required_class);
-            ro_text = _("Match missing!");
-        }
         break;
     case GNCImport_UPDATE:
-        if (gnc_import_TransInfo_get_selected_match (info))
         {
-            color = get_required_color (int_not_required_class);
-            if (gnc_import_TransInfo_get_match_selected_manually (info) == TRUE)
+            GNCImportMatchInfo *sel_match = gnc_import_TransInfo_get_selected_match (info);
+
+            if (sel_match)
             {
-                ro_text = _("Update and reconcile (manual) match");
+                color = get_required_color (int_not_required_class);
+                if (gnc_import_TransInfo_get_match_selected_manually (info))
+                {
+                    ro_text = _("Update and reconcile (manual) match");
+                }
+                else
+                {
+                    ro_text = _("Update and reconcile (auto) match");
+                }
+                update_child_row (sel_match, model, iter);
             }
             else
             {
-                ro_text = _("Update and reconcile (auto) match");
+                color = get_required_color (int_required_class);
+                ro_text = _("Match missing!");
+                remove_child_row (model, iter);
             }
         }
-        else
-        {
-            color = get_required_color (int_required_class);
-            ro_text = _("Match missing!");
-        }
         break;
     case GNCImport_SKIP:
         color = get_required_color (int_required_class);
         ro_text = _("Do not import (no action selected)");
+        remove_child_row (model, iter);
         break;
     default:
         color = "white";
@@ -1237,7 +1342,7 @@ refresh_model_row (GNCImportMainMatcher *gui,
         break;
     }
 
-    gtk_list_store_set (store, iter,
+    gtk_tree_store_set (store, iter,
                         DOWNLOADED_COL_COLOR, color,
                         DOWNLOADED_COL_ACTION_INFO, ro_text ? ro_text : text,
                         -1);
@@ -1249,14 +1354,14 @@ refresh_model_row (GNCImportMainMatcher *gui,
     g_free (int_not_required_class);
 
     /* Set the pixmaps */
-    gtk_list_store_set (store, iter,
+    gtk_tree_store_set (store, iter,
                         DOWNLOADED_COL_ACTION_ADD,
                         gnc_import_TransInfo_get_action (info) == GNCImport_ADD,
                         -1);
     if (gnc_import_TransInfo_get_action (info) == GNCImport_SKIP)
     {
         /*Show the best match's confidence pixmap in the info column*/
-        gtk_list_store_set (store, iter,
+        gtk_tree_store_set (store, iter,
                             DOWNLOADED_COL_ACTION_PIXBUF,
                             gen_probability_pixbuf (gnc_import_MatchInfo_get_probability
                                     (gnc_import_TransInfo_get_selected_match (info)),
@@ -1265,14 +1370,14 @@ refresh_model_row (GNCImportMainMatcher *gui,
                             -1);
     }
 
-    gtk_list_store_set (store, iter,
+    gtk_tree_store_set (store, iter,
                         DOWNLOADED_COL_ACTION_CLEAR,
                         gnc_import_TransInfo_get_action (info) == GNCImport_CLEAR,
                         -1);
     if (gnc_import_TransInfo_get_action (info) == GNCImport_CLEAR)
     {
         /*Show the best match's confidence pixmap in the info column*/
-        gtk_list_store_set (store, iter,
+        gtk_tree_store_set (store, iter,
                             DOWNLOADED_COL_ACTION_PIXBUF,
                             gen_probability_pixbuf (gnc_import_MatchInfo_get_probability
                                     (gnc_import_TransInfo_get_selected_match (info)),
@@ -1281,14 +1386,14 @@ refresh_model_row (GNCImportMainMatcher *gui,
                             -1);
     }
 
-    gtk_list_store_set (store, iter,
+    gtk_tree_store_set (store, iter,
                         DOWNLOADED_COL_ACTION_UPDATE,
                         gnc_import_TransInfo_get_action (info) == GNCImport_UPDATE,
                         -1);
     if (gnc_import_TransInfo_get_action (info) == GNCImport_UPDATE)
     {
         /*Show the best match's confidence pixmap in the info column*/
-        gtk_list_store_set (store, iter,
+        gtk_tree_store_set (store, iter,
                             DOWNLOADED_COL_ACTION_PIXBUF,
                             gen_probability_pixbuf (gnc_import_MatchInfo_get_probability
                                     (gnc_import_TransInfo_get_selected_match (info)),
@@ -1297,6 +1402,19 @@ refresh_model_row (GNCImportMainMatcher *gui,
                             -1);
     }
 
+    // show child row if 'show matched info' is toggled
+    if (gtk_tree_model_iter_has_child (model, iter))
+    {
+        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(gui->show_matched_info)))
+        {
+            GtkTreePath *path = gtk_tree_model_get_path (model, iter);
+
+            gtk_tree_view_column_set_visible (gui->account_column, TRUE);
+
+            gtk_tree_view_expand_row (GTK_TREE_VIEW(gui->view), path, TRUE);
+            gtk_tree_path_free (path);
+        }
+    }
     selection = gtk_tree_view_get_selection (gui->view);
     gtk_tree_selection_unselect_all (selection);
 }
@@ -1339,7 +1457,7 @@ void gnc_gen_trans_list_add_trans_with_ref_id (GNCImportMainMatcher *gui, Transa
                                                  match_selected_manually);
 
         model = gtk_tree_view_get_model (gui->view);
-        gtk_list_store_append (GTK_LIST_STORE(model), &iter);
+        gtk_tree_store_append (GTK_TREE_STORE(model), &iter, NULL);
         refresh_model_row (gui, model, &iter, transaction_info);
     }
     return;



Summary of changes:
 common/debug/valgrind/valgrind-compiz.supp     | 919 +++++++++++++++++++++++++
 gnucash/gtkbuilder/dialog-import.glade         |  50 +-
 gnucash/import-export/import-account-matcher.c |  74 +-
 gnucash/import-export/import-account-matcher.h |   4 +-
 gnucash/import-export/import-main-matcher.c    | 291 +++++---
 5 files changed, 1227 insertions(+), 111 deletions(-)
 create mode 100644 common/debug/valgrind/valgrind-compiz.supp



More information about the gnucash-changes mailing list