mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'import-map-editor'
This commit is contained in:
commit
a3e59e557a
@ -208,6 +208,7 @@ src/gnome/dialog-commodities.c
|
||||
src/gnome/dialog-fincalc.c
|
||||
src/gnome/dialog-find-transactions2.c
|
||||
src/gnome/dialog-find-transactions.c
|
||||
src/gnome/dialog-imap-editor.c
|
||||
src/gnome/dialog-lot-viewer.c
|
||||
src/gnome/dialog-new-user.c
|
||||
src/gnome/dialog-price-edit-db.c
|
||||
@ -248,6 +249,7 @@ src/gnome/gtkbuilder/assistant-loan.glade
|
||||
src/gnome/gtkbuilder/assistant-stock-split.glade
|
||||
src/gnome/gtkbuilder/dialog-commodities.glade
|
||||
src/gnome/gtkbuilder/dialog-fincalc.glade
|
||||
src/gnome/gtkbuilder/dialog-imap-editor.glade
|
||||
src/gnome/gtkbuilder/dialog-lot-viewer.glade
|
||||
src/gnome/gtkbuilder/dialog-new-user.glade
|
||||
src/gnome/gtkbuilder/dialog-price.glade
|
||||
|
@ -5485,6 +5485,216 @@ gnc_account_imap_add_account_bayes (GncImportMatchMap *imap,
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
static void
|
||||
build_bayes_layer_two (const char *key, const GValue *value, gpointer user_data)
|
||||
{
|
||||
QofBook *book;
|
||||
Account *root;
|
||||
gchar *kvp_path;
|
||||
gchar *count;
|
||||
|
||||
struct imap_info *imapInfo_node;
|
||||
|
||||
struct imap_info *imapInfo = (struct imap_info*)user_data;
|
||||
|
||||
// Get the book
|
||||
book = qof_instance_get_book (imapInfo->source_account);
|
||||
root = gnc_book_get_root_account (book);
|
||||
|
||||
PINFO("build_bayes_layer_two: account '%s', token_count: '%" G_GINT64_FORMAT "'",
|
||||
(char*)key, g_value_get_int64(value));
|
||||
|
||||
count = g_strdup_printf ("%" G_GINT64_FORMAT, g_value_get_int64 (value));
|
||||
|
||||
kvp_path = g_strconcat (imapInfo->category_head, "/", key, NULL);
|
||||
|
||||
PINFO("build_bayes_layer_two: kvp_path is '%s'", kvp_path);
|
||||
|
||||
imapInfo_node = g_malloc(sizeof(*imapInfo_node));
|
||||
|
||||
imapInfo_node->source_account = imapInfo->source_account;
|
||||
imapInfo_node->map_account = gnc_account_lookup_by_full_name (root, key);
|
||||
imapInfo_node->full_category = g_strdup (kvp_path);
|
||||
imapInfo_node->match_string = g_strdup (imapInfo->match_string);
|
||||
imapInfo_node->category_head = g_strdup (imapInfo->category_head);
|
||||
imapInfo_node->count = g_strdup (count);
|
||||
|
||||
imapInfo->list = g_list_append (imapInfo->list, imapInfo_node);
|
||||
|
||||
g_free (kvp_path);
|
||||
g_free (count);
|
||||
}
|
||||
|
||||
static void
|
||||
build_bayes (const char *key, const GValue *value, gpointer user_data)
|
||||
{
|
||||
gchar *kvp_path;
|
||||
struct imap_info *imapInfo = (struct imap_info*)user_data;
|
||||
struct imap_info imapInfol2;
|
||||
|
||||
PINFO("build_bayes: match string '%s'", (char*)key);
|
||||
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value) == NULL)
|
||||
{
|
||||
kvp_path = g_strdup_printf (IMAP_FRAME_BAYES "/%s", key);
|
||||
|
||||
if (qof_instance_has_slot (QOF_INSTANCE(imapInfo->source_account), kvp_path))
|
||||
{
|
||||
PINFO("build_bayes: kvp_path is '%s', key '%s'", kvp_path, key);
|
||||
|
||||
imapInfol2.source_account = imapInfo->source_account;
|
||||
imapInfol2.match_string = g_strdup (key);
|
||||
imapInfol2.category_head = g_strdup (kvp_path);
|
||||
imapInfol2.list = imapInfo->list;
|
||||
|
||||
qof_instance_foreach_slot (QOF_INSTANCE(imapInfo->source_account), kvp_path,
|
||||
build_bayes_layer_two, &imapInfol2);
|
||||
|
||||
imapInfo->list = imapInfol2.list;
|
||||
g_free (imapInfol2.match_string);
|
||||
g_free (imapInfol2.category_head);
|
||||
}
|
||||
g_free (kvp_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
build_non_bayes (const char *key, const GValue *value, gpointer user_data)
|
||||
{
|
||||
if (G_VALUE_HOLDS_BOXED (value))
|
||||
{
|
||||
QofBook *book;
|
||||
GncGUID *guid = NULL;
|
||||
gchar *kvp_path;
|
||||
gchar *guid_string = NULL;
|
||||
|
||||
struct imap_info *imapInfo_node;
|
||||
|
||||
struct imap_info *imapInfo = (struct imap_info*)user_data;
|
||||
|
||||
// Get the book
|
||||
book = qof_instance_get_book (imapInfo->source_account);
|
||||
|
||||
guid = (GncGUID*)g_value_get_boxed (value);
|
||||
guid_string = guid_to_string (guid);
|
||||
|
||||
PINFO("build_non_bayes: account '%s', match account guid: '%s'",
|
||||
(char*)key, guid_string);
|
||||
|
||||
kvp_path = g_strconcat (imapInfo->category_head, "/", key, NULL);
|
||||
|
||||
PINFO("build_non_bayes: kvp_path is '%s'", kvp_path);
|
||||
|
||||
imapInfo_node = g_malloc(sizeof(*imapInfo_node));
|
||||
|
||||
imapInfo_node->source_account = imapInfo->source_account;
|
||||
imapInfo_node->map_account = xaccAccountLookup (guid, book);
|
||||
imapInfo_node->full_category = g_strdup (kvp_path);
|
||||
imapInfo_node->match_string = g_strdup (key);
|
||||
imapInfo_node->category_head = g_strdup (imapInfo->category_head);
|
||||
imapInfo_node->count = g_strdup (" ");
|
||||
|
||||
imapInfo->list = g_list_append (imapInfo->list, imapInfo_node);
|
||||
|
||||
g_free (kvp_path);
|
||||
g_free (guid_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GList *
|
||||
gnc_account_imap_get_info_bayes (Account *acc)
|
||||
{
|
||||
GList *list = NULL;
|
||||
|
||||
struct imap_info imapInfo;
|
||||
|
||||
imapInfo.source_account = acc;
|
||||
imapInfo.list = list;
|
||||
|
||||
if (qof_instance_has_slot (QOF_INSTANCE(acc), IMAP_FRAME_BAYES))
|
||||
qof_instance_foreach_slot (QOF_INSTANCE(acc), IMAP_FRAME_BAYES,
|
||||
build_bayes, &imapInfo);
|
||||
|
||||
return imapInfo.list;
|
||||
}
|
||||
|
||||
|
||||
GList *
|
||||
gnc_account_imap_get_info (Account *acc, const char *category)
|
||||
{
|
||||
GList *list = NULL;
|
||||
gchar *category_head = NULL;
|
||||
|
||||
struct imap_info imapInfo;
|
||||
|
||||
imapInfo.source_account = acc;
|
||||
imapInfo.list = list;
|
||||
|
||||
category_head = g_strdup_printf (IMAP_FRAME "/%s", category);
|
||||
imapInfo.category_head = category_head;
|
||||
|
||||
if (qof_instance_has_slot (QOF_INSTANCE(acc), category_head))
|
||||
qof_instance_foreach_slot (QOF_INSTANCE(acc), category_head,
|
||||
build_non_bayes, &imapInfo);
|
||||
|
||||
g_free (category_head);
|
||||
|
||||
return imapInfo.list;
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
gchar *
|
||||
gnc_account_get_map_entry (Account *acc, const char *full_category)
|
||||
{
|
||||
GValue v = G_VALUE_INIT;
|
||||
gchar *text = NULL;
|
||||
gchar *kvp_path = g_strdup (full_category);
|
||||
|
||||
if (qof_instance_has_slot (QOF_INSTANCE(acc), kvp_path))
|
||||
{
|
||||
qof_instance_get_kvp (QOF_INSTANCE(acc), kvp_path, &v);
|
||||
|
||||
if (G_VALUE_HOLDS_STRING (&v))
|
||||
{
|
||||
gchar const *string;
|
||||
string = g_value_get_string (&v);
|
||||
text = g_strdup (string);
|
||||
}
|
||||
}
|
||||
g_free (kvp_path);
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gnc_account_delete_map_entry (Account *acc, char *full_category, gboolean empty)
|
||||
{
|
||||
gchar *kvp_path = g_strdup (full_category);
|
||||
|
||||
if ((acc != NULL) && qof_instance_has_slot (QOF_INSTANCE(acc), kvp_path))
|
||||
{
|
||||
xaccAccountBeginEdit (acc);
|
||||
|
||||
if (empty)
|
||||
qof_instance_slot_delete_if_empty (QOF_INSTANCE(acc), kvp_path);
|
||||
else
|
||||
qof_instance_slot_delete (QOF_INSTANCE(acc), kvp_path);
|
||||
|
||||
PINFO("Account is '%s', path is '%s'", xaccAccountGetName (acc), kvp_path);
|
||||
|
||||
qof_instance_set_dirty (QOF_INSTANCE(acc));
|
||||
xaccAccountCommitEdit (acc);
|
||||
}
|
||||
g_free (kvp_path);
|
||||
g_free (full_category);
|
||||
}
|
||||
|
||||
|
||||
/* ================================================================ */
|
||||
/* QofObject function implementation and registration */
|
||||
|
||||
|
@ -1406,6 +1406,37 @@ Account* gnc_account_imap_find_account_bayes (GncImportMatchMap *imap, GList* to
|
||||
void gnc_account_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
|
||||
Account *acc);
|
||||
|
||||
struct imap_info
|
||||
{
|
||||
Account *source_account;
|
||||
Account *map_account;
|
||||
GList *list;
|
||||
char *category_head;
|
||||
char *full_category;
|
||||
char *match_string;
|
||||
char *count;
|
||||
};
|
||||
|
||||
/** Returns a GList of structure imap_info of all Bayesian mappings for
|
||||
* required Account
|
||||
*/
|
||||
GList *gnc_account_imap_get_info_bayes (Account *acc);
|
||||
|
||||
/** Returns a GList of structure imap_info of all Non Bayesian mappings for
|
||||
* required Account
|
||||
*/
|
||||
GList *gnc_account_imap_get_info (Account *acc, const char *category);
|
||||
|
||||
/** Returns the text string pointed to by full_category for the Account, free
|
||||
* the returned text
|
||||
*/
|
||||
gchar *gnc_account_get_map_entry (Account *acc, const char *full_category);
|
||||
|
||||
/** Delete the entry for Account pointed to by full_category, if empty is TRUE then use
|
||||
* delete if empty, full_category is freed
|
||||
*/
|
||||
void gnc_account_delete_map_entry (Account *acc, char *full_category, gboolean empty);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
@ -32,6 +32,7 @@ libgnc_gnome_la_SOURCES = \
|
||||
dialog-fincalc.c \
|
||||
dialog-find-transactions.c \
|
||||
dialog-find-transactions2.c \
|
||||
dialog-imap-editor.c \
|
||||
dialog-lot-viewer.c \
|
||||
dialog-new-user.c \
|
||||
dialog-price-editor.c \
|
||||
@ -84,6 +85,7 @@ noinst_HEADERS = \
|
||||
dialog-fincalc.h \
|
||||
dialog-find-transactions.h \
|
||||
dialog-find-transactions2.h \
|
||||
dialog-imap-editor.h \
|
||||
dialog-lot-viewer.h \
|
||||
dialog-new-user.h \
|
||||
dialog-print-check.h \
|
||||
|
777
src/gnome/dialog-imap-editor.c
Normal file
777
src/gnome/dialog-imap-editor.c
Normal file
@ -0,0 +1,777 @@
|
||||
/********************************************************************\
|
||||
* dialog-imap-editor.c -- Import Map Editor dialog *
|
||||
* Copyright (C) 2015 Robert Fewell *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "dialog-imap-editor.h"
|
||||
|
||||
#include "dialog-utils.h"
|
||||
#include "gnc-component-manager.h"
|
||||
#include "gnc-session.h"
|
||||
|
||||
#include "gnc-ui-util.h"
|
||||
#include "Account.h"
|
||||
|
||||
#define DIALOG_IMAP_CM_CLASS "dialog-imap-edit"
|
||||
#define GNC_PREFS_GROUP "dialogs.imap-editor"
|
||||
|
||||
#define IMAP_FRAME_BAYES "import-map-bayes"
|
||||
#define IMAP_FRAME "import-map"
|
||||
|
||||
#define IMAP_FRAME_DESC "desc"
|
||||
#define IMAP_FRAME_MEMO "memo"
|
||||
#define IMAP_FRAME_CSV "csv-account-map"
|
||||
|
||||
/** Enumeration for the tree-store */
|
||||
enum GncImapColumn {SOURCE_FULL_ACC, SOURCE_ACCOUNT, BASED_ON, MATCH_STRING,
|
||||
MAP_FULL_ACC, MAP_ACCOUNT, FULL_CATEGORY, COUNT, FILTER};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BAYES,
|
||||
NBAYES,
|
||||
ONLINE
|
||||
}GncListType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
QofSession *session;
|
||||
GtkWidget *view;
|
||||
GncListType type;
|
||||
|
||||
GtkWidget *radio_bayes;
|
||||
GtkWidget *radio_nbayes;
|
||||
GtkWidget *radio_online;
|
||||
|
||||
GtkWidget *filter_button;
|
||||
GtkWidget *filter_text_entry;
|
||||
GtkWidget *filter_label;
|
||||
|
||||
GtkWidget *expand_button;
|
||||
GtkWidget *collapse_button;
|
||||
}ImapDialog;
|
||||
|
||||
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = GNC_MOD_GUI;
|
||||
|
||||
void gnc_imap_dialog_window_destroy_cb (GtkWidget *object, gpointer user_data);
|
||||
void gnc_imap_dialog_close_cb (GtkDialog *dialog, gpointer user_data);
|
||||
void gnc_imap_dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer user_data);
|
||||
|
||||
static void get_account_info (ImapDialog *imap_dialog);
|
||||
|
||||
void
|
||||
gnc_imap_dialog_window_destroy_cb (GtkWidget *object, gpointer user_data)
|
||||
{
|
||||
ImapDialog *imap_dialog = user_data;
|
||||
|
||||
ENTER(" ");
|
||||
gnc_unregister_gui_component_by_data (DIALOG_IMAP_CM_CLASS, imap_dialog);
|
||||
|
||||
if (imap_dialog->dialog)
|
||||
{
|
||||
gtk_widget_destroy (imap_dialog->dialog);
|
||||
imap_dialog->dialog = NULL;
|
||||
}
|
||||
g_free (imap_dialog);
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
void
|
||||
gnc_imap_dialog_close_cb (GtkDialog *dialog, gpointer user_data)
|
||||
{
|
||||
ImapDialog *imap_dialog = user_data;
|
||||
|
||||
ENTER(" ");
|
||||
gnc_close_gui_component_by_data (DIALOG_IMAP_CM_CLASS, imap_dialog);
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
are_you_sure (ImapDialog *imap_dialog)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
gint response;
|
||||
const char *title = _("Are you sure you want to delete the entries ?");
|
||||
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (imap_dialog->dialog),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_CANCEL,
|
||||
"%s", title);
|
||||
|
||||
gtk_dialog_add_button (GTK_DIALOG(dialog), _("_Delete"), GTK_RESPONSE_ACCEPT);
|
||||
|
||||
gtk_widget_grab_focus (gtk_dialog_get_widget_for_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT));
|
||||
|
||||
response = gtk_dialog_run (GTK_DIALOG(dialog));
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
delete_info_bayes (Account *source_account, gchar *match_string, gint depth)
|
||||
{
|
||||
gchar *full_category;
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME_BAYES "/%s", match_string);
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME_BAYES);
|
||||
if (depth == 1) // top level, delete all below
|
||||
gnc_account_delete_map_entry (source_account, full_category, FALSE);
|
||||
else
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_info_nbayes (Account *source_account, gint depth)
|
||||
{
|
||||
gchar *full_category;
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME "/%s", IMAP_FRAME_DESC);
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME "/%s", IMAP_FRAME_MEMO);
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME "/%s", IMAP_FRAME_CSV);
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME);
|
||||
if (depth == 1) // top level, delete all below
|
||||
gnc_account_delete_map_entry (source_account, full_category, FALSE);
|
||||
else
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_selected_row (GtkTreeModel *model, GtkTreeIter *iter, ImapDialog *imap_dialog)
|
||||
{
|
||||
Account *source_account = NULL;
|
||||
gchar *full_source_account;
|
||||
gchar *full_category;
|
||||
gchar *match_string;
|
||||
|
||||
gtk_tree_model_get (model, iter, SOURCE_ACCOUNT, &source_account, SOURCE_FULL_ACC, &full_source_account,
|
||||
FULL_CATEGORY, &full_category, MATCH_STRING, &match_string, -1);
|
||||
|
||||
PINFO("Account is '%s', Full Category is '%s', Match String is '%s'", full_source_account, full_category, match_string);
|
||||
|
||||
if (source_account != NULL)
|
||||
{
|
||||
GtkTreePath *tree_path;
|
||||
gint depth;
|
||||
|
||||
// Get the level we are at in the tree-model
|
||||
tree_path = gtk_tree_model_get_path (model, iter);
|
||||
depth = gtk_tree_path_get_depth (tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
gnc_account_delete_map_entry (source_account, full_category, FALSE);
|
||||
|
||||
if (imap_dialog->type == BAYES)
|
||||
delete_info_bayes (source_account, match_string, depth);
|
||||
|
||||
if (imap_dialog->type == NBAYES)
|
||||
delete_info_nbayes (source_account, depth);
|
||||
}
|
||||
else
|
||||
g_free (full_category);
|
||||
|
||||
g_free (match_string);
|
||||
g_free (full_source_account);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_imap_dialog_delete (ImapDialog *imap_dialog)
|
||||
{
|
||||
GList *list, *row;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW(imap_dialog->view));
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(imap_dialog->view));
|
||||
|
||||
list = gtk_tree_selection_get_selected_rows (selection, &model);
|
||||
|
||||
// Make sure we have some rows selected
|
||||
if (g_list_length (list) == 0)
|
||||
return;
|
||||
|
||||
// Are we sure we want to delete the entries
|
||||
if (are_you_sure (imap_dialog) == FALSE)
|
||||
return;
|
||||
|
||||
// reverse list
|
||||
list = g_list_reverse (list);
|
||||
|
||||
// Walk the list
|
||||
for (row = g_list_first (list); row; row = g_list_next (row))
|
||||
{
|
||||
if (gtk_tree_model_get_iter (model, &iter, row->data))
|
||||
delete_selected_row (model, &iter, imap_dialog);
|
||||
}
|
||||
g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
|
||||
g_list_free (list);
|
||||
|
||||
get_account_info (imap_dialog);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_imap_dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer user_data)
|
||||
{
|
||||
ImapDialog *imap_dialog = user_data;
|
||||
|
||||
switch (response_id)
|
||||
{
|
||||
case GTK_RESPONSE_APPLY:
|
||||
gnc_imap_dialog_delete (imap_dialog);
|
||||
return;
|
||||
|
||||
case GTK_RESPONSE_CLOSE:
|
||||
default:
|
||||
gnc_close_gui_component_by_data (DIALOG_IMAP_CM_CLASS, imap_dialog);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
filter_test_and_move_next (GtkTreeModel *model, GtkTreeIter *iter, ImapDialog *imap_dialog)
|
||||
{
|
||||
GtkTreePath *tree_path;
|
||||
gint depth;
|
||||
gboolean valid;
|
||||
const gchar *filter_text;
|
||||
const gchar *match_string;
|
||||
const gchar *map_full_acc;
|
||||
|
||||
// Read the row
|
||||
gtk_tree_model_get (model, iter, MATCH_STRING, &match_string, MAP_FULL_ACC, &map_full_acc, -1);
|
||||
|
||||
filter_text = gtk_entry_get_text (GTK_ENTRY(imap_dialog->filter_text_entry));
|
||||
|
||||
// Get the level we are at in the tree-model
|
||||
tree_path = gtk_tree_model_get_path (model, iter);
|
||||
depth = gtk_tree_path_get_depth (tree_path);
|
||||
|
||||
// Reset filter to TRUE
|
||||
gtk_tree_store_set (GTK_TREE_STORE(model), iter, FILTER, TRUE, -1);
|
||||
|
||||
// Check for a filter_text entry
|
||||
if (g_strcmp0 (filter_text, "") != 0)
|
||||
{
|
||||
if (match_string != NULL) // Check for match_string is not NULL, valid line
|
||||
{
|
||||
if ((g_strrstr (match_string, filter_text) == NULL) &&
|
||||
(g_strrstr (map_full_acc, filter_text) == NULL ))
|
||||
gtk_tree_store_set (GTK_TREE_STORE(model), iter, FILTER, FALSE, -1);
|
||||
else
|
||||
gtk_tree_view_expand_to_path (GTK_TREE_VIEW(imap_dialog->view), tree_path);
|
||||
}
|
||||
}
|
||||
// Select next entry based on path
|
||||
if (depth == 1)
|
||||
gtk_tree_path_down (tree_path);
|
||||
else
|
||||
{
|
||||
gtk_tree_path_next (tree_path);
|
||||
if (!gtk_tree_model_get_iter (model, iter, tree_path))
|
||||
{
|
||||
gtk_tree_path_prev (tree_path);
|
||||
gtk_tree_path_up (tree_path);
|
||||
gtk_tree_path_next (tree_path);
|
||||
}
|
||||
}
|
||||
valid = gtk_tree_model_get_iter (model, iter, tree_path);
|
||||
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
static void
|
||||
filter_button_cb (GtkButton *button, ImapDialog *imap_dialog)
|
||||
{
|
||||
GtkTreeModel *model, *filter;
|
||||
GtkTreeIter iter;
|
||||
gboolean valid;
|
||||
|
||||
filter = gtk_tree_view_get_model (GTK_TREE_VIEW(imap_dialog->view));
|
||||
model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER(filter));
|
||||
|
||||
// Collapse all nodes
|
||||
gtk_tree_view_collapse_all (GTK_TREE_VIEW(imap_dialog->view));
|
||||
|
||||
valid = gtk_tree_model_get_iter_first (model, &iter);
|
||||
|
||||
while (valid)
|
||||
{
|
||||
valid = filter_test_and_move_next (model, &iter, imap_dialog);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
expand_button_cb (GtkButton *button, ImapDialog *imap_dialog)
|
||||
{
|
||||
// Clear the filter
|
||||
gtk_entry_set_text (GTK_ENTRY(imap_dialog->filter_text_entry), "");
|
||||
|
||||
filter_button_cb (button, imap_dialog);
|
||||
|
||||
gtk_tree_view_expand_all (GTK_TREE_VIEW(imap_dialog->view));
|
||||
}
|
||||
|
||||
static void
|
||||
collapse_button_cb (GtkButton *button, ImapDialog *imap_dialog)
|
||||
{
|
||||
// Clear the filter
|
||||
gtk_entry_set_text (GTK_ENTRY(imap_dialog->filter_text_entry), "");
|
||||
|
||||
filter_button_cb (button, imap_dialog);
|
||||
|
||||
gtk_tree_view_collapse_all (GTK_TREE_VIEW(imap_dialog->view));
|
||||
}
|
||||
|
||||
static void
|
||||
list_type_selected_cb (GtkToggleButton* button, ImapDialog *imap_dialog)
|
||||
{
|
||||
GncListType type;
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(imap_dialog->radio_bayes)))
|
||||
type = BAYES;
|
||||
else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(imap_dialog->radio_nbayes)))
|
||||
type = NBAYES;
|
||||
else
|
||||
type = ONLINE;
|
||||
|
||||
// Lets do this only on change of list type
|
||||
if (type != imap_dialog->type)
|
||||
{
|
||||
imap_dialog->type = type;
|
||||
get_account_info (imap_dialog);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_count_column (ImapDialog *imap_dialog, gboolean show)
|
||||
{
|
||||
GtkTreeViewColumn *tree_column;
|
||||
|
||||
// Show Count Column
|
||||
tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW(imap_dialog->view), 4);
|
||||
gtk_tree_view_column_set_visible (tree_column, show);
|
||||
|
||||
// Hide Based on Column
|
||||
tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW(imap_dialog->view), 1);
|
||||
gtk_tree_view_column_set_visible (tree_column, !show);
|
||||
|
||||
gtk_tree_view_columns_autosize (GTK_TREE_VIEW(imap_dialog->view));
|
||||
}
|
||||
|
||||
static void
|
||||
add_to_store (GtkTreeModel *model, GtkTreeIter *iter, const gchar *text, gpointer user_data)
|
||||
{
|
||||
gchar *fullname = NULL;
|
||||
gchar *map_fullname = NULL;
|
||||
|
||||
struct imap_info *imapInfo = (struct imap_info*)user_data;
|
||||
|
||||
fullname = gnc_account_get_full_name (imapInfo->source_account);
|
||||
|
||||
// Do we have a valid map account
|
||||
if (imapInfo->map_account == NULL)
|
||||
map_fullname = g_strdup (_("Map Account NOT found"));
|
||||
else
|
||||
map_fullname = gnc_account_get_full_name (imapInfo->map_account);
|
||||
|
||||
PINFO("Add to Store: Source Acc '%s', Match '%s', Map Acc '%s'", fullname, imapInfo->match_string, map_fullname);
|
||||
|
||||
gtk_tree_store_set (GTK_TREE_STORE(model), iter,
|
||||
SOURCE_FULL_ACC, fullname, SOURCE_ACCOUNT, imapInfo->source_account,
|
||||
BASED_ON, text,
|
||||
MATCH_STRING, imapInfo->match_string,
|
||||
MAP_FULL_ACC, map_fullname, MAP_ACCOUNT, imapInfo->map_account,
|
||||
FULL_CATEGORY, imapInfo->full_category, COUNT, imapInfo->count,
|
||||
FILTER, TRUE, -1);
|
||||
|
||||
g_free (fullname);
|
||||
g_free (map_fullname);
|
||||
}
|
||||
|
||||
static void
|
||||
get_imap_info (Account *acc, const gchar *category, GtkTreeModel *model, const gchar *text)
|
||||
{
|
||||
GtkTreeIter toplevel, child;
|
||||
GList *imap_list, *node;
|
||||
gchar *acc_name = NULL;
|
||||
|
||||
acc_name = gnc_account_get_full_name (acc);
|
||||
PINFO("Source Acc '%s', Based on '%s', Path Head '%s'", acc_name, text, category);
|
||||
|
||||
if (category == NULL) // For Bayesian, category is NULL
|
||||
imap_list = gnc_account_imap_get_info_bayes (acc);
|
||||
else
|
||||
imap_list = gnc_account_imap_get_info (acc, category);
|
||||
|
||||
if (g_list_length (imap_list) > 0)
|
||||
{
|
||||
PINFO("List length is %d", g_list_length (imap_list));
|
||||
|
||||
// Add top level entry of Source full Account and Based on.
|
||||
gtk_tree_store_append (GTK_TREE_STORE(model), &toplevel, NULL);
|
||||
gtk_tree_store_set (GTK_TREE_STORE(model), &toplevel,
|
||||
SOURCE_ACCOUNT, acc, SOURCE_FULL_ACC, acc_name, BASED_ON, text, FILTER, TRUE, -1);
|
||||
|
||||
for (node = imap_list; node; node = g_list_next (node))
|
||||
{
|
||||
struct imap_info *imapInfo = node->data;
|
||||
|
||||
// First add a child entry and pass iter to add_to_store
|
||||
gtk_tree_store_append (GTK_TREE_STORE(model), &child, &toplevel);
|
||||
add_to_store (model, &child, text, imapInfo);
|
||||
|
||||
// Free the members and structure
|
||||
g_free (imapInfo->category_head);
|
||||
g_free (imapInfo->full_category);
|
||||
g_free (imapInfo->match_string);
|
||||
g_free (imapInfo->count);
|
||||
g_free (imapInfo);
|
||||
}
|
||||
}
|
||||
g_free (acc_name);
|
||||
g_list_free (imap_list); // Free the List
|
||||
}
|
||||
|
||||
static void
|
||||
show_first_row (ImapDialog *imap_dialog)
|
||||
{
|
||||
GtkTreeModel *model, *filter;
|
||||
GtkTreeIter iter;
|
||||
|
||||
filter = gtk_tree_view_get_model (GTK_TREE_VIEW(imap_dialog->view));
|
||||
model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER(filter));
|
||||
|
||||
// See if there are any entries
|
||||
if (gtk_tree_model_get_iter_first (model, &iter))
|
||||
{
|
||||
GtkTreePath *path;
|
||||
path = gtk_tree_path_new_first (); // Set Path to first entry
|
||||
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(imap_dialog->view), path, NULL, TRUE, 0.0, 0.0);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_account_info_bayes (GList *accts, GtkTreeModel *model)
|
||||
{
|
||||
GList *ptr;
|
||||
|
||||
/* Go through list of accounts */
|
||||
for (ptr = accts; ptr; ptr = g_list_next (ptr))
|
||||
{
|
||||
Account *acc = ptr->data;
|
||||
|
||||
get_imap_info (acc, NULL, model, _("Bayesian"));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_account_info_nbayes (GList *accts, GtkTreeModel *model)
|
||||
{
|
||||
GList *ptr;
|
||||
|
||||
/* Go through list of accounts */
|
||||
for (ptr = accts; ptr; ptr = g_list_next (ptr))
|
||||
{
|
||||
Account *acc = ptr->data;
|
||||
|
||||
// Description
|
||||
get_imap_info (acc, IMAP_FRAME_DESC, model, _("Description Field"));
|
||||
|
||||
// Memo
|
||||
get_imap_info (acc, IMAP_FRAME_MEMO, model, _("Memo Field"));
|
||||
|
||||
// CSV Account Map
|
||||
get_imap_info (acc, IMAP_FRAME_CSV, model, _("CSV Account Map"));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_account_info_online (GList *accts, GtkTreeModel *model)
|
||||
{
|
||||
GList *ptr;
|
||||
GtkTreeIter toplevel;
|
||||
|
||||
struct imap_info imapInfo;
|
||||
|
||||
/* Go through list of accounts */
|
||||
for (ptr = accts; ptr; ptr = g_list_next (ptr))
|
||||
{
|
||||
gchar *text = NULL;
|
||||
Account *acc = ptr->data;
|
||||
|
||||
// Save source account
|
||||
imapInfo.source_account = acc;
|
||||
|
||||
imapInfo.full_category = "online_id";
|
||||
|
||||
text = gnc_account_get_map_entry (acc, imapInfo.full_category);
|
||||
|
||||
if (text != NULL)
|
||||
{
|
||||
if (g_strcmp0 (text, "") == 0)
|
||||
imapInfo.map_account = NULL;
|
||||
else
|
||||
imapInfo.map_account = imapInfo.source_account;
|
||||
|
||||
imapInfo.match_string = text;
|
||||
imapInfo.count = " ";
|
||||
|
||||
// Add top level entry and pass iter to add_to_store
|
||||
gtk_tree_store_append (GTK_TREE_STORE(model), &toplevel, NULL);
|
||||
add_to_store (model, &toplevel, _("Online Id"), &imapInfo);
|
||||
}
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_filter_option (ImapDialog *imap_dialog, gboolean show)
|
||||
{
|
||||
if (show)
|
||||
{
|
||||
gtk_widget_show (imap_dialog->filter_text_entry);
|
||||
gtk_widget_show (imap_dialog->filter_button);
|
||||
gtk_widget_show (imap_dialog->filter_label);
|
||||
gtk_widget_show (imap_dialog->expand_button);
|
||||
gtk_widget_show (imap_dialog->collapse_button);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_hide (imap_dialog->filter_text_entry);
|
||||
gtk_widget_hide (imap_dialog->filter_button);
|
||||
gtk_widget_hide (imap_dialog->filter_label);
|
||||
gtk_widget_hide (imap_dialog->expand_button);
|
||||
gtk_widget_hide (imap_dialog->collapse_button);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_account_info (ImapDialog *imap_dialog)
|
||||
{
|
||||
Account *root;
|
||||
GList *accts;
|
||||
GtkTreeModel *model, *filter;
|
||||
GtkTreeIter iter;
|
||||
|
||||
/* Get list of Accounts */
|
||||
root = gnc_book_get_root_account (gnc_get_current_book());
|
||||
accts = gnc_account_get_descendants_sorted (root);
|
||||
|
||||
filter = gtk_tree_view_get_model (GTK_TREE_VIEW(imap_dialog->view));
|
||||
|
||||
model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER(filter));
|
||||
|
||||
// Clear the tree store
|
||||
gtk_tree_store_clear (GTK_TREE_STORE(model));
|
||||
|
||||
// Clear the filter
|
||||
gtk_entry_set_text (GTK_ENTRY(imap_dialog->filter_text_entry), "");
|
||||
|
||||
// Hide Count Column
|
||||
show_count_column (imap_dialog, FALSE);
|
||||
|
||||
// Show Filter Option
|
||||
show_filter_option (imap_dialog, TRUE);
|
||||
|
||||
if (imap_dialog->type == BAYES)
|
||||
{
|
||||
get_account_info_bayes (accts, model);
|
||||
|
||||
// Show Count Column
|
||||
show_count_column (imap_dialog, TRUE);
|
||||
}
|
||||
else if (imap_dialog->type == NBAYES)
|
||||
get_account_info_nbayes (accts, model);
|
||||
else if (imap_dialog->type == ONLINE)
|
||||
{
|
||||
// Hide Filter Option
|
||||
show_filter_option (imap_dialog, FALSE);
|
||||
get_account_info_online (accts, model);
|
||||
}
|
||||
// if there are any entries, show first row
|
||||
show_first_row (imap_dialog);
|
||||
|
||||
g_list_free (accts);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_imap_dialog_create (GtkWidget *parent, ImapDialog *imap_dialog)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkBuilder *builder;
|
||||
GtkTreeModel *filter;
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
ENTER(" ");
|
||||
builder = gtk_builder_new();
|
||||
gnc_builder_add_from_file (builder, "dialog-imap-editor.glade", "tree-store");
|
||||
gnc_builder_add_from_file (builder, "dialog-imap-editor.glade", "treemodelfilter");
|
||||
gnc_builder_add_from_file (builder, "dialog-imap-editor.glade", "Import Map Dialog");
|
||||
|
||||
dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Import Map Dialog"));
|
||||
imap_dialog->dialog = dialog;
|
||||
|
||||
imap_dialog->session = gnc_get_current_session();
|
||||
imap_dialog->type = BAYES;
|
||||
|
||||
/* parent */
|
||||
if (parent != NULL)
|
||||
gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(parent));
|
||||
|
||||
/* Connect the radio buttons...*/
|
||||
imap_dialog->radio_bayes = GTK_WIDGET(gtk_builder_get_object (builder, "radio-bayes"));
|
||||
imap_dialog->radio_nbayes = GTK_WIDGET(gtk_builder_get_object (builder, "radio-nbayes"));
|
||||
imap_dialog->radio_online = GTK_WIDGET(gtk_builder_get_object (builder, "radio-online"));
|
||||
g_signal_connect (imap_dialog->radio_bayes, "toggled",
|
||||
G_CALLBACK(list_type_selected_cb), (gpointer)imap_dialog);
|
||||
g_signal_connect (imap_dialog->radio_nbayes, "toggled",
|
||||
G_CALLBACK(list_type_selected_cb), (gpointer)imap_dialog);
|
||||
|
||||
imap_dialog->filter_text_entry = GTK_WIDGET(gtk_builder_get_object (builder, "filter-text-entry"));
|
||||
imap_dialog->filter_label = GTK_WIDGET(gtk_builder_get_object (builder, "filter-label"));
|
||||
imap_dialog->filter_button = GTK_WIDGET(gtk_builder_get_object (builder, "filter-button"));
|
||||
g_signal_connect (imap_dialog->filter_button, "clicked",
|
||||
G_CALLBACK(filter_button_cb), (gpointer)imap_dialog);
|
||||
|
||||
imap_dialog->expand_button = GTK_WIDGET(gtk_builder_get_object (builder, "expand-button"));
|
||||
g_signal_connect (imap_dialog->expand_button, "clicked",
|
||||
G_CALLBACK(expand_button_cb), (gpointer)imap_dialog);
|
||||
|
||||
imap_dialog->collapse_button = GTK_WIDGET(gtk_builder_get_object (builder, "collapse-button"));
|
||||
g_signal_connect (imap_dialog->collapse_button, "clicked",
|
||||
G_CALLBACK(collapse_button_cb), (gpointer)imap_dialog);
|
||||
|
||||
imap_dialog->view = GTK_WIDGET(gtk_builder_get_object (builder, "treeview"));
|
||||
|
||||
// Set filter column
|
||||
filter = gtk_tree_view_get_model (GTK_TREE_VIEW(imap_dialog->view));
|
||||
gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER(filter), FILTER);
|
||||
|
||||
/* Enable alternative line colors */
|
||||
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(imap_dialog->view), TRUE);
|
||||
|
||||
/* default to 'close' button */
|
||||
gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(imap_dialog->view));
|
||||
gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
|
||||
|
||||
gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, imap_dialog);
|
||||
|
||||
g_object_unref (G_OBJECT(builder));
|
||||
|
||||
gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(imap_dialog->dialog));
|
||||
get_account_info (imap_dialog);
|
||||
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
static void
|
||||
close_handler (gpointer user_data)
|
||||
{
|
||||
ImapDialog *imap_dialog = user_data;
|
||||
|
||||
ENTER(" ");
|
||||
gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(imap_dialog->dialog));
|
||||
gtk_widget_destroy (GTK_WIDGET(imap_dialog->dialog));
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
static void
|
||||
refresh_handler (GHashTable *changes, gpointer user_data)
|
||||
{
|
||||
ENTER(" ");
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
show_handler (const char *klass, gint component_id,
|
||||
gpointer user_data, gpointer iter_data)
|
||||
{
|
||||
ImapDialog *imap_dialog = user_data;
|
||||
|
||||
ENTER(" ");
|
||||
if (!imap_dialog)
|
||||
{
|
||||
LEAVE("No data strucure");
|
||||
return(FALSE);
|
||||
}
|
||||
gtk_window_present (GTK_WINDOW(imap_dialog->dialog));
|
||||
LEAVE(" ");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* gnc_imap_dialog *
|
||||
* opens a window showing Bayesian and Non-Bayesian information *
|
||||
* *
|
||||
* Args: parent - the parent of the window to be created *
|
||||
* Return: nothing *
|
||||
\********************************************************************/
|
||||
void
|
||||
gnc_imap_dialog (GtkWidget *parent)
|
||||
{
|
||||
ImapDialog *imap_dialog;
|
||||
gint component_id;
|
||||
|
||||
ENTER(" ");
|
||||
if (gnc_forall_gui_components (DIALOG_IMAP_CM_CLASS, show_handler, NULL))
|
||||
{
|
||||
LEAVE("Existing dialog raised");
|
||||
return;
|
||||
}
|
||||
imap_dialog = g_new0 (ImapDialog, 1);
|
||||
|
||||
gnc_imap_dialog_create (parent, imap_dialog);
|
||||
|
||||
component_id = gnc_register_gui_component (DIALOG_IMAP_CM_CLASS,
|
||||
refresh_handler, close_handler,
|
||||
imap_dialog);
|
||||
|
||||
gnc_gui_component_set_session (component_id, imap_dialog->session);
|
||||
|
||||
gtk_widget_show (imap_dialog->dialog);
|
||||
LEAVE(" ");
|
||||
}
|
28
src/gnome/dialog-imap-editor.h
Normal file
28
src/gnome/dialog-imap-editor.h
Normal file
@ -0,0 +1,28 @@
|
||||
/********************************************************************\
|
||||
* dialog-imap-editor.h -- Import Map Editor dialog *
|
||||
* Copyright (C) 2015 Robert Fewell *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef DIALOG_IMAP_EDITOR_H
|
||||
#define DIALOG_IMAP_EDITOR_H
|
||||
|
||||
void gnc_imap_dialog (GtkWidget *parent);
|
||||
|
||||
#endif
|
@ -44,6 +44,7 @@
|
||||
#include "dialog-fincalc.h"
|
||||
#include "dialog-find-transactions.h"
|
||||
#include "dialog-find-transactions2.h"
|
||||
#include "dialog-imap-editor.h"
|
||||
#include "dialog-sx-since-last-run.h"
|
||||
#include "dialog-totd.h"
|
||||
#include "assistant-acct-period.h"
|
||||
@ -88,6 +89,7 @@ static void gnc_main_window_cmd_tools_financial_calculator (GtkAction *action, G
|
||||
static void gnc_main_window_cmd_tools_close_book (GtkAction *action, GncMainWindowActionData *data);
|
||||
static void gnc_main_window_cmd_tools_find_transactions (GtkAction *action, GncMainWindowActionData *data);
|
||||
static void gnc_main_window_cmd_tools_price_editor (GtkAction *action, GncMainWindowActionData *data);
|
||||
static void gnc_main_window_cmd_tools_imap_editor (GtkAction *action, GncMainWindowActionData *data);
|
||||
static void gnc_main_window_cmd_tools_commodity_editor (GtkAction *action, GncMainWindowActionData *data);
|
||||
static void gnc_main_window_cmd_help_totd (GtkAction *action, GncMainWindowActionData *data);
|
||||
|
||||
@ -201,6 +203,11 @@ static GtkActionEntry gnc_plugin_actions [] =
|
||||
N_("Close the Book at the end of the Period"),
|
||||
G_CALLBACK (gnc_main_window_cmd_tools_close_book)
|
||||
},
|
||||
{
|
||||
"ToolsImapEditorAction", NULL, N_("_Import Map Editor"), NULL,
|
||||
N_("View and Delete Bayesian and Non Bayesian information"),
|
||||
G_CALLBACK (gnc_main_window_cmd_tools_imap_editor)
|
||||
},
|
||||
|
||||
/* Help menu */
|
||||
|
||||
@ -602,6 +609,14 @@ gnc_main_window_cmd_actions_close_books (GtkAction *action, GncMainWindowActionD
|
||||
}
|
||||
#endif /* CLOSE_BOOKS_ACTUALLY_WORKS */
|
||||
|
||||
static void
|
||||
gnc_main_window_cmd_tools_imap_editor (GtkAction *action, GncMainWindowActionData *data)
|
||||
{
|
||||
gnc_set_busy_cursor(NULL, TRUE);
|
||||
gnc_imap_dialog (NULL);
|
||||
gnc_unset_busy_cursor(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_main_window_cmd_tools_price_editor (GtkAction *action, GncMainWindowActionData *data)
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
<schemalist gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<schema id="org.gnucash.dialogs" path="/org/gnucash/dialogs/">
|
||||
<child name="account" schema="org.gnucash.dialogs.account"/>
|
||||
<child name="imap-editor" schema="org.gnucash.dialogs.imap-editor"/>
|
||||
<child name="preferences" schema="org.gnucash.dialogs.preferences"/>
|
||||
<child name="price-editor" schema="org.gnucash.dialogs.price-editor"/>
|
||||
<child name="pricedb-editor" schema="org.gnucash.dialogs.pricedb-editor"/>
|
||||
@ -30,6 +31,16 @@
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<schema id="org.gnucash.dialogs.imap-editor" path="/org/gnucash/dialogs/imap-editor/">
|
||||
<key type="(iiii)" name="last-geometry">
|
||||
<default>(-1,-1,-1,-1)</default>
|
||||
<summary>Last window position and size</summary>
|
||||
<description>This setting describes the size and position of the window when it was last closed.
|
||||
The numbers are the X and Y coordinates of the top left corner of the window
|
||||
followed by the width and height of the window.</description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<schema id="org.gnucash.dialogs.preferences" path="/org/gnucash/dialogs/preferences/">
|
||||
<key name="last-geometry" type="(iiii)">
|
||||
<default>(-1,-1,-1,-1)</default>
|
||||
|
@ -5,6 +5,7 @@ gtkbuilder_DATA = \
|
||||
assistant-loan.glade \
|
||||
assistant-stock-split.glade \
|
||||
dialog-commodities.glade \
|
||||
dialog-imap-editor.glade \
|
||||
dialog-fincalc.glade \
|
||||
dialog-lot-viewer.glade \
|
||||
dialog-new-user.glade \
|
||||
|
370
src/gnome/gtkbuilder/dialog-imap-editor.glade
Normal file
370
src/gnome/gtkbuilder/dialog-imap-editor.glade
Normal file
@ -0,0 +1,370 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkTreeStore" id="tree-store">
|
||||
<columns>
|
||||
<!-- column-name source_account_name -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name source_account -->
|
||||
<column type="gpointer"/>
|
||||
<!-- column-name based_on -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name match_string -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name map_account_name -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name map_account -->
|
||||
<column type="gpointer"/>
|
||||
<!-- column-name full_category -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name count -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name filter -->
|
||||
<column type="gboolean"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkTreeModelFilter" id="treemodelfilter">
|
||||
<property name="child_model">tree-store</property>
|
||||
</object>
|
||||
<object class="GtkDialog" id="Import Map Dialog">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="title" translatable="yes">Import Map Editor</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="default_height">400</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<signal name="destroy" handler="gnc_imap_dialog_window_destroy_cb" swapped="no"/>
|
||||
<signal name="response" handler="gnc_imap_dialog_response_cb" swapped="no"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox2">
|
||||
<property name="can_focus">False</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="delete_button">
|
||||
<property name="label">gtk-delete</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">What type of information to display?</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">5</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="radio-bayes">
|
||||
<property name="label" translatable="yes">Bayesian</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="radio-nbayes">
|
||||
<property name="label" translatable="yes">Non-Bayesian</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">radio-bayes</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="radio-online">
|
||||
<property name="label" translatable="yes">Online ID</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">radio-bayes</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">treemodelfilter</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="source_account_name">
|
||||
<property name="resizable">True</property>
|
||||
<property name="title" translatable="yes">Source Account Name</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext3"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="based_on">
|
||||
<property name="resizable">True</property>
|
||||
<property name="title" translatable="yes">Based On</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext4">
|
||||
<property name="xpad">10</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="match">
|
||||
<property name="resizable">True</property>
|
||||
<property name="title" translatable="yes">Match String</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext1">
|
||||
<property name="xpad">10</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="map_account_name">
|
||||
<property name="resizable">True</property>
|
||||
<property name="title" translatable="yes">Mapped to Account Name</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext2">
|
||||
<property name="xpad">10</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="count">
|
||||
<property name="resizable">True</property>
|
||||
<property name="title" translatable="yes">Count of Match String Usage</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext5">
|
||||
<property name="xpad">10</property>
|
||||
<property name="alignment">center</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">7</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="filter-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ypad">5</property>
|
||||
<property name="label" translatable="yes">Case sensative filtering is available on 'Match String' and 'Mapped to Account Name'.</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="filter-text-entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="invisible_char_set">True</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="filter-button">
|
||||
<property name="label" translatable="yes">_Filter</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="expand-button">
|
||||
<property name="label" translatable="yes">_Expand All</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="collapse-button">
|
||||
<property name="label" translatable="yes">_Collapse All</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ypad">5</property>
|
||||
<property name="label" translatable="yes">Multiple rows can be selected and then deleted by pressing the delete button...</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-10">delete_button</action-widget>
|
||||
<action-widget response="-6">close_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
@ -56,6 +56,7 @@
|
||||
<menuitem name="ToolsCommodityEditor" action="ToolsCommodityEditorAction"/>
|
||||
<menuitem name="ToolsFinancialCalculator" action="ToolsFinancialCalculatorAction"/>
|
||||
<menuitem name="ToolsBookClose" action="ToolsBookCloseAction"/>
|
||||
<menuitem name="ToolsImapEditor" action="ToolsImapEditorAction"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
|
||||
|
@ -1280,8 +1280,16 @@ struct wrap_param
|
||||
static void
|
||||
wrap_gvalue_function (const char* key, KvpValue *val, gpointer data)
|
||||
{
|
||||
GValue *gv;
|
||||
auto param = static_cast<wrap_param*>(data);
|
||||
GValue *gv = gvalue_from_kvp_value(val);
|
||||
if (val->get_type() != KvpValue::Type::FRAME)
|
||||
gv = gvalue_from_kvp_value(val);
|
||||
else
|
||||
{
|
||||
gv = g_slice_new0 (GValue);
|
||||
g_value_init (gv, G_TYPE_STRING);
|
||||
g_value_set_string (gv, nullptr);
|
||||
}
|
||||
param->proc(key, gv, param->user_data);
|
||||
g_slice_free (GValue, gv);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user