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.
This commit is contained in:
Robert Fewell 2019-08-23 14:09:27 +01:00
parent 6c3b24a9b6
commit 161bb5f65d
3 changed files with 1122 additions and 57 deletions

View File

@ -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@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
}

View File

@ -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>

View File

@ -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;