r21871 - gnucash/trunk/src/plugins/bi_import - Bug 667581 - Migrate Invoice / Bill plugin to Builder
Mike Evans
mikee at code.gnucash.org
Sat Jan 21 11:22:45 EST 2012
Author: mikee
Date: 2012-01-21 11:22:45 -0500 (Sat, 21 Jan 2012)
New Revision: 21871
Trac: http://svn.gnucash.org/trac/changeset/21871
Added:
gnucash/trunk/src/plugins/bi_import/dialog-bi-import-gui.c
gnucash/trunk/src/plugins/bi_import/dialog-bi-import-gui.h
gnucash/trunk/src/plugins/bi_import/dialog-bi-import-helper.c
gnucash/trunk/src/plugins/bi_import/dialog-bi-import-helper.h
gnucash/trunk/src/plugins/bi_import/dialog-bi-import.c
gnucash/trunk/src/plugins/bi_import/dialog-bi-import.h
gnucash/trunk/src/plugins/bi_import/gnc-plugin-bi-import.c
gnucash/trunk/src/plugins/bi_import/gnc-plugin-bi-import.h
gnucash/trunk/src/plugins/bi_import/gtkbuilder/
gnucash/trunk/src/plugins/bi_import/gtkbuilder/Makefile.am
gnucash/trunk/src/plugins/bi_import/gtkbuilder/dialog-bi-import-gui.glade
gnucash/trunk/src/plugins/bi_import/ui/gnc-plugin-bi-import-ui.xml
Log:
Bug 667581 - Migrate Invoice / Bill plugin to Builder
Add the renamed files.
Patch supplied by Bob Fewell. Many thanks.
Added: gnucash/trunk/src/plugins/bi_import/dialog-bi-import-gui.c
===================================================================
--- gnucash/trunk/src/plugins/bi_import/dialog-bi-import-gui.c (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/dialog-bi-import-gui.c 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,496 @@
+/*
+ * dialog-bi-import-gui.c -- Invoice Importer GUI
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file dialog-bi-import-gui.c
+ * @brief GUI handling for bi-import plugin
+ * @author Copyright (C) 2009 Sebastian Held <sebastian.held at gmx.de>
+ * @author Mike Evans <mikee at saxicola.co.uk>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib/gi18n.h>
+
+#include "gnc-ui.h"
+#include "gnc-ui-util.h"
+#include "gnc-component-manager.h"
+#include "dialog-utils.h"
+#include "gnc-gui-query.h"
+#include "gnc-file.h"
+#include "gnc-gnome-utils.h"
+#include "dialog-bi-import.h"
+#include "dialog-bi-import-gui.h"
+
+struct _bi_import_gui
+{
+ GtkWidget *dialog;
+ GtkWidget *tree_view;
+ GtkWidget *entryFilename;
+ GtkListStore *store;
+ gint component_id;
+ GString *regexp;
+ QofBook *book;
+ gchar *type;
+ gchar *open_mode;
+};
+
+
+// callback routines
+void gnc_bi_import_gui_ok_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_cancel_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_help_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_destroy_cb (GtkWidget *widget, gpointer data);
+static void gnc_bi_import_gui_close_handler (gpointer user_data);
+void gnc_bi_import_gui_buttonOpen_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_filenameChanged_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_option1_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_option2_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_option3_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_option4_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_option5_cb (GtkWidget *widget, gpointer data);
+void gnc_bi_import_gui_open_mode_cb (GtkWidget *widget, gpointer data);
+void gnc_import_gui_type_cb (GtkWidget *widget, gpointer data);
+
+// utils
+static gchar *gnc_input_dialog (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input);
+static void gnc_info2_dialog (GtkWidget *parent, const gchar *title, const gchar *msg);
+
+
+BillImportGui *
+gnc_plugin_bi_import_showGUI(void)
+{
+ BillImportGui *gui;
+ GtkBuilder *builder;
+ GList *glist;
+ GtkTreeIter iter;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ // if window exists already, activate it
+ glist = gnc_find_gui_components ("dialog-bi-import-gui", NULL, NULL);
+ if (glist)
+ {
+ // window found
+ gui = g_list_nth_data (glist, 0);
+ g_list_free (glist);
+ gtk_window_present (GTK_WINDOW(gui->dialog));
+ return gui;
+ }
+
+ // create new window
+ gui = g_new0 (BillImportGui, 1);
+ gui->type = "BILL"; // Set default type to match gui. really shouldn't be here TODO change me
+ gui->open_mode = "ALL";
+
+ builder = gtk_builder_new();
+ gnc_builder_add_from_file (builder,"dialog-bi-import-gui.glade", "bi-import Dialog");
+ gui->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "bi-import Dialog"));
+ gui->tree_view = GTK_WIDGET(gtk_builder_get_object (builder, "treeview1"));
+ gui->entryFilename = GTK_WIDGET(gtk_builder_get_object (builder, "entryFilename"));
+
+ gui->book = gnc_get_current_book();
+
+ gui->regexp = g_string_new ( "^(?<id>[^;]*);(?<date_opened>[^;]*);(?<owner_id>[^;]*);(?<billing_id>[^;]*);?(?<notes>[^;]*);?(?<date>[^;]*);?(?<desc>[^;]*);?(?<action>[^;]*);?(?<account>[^;]*);?(?<quantity>[^;]*);?(?<price>[^;]*);?(?<disc_type>[^;]*);?(?<disc_how>[^;]*);?(?<discount>[^;]*);?(?<taxable>[^;]*);?(?<taxincluded>[^;]*);?(?<tax_table>[^;]*);(?<date_posted>[^;]*);(?<due_date>[^;]*);(?<account_posted>[^;]*);(?<memo_posted>[^;]*);(?<accu_splits>[^;]*)$");
+
+ // create model and bind to view
+ gui->store = gtk_list_store_new (N_COLUMNS,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, // invoice settings
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, // entry settings
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); // autopost settings
+ gtk_tree_view_set_model( GTK_TREE_VIEW(gui->tree_view), GTK_TREE_MODEL(gui->store) );
+#define CREATE_COLUMN(description,column_id) \
+ renderer = gtk_cell_renderer_text_new (); \
+ column = gtk_tree_view_column_new_with_attributes (description, renderer, "text", column_id, NULL); \
+ gtk_tree_view_column_set_resizable (column, TRUE); \
+ gtk_tree_view_append_column (GTK_TREE_VIEW (gui->tree_view), column);
+ CREATE_COLUMN ("id", ID);
+ CREATE_COLUMN ("date__opened", DATE_OPENED);
+ CREATE_COLUMN ("owner__id", OWNER_ID);
+ CREATE_COLUMN ("billing__id", BILLING_ID);
+ CREATE_COLUMN ("notes", NOTES);
+
+ CREATE_COLUMN ("date", DATE);
+ CREATE_COLUMN ("desc", DESC);
+ CREATE_COLUMN ("action", ACTION);
+ CREATE_COLUMN ("account", ACCOUNT);
+ CREATE_COLUMN ("quantity", QUANTITY);
+ CREATE_COLUMN ("price", PRICE);
+ CREATE_COLUMN ("disc__type", DISC_TYPE);
+ CREATE_COLUMN ("disc__how", DISC_HOW);
+ CREATE_COLUMN ("discount", DISCOUNT);
+ CREATE_COLUMN ("taxable", TAXABLE);
+ CREATE_COLUMN ("taxincluded", TAXINCLUDED);
+ CREATE_COLUMN ("tax__table", TAX_TABLE);
+
+ CREATE_COLUMN ("date__posted", DATE_POSTED);
+ CREATE_COLUMN ("due__date", DUE_DATE);
+ CREATE_COLUMN ("account__posted", ACCOUNT_POSTED);
+ CREATE_COLUMN ("memo__posted", MEMO_POSTED);
+ CREATE_COLUMN ("accu__splits", ACCU_SPLITS);
+
+ gui->component_id = gnc_register_gui_component ("dialog-bi-import-gui",
+ NULL,
+ gnc_bi_import_gui_close_handler,
+ gui);
+
+ /* Setup signals */
+ gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, gui);
+
+ gtk_widget_show_all ( gui->dialog );
+
+ g_object_unref(G_OBJECT(builder));
+
+ return gui;
+}
+
+static gchar *
+gnc_plugin_bi_import_getFilename(void)
+{
+ // prepare file import dialog
+ gchar *filename;
+ GList *filters;
+ GtkFileFilter *filter;
+ filters = NULL;
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "comma separated values (*.csv)");
+ gtk_file_filter_add_pattern (filter, "*.csv");
+ filters = g_list_append( filters, filter );
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "text files (*.txt)");
+ gtk_file_filter_add_pattern (filter, "*.txt");
+ filters = g_list_append( filters, filter );
+ filename = gnc_file_dialog(_("Import Bills or Invoices from csv"), filters, NULL, GNC_FILE_DIALOG_IMPORT);
+
+ return filename;
+}
+
+void
+gnc_bi_import_gui_ok_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ gchar *filename = g_strdup( gtk_entry_get_text( GTK_ENTRY(gui->entryFilename) ) );
+ bi_import_stats stats;
+ bi_import_result res;
+ guint n_fixed, n_deleted, n_invoices_created, n_invoices_updated;
+ GString *info;
+
+ // import
+ info = g_string_new("");
+
+ gtk_list_store_clear (gui->store);
+ res = gnc_bi_import_read_file (filename, gui->regexp->str, gui->store, 0, &stats);
+ if (res == RESULT_OK)
+ {
+ gnc_bi_import_fix_bis (gui->store, &n_fixed, &n_deleted, info, gui->type);
+ if (info->len > 0)
+ gnc_info_dialog (gui->dialog, "%s", info->str);
+ g_string_free( info, TRUE );
+ gnc_bi_import_create_bis (gui->store, gui->book, &n_invoices_created, &n_invoices_updated, gui->type, gui->open_mode);
+ gnc_info_dialog (gui->dialog, _("Import results:\n%i lines were ignored\n%i lines imported:\n %u fixes\n %u ignored (not fixable)\n\n %u created\n %u updated (based on id)"), stats.n_ignored, stats.n_imported, n_fixed, n_deleted, n_invoices_created, n_invoices_updated);
+
+ if (stats.n_ignored > 0)
+ gnc_info2_dialog (gui->dialog, _("These lines were ignored during import"), stats.ignored_lines->str);
+
+ g_string_free (stats.ignored_lines, TRUE);
+ gnc_close_gui_component (gui->component_id);
+ }
+ else if (res == RESULT_OPEN_FAILED)
+ {
+ gnc_error_dialog (gui->dialog, _("The input file can not be opened."));
+ }
+ else if (res == RESULT_ERROR_IN_REGEXP)
+ {
+ //gnc_error_dialog (gui->dialog, "The regular expression is faulty:\n\n%s", stats.err->str);
+ }
+}
+
+void
+gnc_bi_import_gui_cancel_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+
+ gnc_close_gui_component (gui->component_id);
+}
+
+void
+gnc_bi_import_gui_help_cb (GtkWidget *widget, gpointer data)
+{
+ gnc_gnome_help(HF_HELP, HL_USAGE);
+}
+
+static void
+gnc_bi_import_gui_close_handler (gpointer user_data)
+{
+ BillImportGui *gui = user_data;
+
+ gtk_widget_destroy (gui->dialog);
+ // gui has already been freed by this point.
+ // gui->dialog = NULL;
+}
+
+void
+gnc_bi_import_gui_destroy_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+
+ gnc_suspend_gui_refresh ();
+ gnc_unregister_gui_component (gui->component_id);
+ gnc_resume_gui_refresh ();
+
+ g_object_unref (gui->store);
+ g_string_free (gui->regexp, TRUE);
+ g_free (gui);
+}
+
+void gnc_bi_import_gui_buttonOpen_cb (GtkWidget *widget, gpointer data)
+{
+ gchar *filename;
+ BillImportGui *gui = data;
+
+ filename = gnc_plugin_bi_import_getFilename();
+ if (filename)
+ {
+ //printf("Setting filename"); // debug
+ gtk_entry_set_text( GTK_ENTRY(gui->entryFilename), filename );
+ //printf("Set filename"); // debug
+ g_free( filename );
+ }
+}
+
+void gnc_bi_import_gui_filenameChanged_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ gchar *filename = g_strdup( gtk_entry_get_text( GTK_ENTRY(gui->entryFilename) ) );
+
+ // generate preview
+ gtk_list_store_clear (gui->store);
+ gnc_bi_import_read_file (filename, gui->regexp->str, gui->store, 10, NULL);
+
+ g_free( filename );
+}
+
+void gnc_bi_import_gui_option1_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
+ return;
+ g_string_assign (gui->regexp, "^(?<id>[^;]*);(?<date_opened>[^;]*);(?<owner_id>[^;]*);(?<billing_id>[^;]*);?(?<notes>[^;]*);?(?<date>[^;]*);?(?<desc>[^;]*);?(?<action>[^;]*);?(?<account>[^;]*);?(?<quantity>[^;]*);?(?<price>[^;]*);?(?<disc_type>[^;]*);?(?<disc_how>[^;]*);?(?<discount>[^;]*);?(?<taxable>[^;]*);?(?<taxincluded>[^;]*);?(?<tax_table>[^;]*);(?<date_posted>[^;]*);(?<due_date>[^;]*);(?<account_posted>[^;]*);(?<memo_posted>[^;]*);(?<accu_splits>[^;]*)$");
+ gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
+}
+
+void gnc_bi_import_gui_option2_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
+ return;
+ g_string_assign (gui->regexp, "^(?<id>[^,]*),(?<date_opened>[^,]*),(?<owner_id>[^,]*),(?<billing_id>[^,]*),?(?<notes>[^,]*),?(?<date>[^,]*),?(?<desc>[^,]*),?(?<action>[^,]*),?(?<account>[^,]*),?(?<quantity>[^,]*),?(?<price>[^,]*),?(?<disc_type>[^,]*),?(?<disc_how>[^,]*),?(?<discount>[^,]*),?(?<taxable>[^,]*),?(?<taxincluded>[^,]*),?(?<tax_table>[^,]*),(?<date_posted>[^,]*),(?<due_date>[^,]*),(?<account_posted>[^,]*),(?<memo_posted>[^,]*),(?<accu_splits>[^,]*)$");
+ gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
+}
+
+void gnc_bi_import_gui_option3_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
+ return;
+ g_string_assign (gui->regexp, "^((?<id>[^\";]*)|\"(?<id>[^\"]*)\");((?<date_opened>[^\";]*)|\"(?<date_opened>[^\"]*)\");((?<owner_id>[^\";]*)|\"(?<owner_id>[^\"]*)\");((?<billing_id>[^\";]*)|\"(?<billing_id>[^\"]*)\");((?<notes>[^\";]*)|\"(?<notes>[^\"]*)\");((?<date>[^\";]*)|\"(?<date>[^\"]*)\");((?<desc>[^\";]*)|\"(?<desc>[^\"]*)\");((?<action>[^\";]*)|\"(?<action>[^\"]*)\");((?<account>[^\";]*)|\"(?<account>[^\"]*)\");((?<quantity>[^\";]*)|\"(?<quantity>[^\"]*)\");((?<price>[^\";]*)|\"(?<price>[^\"]*)\");((?<disc_type>[^\";]*)|\"(?<disc_type>[^\"]*)\");((?<disc_how>[^\";]*)|\"(?<disc_how>[^\"]*)\");((?<discount>[^\";]*)|\"(?<discount>[^\"]*)\");((?<taxable>[^\";]*)|\"(?<taxable>[^\"]*)\");((?<taxincluded>[^\";]*)|\"(?<taxincluded>[^\"]*)\");((?<tax_table>[^\";]*)|\"(?<tax_table>[^\"]*)\");((?<date_posted>[^\";]*)|\"(?<date_posted>[^\"]*)\");((?<due_date>[^\";]*)|\"(?<due_date>[^\"]*)\");((?<account_posted>[^\";]*)|\"(?<account_posted>[^\"]*)\");((?<memo_posted>[^\";]*)|\"(?<memo_posted>[^\"]*)\");((?<accu_splits>[^\";]*)|\"(?<accu_splits>[^\"]*)\")$");
+ gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
+}
+
+void gnc_bi_import_gui_option4_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
+ return;
+ g_string_assign (gui->regexp, "^((?<id>[^\",]*)|\"(?<id>[^\"]*)\"),((?<date_opened>[^\",]*)|\"(?<date_opened>[^\"]*)\"),((?<owner_id>[^\",]*)|\"(?<owner_id>[^\"]*)\"),((?<billing_id>[^\",]*)|\"(?<billing_id>[^\"]*)\"),((?<notes>[^\",]*)|\"(?<notes>[^\"]*)\"),((?<date>[^\",]*)|\"(?<date>[^\"]*)\"),((?<desc>[^\",]*)|\"(?<desc>[^\"]*)\"),((?<action>[^\",]*)|\"(?<action>[^\"]*)\"),((?<account>[^\",]*)|\"(?<account>[^\"]*)\"),((?<quantity>[^\",]*)|\"(?<quantity>[^\"]*)\"),((?<price>[^\",]*)|\"(?<price>[^\"]*)\"),((?<disc_type>[^\",]*)|\"(?<disc_type>[^\"]*)\"),((?<disc_how>[^\",]*)|\"(?<disc_how>[^\"]*)\"),((?<discount>[^\",]*)|\"(?<discount>[^\"]*)\"),((?<taxable>[^\",]*)|\"(?<taxable>[^\"]*)\"),((?<taxincluded>[^\",]*)|\"(?<taxincluded>[^\"]*)\"),((?<tax_table>[^\",]*)|\"(?<tax_table>[^\"]*)\"),((?<date_posted>[^\",]*)|\"(?<date_posted>[^\"]*)\"),((?<due_date>[^\",]*)|\"(?<due_date>[^\"]*)\"),((?<account_posted>[^\",]*)|\"(?<account_posted>[^\"]*)\"),((?<memo_posted>[^\",]*)|\"(?<memo_posted>[^\"]*)\"),((?<accu_splits>[^\",]*)|\"(?<accu_splits>[^\"]*)\")$");
+ gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
+}
+
+void gnc_bi_import_gui_option5_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ gchar *temp;
+ if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
+ return;
+ temp = gnc_input_dialog (0, _("Adjust regular expression used for import"), _("This regular expression is used to parse the import file. Modify according to your needs.\n"), gui->regexp->str);
+ if (temp)
+ {
+ g_string_assign (gui->regexp, temp);
+ g_free (temp);
+ gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
+ }
+}
+
+void gnc_bi_import_gui_open_mode_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ const gchar *name;
+ name = gtk_buildable_get_name(GTK_BUILDABLE(widget));
+ if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
+ return;
+ if (g_ascii_strcasecmp(name, "radiobuttonOpenAll") == 0)gui->open_mode = "ALL";
+ else if (g_ascii_strcasecmp(name, "radiobuttonOpenNotPosted") == 0)gui->open_mode = "NOT_POSTED";
+ else if (g_ascii_strcasecmp(name, "radiobuttonOpenNone") == 0)gui->open_mode = "NONE";
+}
+
+
+/*****************************************************************
+ * Set whether we are importing a bi, invoice, Customer or Vendor
+ * ****************************************************************/
+void gnc_import_gui_type_cb (GtkWidget *widget, gpointer data)
+{
+ BillImportGui *gui = data;
+ const gchar *name;
+ name = gtk_buildable_get_name(GTK_BUILDABLE(widget));
+ if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
+ return;
+ if (g_ascii_strcasecmp(name, "radiobuttonInvoice") == 0)gui->type = "INVOICE";
+ else if (g_ascii_strcasecmp(name, "radiobuttonBill") == 0)gui->type = "BILL";
+ //printf ("TYPE set to, %s\n",gui->type);
+
+}
+
+
+/********************************************************************\
+ * gnc_input_dialog *
+ * simple convenience dialog to get a single value from the user *
+ * user may choose between "Ok" and "Cancel" *
+ * *
+ * NOTE: This function does not return until the dialog is closed *
+ * *
+ * Args: parent - the parent window or NULL *
+ * title - the title of the dialog *
+ * msg - the message to display *
+ * default_input - will be displayed as default input *
+ * Return: the input (text) the user entered, if pressed "Ok" *
+ * NULL, if pressed "Cancel" *
+\********************************************************************/
+static gchar *
+gnc_input_dialog (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input)
+{
+ GtkWidget *dialog, *label, *content_area;
+ gint result;
+ GtkWidget *view;
+ GtkTextBuffer *buffer;
+ gchar *user_input;
+ GtkTextIter start, end;
+
+ /* Create the widgets */
+ dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
+#ifdef HAVE_GTK_2_14
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+#else
+ content_area = GTK_DIALOG (dialog)->vbox;
+#endif
+
+ // add a label
+ label = gtk_label_new (msg);
+ gtk_container_add (GTK_CONTAINER (content_area), label);
+
+ // add a textview
+ view = gtk_text_view_new ();
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD_CHAR);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ gtk_text_buffer_set_text (buffer, default_input, -1);
+ gtk_container_add (GTK_CONTAINER (content_area), view);
+
+ // run the dialog
+ gtk_widget_show_all (dialog);
+ result = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (result == GTK_RESPONSE_REJECT)
+ user_input = 0;
+ else
+ {
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ user_input = gtk_text_buffer_get_text (buffer,
+ &start, &end, FALSE);
+ }
+
+ gtk_widget_destroy (dialog);
+
+ return user_input;
+}
+
+
+/********************************************************************\
+ * gnc_info2_dialog *
+ * displays an information dialog box (with scrollable text area) *
+ * *
+ * NOTE: This function does not return until the dialog is closed *
+ * *
+ * Args: parent - the parent window or NULL *
+ * title - the title of the dialog *
+ * msg - the message to display *
+ * Return: none *
+\********************************************************************/
+static void
+gnc_info2_dialog (GtkWidget *parent, const gchar *title, const gchar *msg)
+{
+ GtkWidget *dialog, *scrolledwindow, *content_area;
+ gint result;
+ GtkWidget *view;
+ GtkTextBuffer *buffer;
+ gchar *user_input;
+ GtkTextIter start, end;
+ gint width, height;
+
+ /* Create the widgets */
+ dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
+#ifdef HAVE_GTK_2_14
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+#else
+ content_area = GTK_DIALOG (dialog)->vbox;
+#endif
+
+ // add a scroll area
+ scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (content_area), scrolledwindow);
+
+ // add a textview
+ view = gtk_text_view_new ();
+// gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD_CHAR);
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ gtk_text_buffer_set_text (buffer, msg, -1);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow), view);
+
+ // run the dialog
+ if (parent)
+ {
+ gtk_window_get_size (GTK_WINDOW(parent), &width, &height);
+ gtk_window_set_default_size (GTK_WINDOW(dialog), width, height);
+ }
+ gtk_widget_show_all (dialog);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
Added: gnucash/trunk/src/plugins/bi_import/dialog-bi-import-gui.h
===================================================================
--- gnucash/trunk/src/plugins/bi_import/dialog-bi-import-gui.h (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/dialog-bi-import-gui.h 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,48 @@
+/*
+ * dialog-bi-import-gui.h -- Invoice Importer GUI
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Tools
+ * @{
+ * @file dialog-bi-import-gui.h
+ * @brief GUI handling for bi-import plugin
+ * @author Copyright (C) 2009 Sebastian Held <sebastian.held at gmx.de>
+ */
+
+#ifndef GNC_PLUGIN_BI_IMPORT_GUI_H
+#define GNC_PLUGIN_BI_IMPORT_GUI_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _bi_import_gui BillImportGui;
+
+/**
+ * File chooser
+ */
+BillImportGui *gnc_plugin_bi_import_showGUI(void);
+
+G_END_DECLS
+
+#endif /* GNC_PLUGIN_BI_IMPORT_GUI_H */
+
+/** @} */
Added: gnucash/trunk/src/plugins/bi_import/dialog-bi-import-helper.c
===================================================================
--- gnucash/trunk/src/plugins/bi_import/dialog-bi-import-helper.c (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/dialog-bi-import-helper.c 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,80 @@
+/**
+ * dialog-bi-import-helper.c -- Helper functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "dialog-bi-import-helper.h"
+
+//! \brief helper function
+gboolean text2bool( const gchar *text )
+{
+ gboolean erg = FALSE;
+ gchar *temp;
+
+ if (!text)
+ return erg;
+
+ temp = g_strdup( text );
+ g_strstrip( temp );
+ if ((g_ascii_strcasecmp( temp, "yes" ) == 0) || (g_ascii_strcasecmp( temp, "true" ) == 0) ||
+ (g_ascii_strcasecmp( temp, "1" ) == 0) || (g_ascii_strcasecmp( temp, "x" ) == 0))
+ erg = TRUE;
+ g_free( temp );
+ return erg;
+}
+
+//! \brief helper function
+GncAmountType text2disc_type( const gchar *text )
+{
+ GncAmountType type = GNC_AMT_TYPE_PERCENT;
+ gchar *temp;
+
+ if (!text)
+ return type;
+
+ temp = g_strdup( text );
+ g_strstrip( temp );
+ if ((strlen(temp) > 0) && (g_ascii_strcasecmp( temp, "%" ) != 0))
+ type = GNC_AMT_TYPE_VALUE;
+ g_free( temp );
+ return type;
+}
+
+//! \brief helper function
+GncDiscountHow text2disc_how( const gchar *text )
+{
+ GncDiscountHow how = GNC_DISC_PRETAX;
+ gchar *temp;
+
+ if (!text)
+ return how;
+
+ temp = g_strdup( text );
+ g_strstrip( temp );
+ if (g_ascii_strcasecmp( temp, "=" ) == 0)
+ how = GNC_DISC_SAMETIME;
+ else if (g_ascii_strcasecmp( temp, ">" ) == 0)
+ how = GNC_DISC_POSTTAX;
+ g_free( temp );
+ return how;
+}
Added: gnucash/trunk/src/plugins/bi_import/dialog-bi-import-helper.h
===================================================================
--- gnucash/trunk/src/plugins/bi_import/dialog-bi-import-helper.h (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/dialog-bi-import-helper.h 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,33 @@
+/**
+ * dialog-bi-import-helper.h -- Helper functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ *
+ *
+ */
+
+
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include "gncEntry.h"
+
+gboolean text2bool( const gchar *text );
+GncAmountType text2disc_type( const gchar *text );
+GncDiscountHow text2disc_how( const gchar *text );
Added: gnucash/trunk/src/plugins/bi_import/dialog-bi-import.c
===================================================================
--- gnucash/trunk/src/plugins/bi_import/dialog-bi-import.c (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/dialog-bi-import.c 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,772 @@
+/*
+ * dialog-bi-import.c -- Invoice importer Core functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file dialog-bi-import.c
+ * @brief core import functions for invoice import plugin
+ * @author Copyright (C) 2009 Sebastian Held <sebastian.held at gmx.de>
+ * @author Mike Evans <mikee at saxicola.co.uk>
+ * @todo Create an option to import a pre-formed regex when it is present
+ * to enable the use of custom output csv formats.
+ * @todo Open the newly created invoice(es).
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef HAVE_LOCALTIME_R
+#include "localtime_r.h"
+#endif
+
+#include <glib/gi18n.h>
+#include <regex.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "gnc-ui.h"
+#include "gnc-ui-util.h"
+#include "gnc-gui-query.h"
+#include "gncAddress.h"
+#include "gncVendorP.h"
+#include "gncVendor.h"
+#include "gncEntry.h"
+
+#include "gnc-exp-parser.h"
+
+// query
+#include "Query.h"
+#include "qof.h"
+#include "GNCId.h"
+#include "gncIDSearch.h"
+#include "dialog-bi-import.h"
+#include "dialog-bi-import-helper.h"
+
+// To open the invoices for editing
+#include "business/business-gnome/gnc-plugin-page-invoice.h"
+#include "business/business-gnome/dialog-invoice.h"
+
+
+//#ifdef HAVE_GLIB_2_14
+// glib >= 2.14.0
+// perl regular expressions are available
+
+// this helper macro takes a regexp match and fills the model
+#define FILL_IN_HELPER(match_name,column) \
+ temp = g_match_info_fetch_named (match_info, match_name); \
+ if (temp) \
+ { \
+ g_strstrip( temp ); \
+ gtk_list_store_set (store, &iter, column, temp, -1); \
+ g_free (temp); \
+ }
+
+
+bi_import_result
+gnc_bi_import_read_file (const gchar * filename, const gchar * parser_regexp,
+ GtkListStore * store, guint max_rows,
+ bi_import_stats * stats)
+{
+ // some statistics
+ bi_import_stats stats_fallback;
+ FILE *f;
+
+ // regexp
+ char *line;
+ gchar *line_utf8, *temp;
+ GMatchInfo *match_info;
+ GError *err;
+ GRegex *regexpat;
+
+ // model
+ GtkTreeIter iter;
+
+ f = g_fopen (filename, "rt");
+ if (!f)
+ {
+ //gnc_error_dialog( 0, _("File %s cannot be opened."), filename );
+ return RESULT_OPEN_FAILED;
+ }
+
+ // set up statistics
+ if (!stats)
+ stats = &stats_fallback;
+
+ // compile the regular expression and check for errors
+ err = NULL;
+ regexpat =
+ g_regex_new (parser_regexp, G_REGEX_EXTENDED | G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES, 0, &err);
+ if (err != NULL)
+ {
+ GtkWidget *dialog;
+ gchar *errmsg;
+
+ errmsg = g_strdup_printf (_("Error in regular expression '%s':\n%s"),
+ parser_regexp, err->message);
+ g_error_free (err);
+ err = NULL;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK, "%s", errmsg);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ g_free (errmsg);
+ errmsg = 0;
+
+ fclose (f);
+ return RESULT_ERROR_IN_REGEXP;
+ }
+
+ // start the import
+ stats->n_imported = 0;
+ stats->n_ignored = 0;
+ stats->ignored_lines = g_string_new (NULL);
+#define buffer_size 1000
+ line = g_malloc0 (buffer_size);
+ while (!feof (f)
+ && ((max_rows == 0)
+ || (stats->n_imported + stats->n_ignored < max_rows)))
+ {
+ int l;
+ // read one line
+ if (!fgets (line, buffer_size, f))
+ break; // eof
+ // now strip the '\n' from the end of the line
+ l = strlen (line);
+ if ((l > 0) && (line[l - 1] == '\n'))
+ line[l - 1] = 0;
+
+ // convert line from locale into utf8
+ line_utf8 = g_locale_to_utf8 (line, -1, NULL, NULL, NULL);
+
+ // parse the line
+ match_info = NULL; // it seems, that in contrast to documentation, match_info is not alsways set -> g_match_info_free will segfault
+ if (g_regex_match (regexpat, line_utf8, 0, &match_info))
+ {
+ // match found
+ stats->n_imported++;
+
+ // fill in the values
+ gtk_list_store_append (store, &iter);
+ FILL_IN_HELPER ("id", ID); /* FIXME: Should "id" be translated? I don't think so. */
+ FILL_IN_HELPER ("date_opened", DATE_OPENED);
+ FILL_IN_HELPER ("owner_id", OWNER_ID);
+ FILL_IN_HELPER ("billing_id", BILLING_ID);
+ FILL_IN_HELPER ("notes", NOTES);
+
+ FILL_IN_HELPER ("date", DATE);
+ FILL_IN_HELPER ("desc", DESC);
+ FILL_IN_HELPER ("action", ACTION);
+ FILL_IN_HELPER ("account", ACCOUNT);
+ FILL_IN_HELPER ("quantity", QUANTITY);
+ FILL_IN_HELPER ("price", PRICE);
+ FILL_IN_HELPER ("disc_type", DISC_TYPE);
+ FILL_IN_HELPER ("disc_how", DISC_HOW);
+ FILL_IN_HELPER ("discount", DISCOUNT);
+ FILL_IN_HELPER ("taxable", TAXABLE);
+ FILL_IN_HELPER ("taxincluded", TAXINCLUDED);
+ FILL_IN_HELPER ("tax_table", TAX_TABLE);
+
+ FILL_IN_HELPER ("date_posted", DATE_POSTED);
+ FILL_IN_HELPER ("due_date", DUE_DATE);
+ FILL_IN_HELPER ("account_posted", ACCOUNT_POSTED);
+ FILL_IN_HELPER ("memo_posted", MEMO_POSTED);
+ FILL_IN_HELPER ("accu_splits", ACCU_SPLITS);
+ }
+ else
+ {
+ // ignore line
+ stats->n_ignored++;
+ g_string_append (stats->ignored_lines, line_utf8);
+ g_string_append_c (stats->ignored_lines, '\n');
+ }
+
+ g_match_info_free (match_info);
+ match_info = 0;
+ g_free (line_utf8);
+ line_utf8 = 0;
+ }
+ g_free (line);
+ line = 0;
+
+ g_regex_unref (regexpat);
+ regexpat = 0;
+ fclose (f);
+
+ if (stats == &stats_fallback)
+ // stats are not requested -> free the string
+ g_string_free (stats->ignored_lines, TRUE);
+
+ return RESULT_OK;
+}
+
+
+//! \brief try to fix some common errors in the csv representation of invoices
+//! * corrects the date format
+//! * corrects ambigous values in multi line invoices
+//! * ensures customer exists
+//! * if quantity is unset, set to 1
+//! * if price is unset, delete row
+void
+gnc_bi_import_fix_bis (GtkListStore * store, guint * fixed, guint * deleted,
+ GString * info, gchar *type)
+{
+ GtkTreeIter iter;
+ gboolean valid, row_deleted, row_fixed;
+ gchar *id, *date_opened, *date_posted, *owner_id, *date, *quantity, *price;
+ GString *prev_id, *prev_date_opened, *prev_date_posted, *prev_owner_id, *prev_date; // needed to fix multi line invoices
+ guint dummy;
+ gint row = 1;
+
+ // allow the call to this function with only GtkListeStore* specified
+ if (!fixed)
+ fixed = &dummy;
+ if (!deleted)
+ deleted = &dummy;
+
+ *fixed = 0;
+ *deleted = 0;
+
+ // init strings
+ prev_id = g_string_new ("");
+ prev_date_opened = g_string_new ("");
+ prev_date_posted = g_string_new ("");
+ prev_owner_id = g_string_new ("");
+ prev_date = g_string_new ("");
+
+ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
+ while (valid)
+ {
+ row_deleted = FALSE;
+ row_fixed = FALSE;
+
+ // Walk through the list, reading each row
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+ ID, &id,
+ DATE_OPENED, &date_opened,
+ DATE_POSTED, &date_posted,
+ OWNER_ID, &owner_id,
+ DATE, &date,
+ QUANTITY, &quantity, PRICE, &price, -1);
+
+ if (strlen (price) == 0)
+ {
+ // invalid row (no price given)
+ // no fix possible -> delete row
+ valid = gtk_list_store_remove (store, &iter);
+ row_deleted = TRUE;
+ g_string_append_printf (info,
+ _("ROW %d DELETED, PRICE_NOT_SET: id=%s\n"),
+ row, id);
+ }
+ else if (strlen (quantity) == 0)
+ {
+ // invalid row (no quantity given)
+ // no fix possible -> delete row
+ valid = gtk_list_store_remove (store, &iter);
+ row_deleted = TRUE;
+ g_string_append_printf (info, _("ROW %d DELETED, QTY_NOT_SET: id=%s\n"),
+ row, id);
+ }
+ else
+ {
+ if (strlen (id) == 0)
+ {
+ // no invoice id specified
+ if (prev_id->len == 0)
+ {
+ // cannot fix -> delete row
+ valid = gtk_list_store_remove (store, &iter);
+ row_deleted = TRUE;
+ g_string_append_printf (info,
+ _("ROW %d DELETED, ID_NOT_SET\n"), row);
+ }
+ else
+ {
+ // this is a fixable multi line invoice
+ gtk_list_store_set (store, &iter, ID, prev_id->str, -1);
+ row_fixed = TRUE;
+ }
+ }
+ else
+ {
+ // remember invoice id (to be able to fix multi line invoices)
+ g_string_assign (prev_id, id);
+ // new invoice => reset all other fixable entries
+ g_string_assign (prev_date_opened, "");
+ g_string_assign (prev_date_posted, "");
+ g_string_assign (prev_owner_id, "");
+ g_string_assign (prev_date, "");
+ }
+ }
+
+ if (!row_deleted)
+ {
+ // the row is valid (price and id are valid)
+
+ if (strlen (date_opened) == 0)
+ {
+ if (prev_date_opened->len == 0)
+ {
+ // fix this by using the current date (why is this so complicated?)
+ gchar temp[20];
+ GDate *date;
+ time_t secs;
+ struct tm now;
+ time (&secs);
+ localtime_r (&secs, &now);
+ date =
+ g_date_new_dmy (now.tm_mday, now.tm_mon + 1,
+ now.tm_year + 1900);
+ g_date_strftime (temp, 20, "%x", date); // create a locale specific date string
+ g_string_assign (prev_date_opened, temp);
+ g_date_free (date);
+ }
+ // fix this by using the previous date_opened value (multi line invoice)
+ gtk_list_store_set (store, &iter, DATE_OPENED,
+ prev_date_opened->str, -1);
+ row_fixed = TRUE;
+ }
+ else
+ {
+ // remember date_opened (to be able to fix multi line invoices)
+ g_string_assign (prev_date_opened, date_opened);
+ }
+
+ // date_opened is valid
+
+ if (strlen (date_posted) == 0)
+ {
+ if (prev_date_posted->len == 0)
+ {
+ // this invoice will have to get posted manually
+ }
+ else
+ {
+ // multi line invoice => fix it
+ gtk_list_store_set (store, &iter, DATE_POSTED,
+ prev_date_posted->str, -1);
+ row_fixed = TRUE;
+ }
+ }
+ else
+ {
+ // remember date_opened (to be able to fix multi line invoices)
+ g_string_assign (prev_date_posted, date_posted);
+ }
+
+ // date_posted is valid
+
+ if (strlen (quantity) == 0)
+ {
+ // quantity is unset => set to 1
+ gtk_list_store_set (store, &iter, QUANTITY, "1", -1);
+ row_fixed = TRUE;
+ }
+
+ // quantity is valid
+
+ if (strlen (owner_id) == 0)
+ {
+ if (prev_owner_id->len == 0)
+ {
+ // no customer given and not fixable => delete row
+ valid = gtk_list_store_remove (store, &iter);
+ row_deleted = TRUE;
+ g_string_append_printf (info,
+ _("ROW %d DELETED, OWNER_NOT_SET: id=%s\n"),
+ row, id);
+ }
+ else
+ {
+ gtk_list_store_set (store, &iter, owner_id,
+ prev_owner_id->str, -1);
+ row_fixed = TRUE;
+ }
+ }
+ else
+ {
+ // remember owner_id
+ g_string_assign (prev_owner_id, owner_id);
+ }
+ if (g_ascii_strcasecmp (type, "BILL") == 0)
+ {
+ // BILL: check, if vendor exists
+ if (!gnc_search_vendor_on_id
+ (gnc_get_current_book (), prev_owner_id->str))
+ {
+ // vendor not found => delete row
+ valid = gtk_list_store_remove (store, &iter);
+ row_deleted = TRUE;
+ g_string_append_printf (info,
+ _("ROW %d DELETED, VENDOR_DOES_NOT_EXIST: id=%s\n"),
+ row, id);
+ }
+ }
+ else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
+ {
+ // INVOICE: check, if customer exists
+ if (!gnc_search_customer_on_id
+ (gnc_get_current_book (), prev_owner_id->str))
+ {
+ // customer not found => delete row
+ valid = gtk_list_store_remove (store, &iter);
+ row_deleted = TRUE;
+ g_string_append_printf (info,
+ _("ROW %d DELETED, CUSTOMER_DOES_NOT_EXIST: id=%s\n"),
+ row, id);
+ }
+ }
+
+ // owner_id is valid
+ }
+
+ g_free (id);
+ g_free (date_opened);
+ g_free (date_posted);
+ g_free (owner_id);
+ g_free (date);
+ g_free (quantity);
+ g_free (price);
+ if (row_deleted)
+ {
+ (*deleted)++;
+ // reset all remembered values
+ g_string_assign (prev_id, "");
+ g_string_assign (prev_date_opened, "");
+ g_string_assign (prev_date_posted, "");
+ g_string_assign (prev_owner_id, "");
+ g_string_assign (prev_date, "");
+ }
+ else if (row_fixed)
+ (*fixed)++;
+
+ if (!row_deleted)
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+
+ row++;
+ }
+
+ // deallocate strings
+ g_string_free (prev_id, TRUE);
+ g_string_free (prev_date_opened, TRUE);
+ g_string_free (prev_date_posted, TRUE);
+ g_string_free (prev_owner_id, TRUE);
+ g_string_free (prev_date, TRUE);
+
+ if (info && (info->len > 0))
+ {
+ g_string_prepend (info, "\n\n");
+ g_string_prepend (info, _("These rows were deleted:"));
+ }
+}
+
+
+/***********************************************************************
+ * @todo Maybe invoice checking should be done in gnc_bi_import_fix_bis (...)
+ * rather than in here? But that is more concerned with ensuring the csv is consistent.
+ * @param GtkListStore *store
+ * @param guint *n_invoices_created
+ * @param guint *n_invoices_updated
+ * @return void
+ ***********************************************************************/
+void
+gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
+ guint * n_invoices_created,
+ guint * n_invoices_updated,
+ gchar * type, gchar * open_mode )
+{
+ gboolean valid;
+ GtkTreeIter iter;
+ gchar *id, *date_opened, *owner_id, *billing_id, *notes;
+ gchar *date, *desc, *action, *account, *quantity, *price, *disc_type,
+ *disc_how, *discount, *taxable, *taxincluded, *tax_table;
+ gchar *date_posted, *due_date, *account_posted, *memo_posted,
+ *accumulatesplits;
+ guint dummy;
+ GncInvoice *invoice;
+ GncOrder *order;
+ GncEntry *entry;
+ gint day, month, year;
+ gnc_numeric n;
+ GncOwner *owner;
+ Account *acc;
+ enum update {YES = GTK_RESPONSE_YES, NO = GTK_RESPONSE_NO} update;
+ GtkWidget *dialog;
+ Timespec today;
+ GncPluginPage *new_page;
+ InvoiceWindow *iw;
+
+ // these arguments are needed
+ g_return_if_fail (store && book);
+
+ // allow to call this function without statistics
+ if (!n_invoices_created)
+ n_invoices_created = &dummy;
+ if (!n_invoices_updated)
+ n_invoices_updated = &dummy;
+ *n_invoices_created = 0;
+ *n_invoices_updated = 0;
+
+ invoice = NULL;
+ order = NULL;
+ update = NO;
+
+ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
+ while (valid)
+ {
+ // Walk through the list, reading each row
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &id, DATE_OPENED, &date_opened, DATE_POSTED, &date_posted, // if autoposting requested
+ DUE_DATE, &due_date, // if autoposting requested
+ ACCOUNT_POSTED, &account_posted, // if autoposting requested
+ MEMO_POSTED, &memo_posted, // if autoposting requested
+ ACCU_SPLITS, &accumulatesplits, // if autoposting requested
+ OWNER_ID, &owner_id,
+ BILLING_ID, &billing_id,
+ NOTES, ¬es,
+ DATE, &date,
+ DESC, &desc,
+ ACTION, &action,
+ ACCOUNT, &account,
+ QUANTITY, &quantity,
+ PRICE, &price,
+ DISC_TYPE, &disc_type,
+ DISC_HOW, &disc_how,
+ DISCOUNT, &discount,
+ TAXABLE, &taxable,
+ TAXINCLUDED, &taxincluded,
+ TAX_TABLE, &tax_table, -1);
+
+ // TODO: Assign a new invoice number if one is absent. BUT we don't want to assign a new invoice for every line!!
+ // so we'd have to flag this up somehow or add an option in the import GUI. The former implies that we make
+ // an assumption about what the importer (person) wants to do. It seems resonable that a CSV file full of items with
+ // If an invoice exists then we add to it in this current schema.
+ // no predefined invoice number is a new invoice that's in need of a new number.
+ // This was not designed to satisfy the need for repeat invoices however, so maybe we need a another method for this, after all
+ // It should be easier to copy an invoice with a new ID than to go through all this malarky.
+ if (g_ascii_strcasecmp (type, "BILL") == 0)
+ invoice = gnc_search_bill_on_id (book, id);
+ else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
+ invoice = gnc_search_invoice_on_id (book, id);
+
+ if (!invoice)
+ {
+ // new invoice
+ invoice = gncInvoiceCreate (book);
+ gncInvoiceSetID (invoice, id);
+ owner = gncOwnerNew ();
+ if (g_ascii_strcasecmp (type, "BILL") == 0)
+ gncOwnerInitVendor (owner,
+ gnc_search_vendor_on_id (book, owner_id));
+ else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
+ gncOwnerInitCustomer (owner,
+ gnc_search_customer_on_id (book, owner_id));
+ gncInvoiceSetOwner (invoice, owner);
+ gncInvoiceSetCurrency (invoice, gncOwnerGetCurrency (owner)); // Set the invoice currency based on the owner
+ if (strlen (date_opened) != 0) // If a date is specified in CSV
+ {
+ qof_scan_date (date_opened, &day, &month, &year);
+ gncInvoiceSetDateOpened (invoice,
+ gnc_dmy2timespec (day, month, year));
+ }
+ else // If no date in CSV
+ {
+ time_t now = time (NULL);
+ Timespec now_timespec;
+ timespecFromTime_t (&now_timespec, now);
+ gncInvoiceSetDateOpened (invoice, now_timespec);
+ }
+ gncInvoiceSetBillingID (invoice, billing_id);
+ gncInvoiceSetNotes (invoice, notes);
+ gncInvoiceSetActive (invoice, TRUE);
+ //if (g_ascii_strcasecmp(type,"INVOICE"))gncInvoiceSetBillTo( invoice, billto );
+ (*n_invoices_created)++;
+ update = YES;
+
+ // open new bill / invoice in a tab, if requested
+ if (g_ascii_strcasecmp(open_mode, "ALL") == 0
+ || (g_ascii_strcasecmp(open_mode, "NOT_POSTED") == 0
+ && strlen(date_posted) == 0))
+ {
+ iw = gnc_ui_invoice_edit (invoice);
+ new_page = gnc_plugin_page_invoice_new (iw);
+ }
+ }
+// I want to warn the user that an existing billvoice exists, but not every
+// time.
+// An import can contain many lines usually referring to the same invoice.
+// NB: Posted invoices are NEVER updated.
+ else // if invoice exists
+ {
+ if (gncInvoiceIsPosted (invoice)) // Is it already posted?
+ {
+ valid =
+ gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+ continue; // If already posted then never import
+ }
+ if (update != YES) // Pop up a dialog to ask if updates are the expected action
+ {
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_YES_NO,
+ "%s",
+ _("Are you sure you have bills/invoices to update?"));
+ update = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ if (update == NO)
+ {
+ // Cleanup and leave
+ g_free (id);
+ g_free (date_opened);
+ g_free (owner_id);
+ g_free (billing_id);
+ g_free (notes);
+ g_free (date);
+ g_free (desc);
+ g_free (action);
+ g_free (account);
+ g_free (quantity);
+ g_free (price);
+ g_free (disc_type);
+ g_free (disc_how);
+ g_free (discount);
+ g_free (taxable);
+ g_free (taxincluded);
+ g_free (tax_table);
+ g_free (date_posted);
+ g_free (due_date);
+ g_free (account_posted);
+ g_free (memo_posted);
+ g_free (accumulatesplits);
+ return;
+ }
+ }
+ (*n_invoices_updated)++;
+ }
+
+
+ // add entry to invoice/bill
+ entry = gncEntryCreate (book);
+ qof_scan_date (date, &day, &month, &year);
+ {
+ GDate *date = g_date_new_dmy(day, month, year);
+ gncEntrySetDateGDate (entry, date);
+ g_date_free (date);
+ }
+ timespecFromTime_t (&today, time (NULL)); // set today to the current date
+ gncEntrySetDateEntered (entry, today);
+ gncEntrySetDescription (entry, desc);
+ gncEntrySetAction (entry, action);
+
+ n = gnc_numeric_zero ();
+ gnc_exp_parser_parse (quantity, &n, NULL);
+ gncEntrySetQuantity (entry, n);
+ acc = gnc_account_lookup_for_register (gnc_get_current_root_account (),
+ account);
+ if (g_ascii_strcasecmp (type, "BILL") == 0)
+ {
+ gncEntrySetBillAccount (entry, acc);
+ n = gnc_numeric_zero ();
+ gnc_exp_parser_parse (price, &n, NULL);
+ gncEntrySetBillPrice (entry, n);
+ gncEntrySetBillTaxable (entry, text2bool (taxable));
+ gncEntrySetBillTaxIncluded (entry, text2bool (taxincluded));
+ gncEntrySetBillTaxTable (entry,
+ gncTaxTableLookupByName (book, tax_table));
+ n = gnc_numeric_zero ();
+ gnc_exp_parser_parse (discount, &n, NULL);
+ gncBillAddEntry (invoice, entry);
+ }
+ else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
+ {
+ gncEntrySetNotes (entry, notes);
+ gncEntrySetInvAccount (entry, acc);
+ n = gnc_numeric_zero ();
+ gnc_exp_parser_parse (price, &n, NULL);
+ gncEntrySetInvPrice (entry, n);
+ gncEntrySetInvTaxable (entry, text2bool (taxable));
+ gncEntrySetInvTaxIncluded (entry, text2bool (taxincluded));
+ gncEntrySetInvTaxTable (entry,
+ gncTaxTableLookupByName (book, tax_table));
+ n = gnc_numeric_zero ();
+ gnc_exp_parser_parse (discount, &n, NULL);
+ gncEntrySetInvDiscount (entry, n);
+ gncEntrySetInvDiscountType (entry, text2disc_type (disc_type));
+ gncEntrySetInvDiscountHow (entry, text2disc_how (disc_how));
+ gncInvoiceAddEntry (invoice, entry);
+ }
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+
+ // handle auto posting of invoices
+ {
+ gchar *new_id = NULL;
+ Transaction *tnx;
+ if (valid)
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &new_id, -1);
+ if (g_strcmp0 (id, new_id) != 0)
+ {
+ // the next invoice id is different => try to autopost this invoice
+ if (qof_scan_date (date_posted, &day, &month, &year))
+ {
+ // autopost this invoice
+ Timespec d1, d2;
+ d1 = gnc_dmy2timespec (day, month, year);
+ qof_scan_date (due_date, &day, &month, &year); // obtains the due date, or leaves it at date_posted
+ d2 = gnc_dmy2timespec (day, month, year);
+ acc = gnc_account_lookup_for_register
+ (gnc_get_current_root_account (), account_posted);
+ tnx = gncInvoicePostToAccount (invoice, acc, &d1, &d2,
+ memo_posted,
+ text2bool (accumulatesplits));
+ }
+ }
+ g_free (new_id);
+ }
+
+ // cleanup
+ g_free (id);
+ g_free (date_opened);
+ g_free (owner_id);
+ g_free (billing_id);
+ g_free (notes);
+ g_free (date);
+ g_free (desc);
+ g_free (action);
+ g_free (account);
+ g_free (quantity);
+ g_free (price);
+ g_free (disc_type);
+ g_free (disc_how);
+ g_free (discount);
+ g_free (taxable);
+ g_free (taxincluded);
+ g_free (tax_table);
+ g_free (date_posted);
+ g_free (due_date);
+ g_free (account_posted);
+ g_free (memo_posted);
+ g_free (accumulatesplits);
+ }
+}
Added: gnucash/trunk/src/plugins/bi_import/dialog-bi-import.h
===================================================================
--- gnucash/trunk/src/plugins/bi_import/dialog-bi-import.h (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/dialog-bi-import.h 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,78 @@
+/*
+ * dialog-bi-import.h -- Invoice Importer core functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Tools
+ * @{
+ * @file dialog-bi-import.h
+ * @brief core import functions for invoice import plugin
+ * @author Copyright (C) 2009 Sebastian Held <sebastian.held at gmx.de>
+ * @author Mike Evans <mikee at saxicola.co.uk>
+ */
+
+#ifndef GNC_PLUGIN_BI_IMPORT_H
+#define GNC_PLUGIN_BI_IMPORT_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+// model
+enum bi_import_model_columns
+{
+ ID, DATE_OPENED, OWNER_ID, BILLING_ID, NOTES, // invoice settings
+ DATE, DESC, ACTION, ACCOUNT, QUANTITY, PRICE, DISC_TYPE, DISC_HOW, DISCOUNT, TAXABLE, TAXINCLUDED, TAX_TABLE, // entry settings
+ DATE_POSTED, DUE_DATE, ACCOUNT_POSTED, MEMO_POSTED, ACCU_SPLITS, // autopost settings
+ N_COLUMNS
+};
+
+enum _bi_import_result
+{
+ RESULT_OK,
+ RESULT_OPEN_FAILED,
+ RESULT_ERROR_IN_REGEXP,
+};
+typedef enum _bi_import_result bi_import_result;
+
+struct _bi_import_stats
+{
+ int n_imported, n_ignored;
+ GString *ignored_lines;
+};
+typedef struct _bi_import_stats bi_import_stats;
+
+
+bi_import_result
+gnc_bi_import_read_file (const gchar *filename, const gchar *parser_regexp, GtkListStore *store, guint max_rows, bi_import_stats *stats);
+
+void
+gnc_bi_import_fix_bis (GtkListStore *store, guint *fixed, guint *deleted, GString *info, gchar *type);
+
+void
+gnc_bi_import_create_bis (GtkListStore *store, QofBook *book, guint *n_invoices_created, guint *n_invoices_updated, gchar *type, gchar *open_mode);
+
+
+G_END_DECLS
+
+#endif /* GNC_PLUGIN_BI_IMPORT_H */
+
+/** @} */
Added: gnucash/trunk/src/plugins/bi_import/gnc-plugin-bi-import.c
===================================================================
--- gnucash/trunk/src/plugins/bi_import/gnc-plugin-bi-import.c (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/gnc-plugin-bi-import.c 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,115 @@
+/*
+ * gnc-plugin-bi-import.c -- Invoice Importer Plugin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-plugin-bi-import.c
+ * @brief Plugin registration of the bi-import plugin
+ * @author Copyright (C) 2009 Sebastian Held <sebastian.held at gmx.de>
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <glib/gi18n.h>
+
+#include "dialog-utils.h"
+
+#include "gnc-plugin-bi-import.h"
+#include "dialog-bi-import-gui.h"
+
+/* This static indicates the debugging module that this .o belongs to. */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+static void gnc_plugin_bi_import_class_init (GncPluginbi_importClass *klass);
+static void gnc_plugin_bi_import_init (GncPluginbi_import *plugin);
+static void gnc_plugin_bi_import_finalize (GObject *object);
+
+/* Command callbacks */
+static void gnc_plugin_bi_import_cmd_test (GtkAction *action, GncMainWindowActionData *data);
+
+#define PLUGIN_ACTIONS_NAME "gnc-plugin-bi-import-actions"
+#define PLUGIN_UI_FILENAME "gnc-plugin-bi-import-ui.xml"
+
+static GtkActionEntry gnc_plugin_actions [] =
+{
+ /* Menu Items */
+ { "ImportMenuAction", NULL, N_("_Import"), NULL, NULL, NULL },
+ { "bi_importAction", NULL, N_("Import Bills & Invoices..."), NULL, N_("Import bills and invoices from a CSV text file"), G_CALLBACK(gnc_plugin_bi_import_cmd_test) },
+};
+static guint gnc_plugin_n_actions = G_N_ELEMENTS(gnc_plugin_actions);
+
+
+/************************************************************
+ * Object Implementation *
+ ************************************************************/
+
+G_DEFINE_TYPE(GncPluginbi_import, gnc_plugin_bi_import, GNC_TYPE_PLUGIN);
+
+GncPlugin *
+gnc_plugin_bi_import_new (void)
+{
+ return GNC_PLUGIN (g_object_new (GNC_TYPE_PLUGIN_BI_IMPORT, (gchar*) NULL));
+}
+
+static void
+gnc_plugin_bi_import_class_init (GncPluginbi_importClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GncPluginClass *plugin_class = GNC_PLUGIN_CLASS(klass);
+
+ object_class->finalize = gnc_plugin_bi_import_finalize;
+
+ /* plugin info */
+ plugin_class->plugin_name = GNC_PLUGIN_BI_IMPORT_NAME;
+
+ /* widget addition/removal */
+ plugin_class->actions_name = PLUGIN_ACTIONS_NAME;
+ plugin_class->actions = gnc_plugin_actions;
+ plugin_class->n_actions = gnc_plugin_n_actions;
+ plugin_class->ui_filename = PLUGIN_UI_FILENAME;
+}
+
+static void
+gnc_plugin_bi_import_init (GncPluginbi_import *plugin)
+{
+}
+
+static void
+gnc_plugin_bi_import_finalize (GObject *object)
+{
+}
+
+/************************************************************
+ * Command Callbacks *
+ ************************************************************/
+
+static void
+gnc_plugin_bi_import_cmd_test (GtkAction *action, GncMainWindowActionData *data)
+{
+ ENTER ("action %p, main window data %p", action, data);
+ g_message ("bi_import");
+
+ gnc_plugin_bi_import_showGUI();
+
+ LEAVE (" ");
+}
Added: gnucash/trunk/src/plugins/bi_import/gnc-plugin-bi-import.h
===================================================================
--- gnucash/trunk/src/plugins/bi_import/gnc-plugin-bi-import.h (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/gnc-plugin-bi-import.h 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,80 @@
+/*
+ * gnc-plugin-bi-import.h -- Invoice Importer Plugin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Tools
+ * @{
+ * @file gnc-plugin-bi-import.h
+ * @brief Plugin registration of the bi-import module
+ * @author Copyright (C) 2009 Sebastian Held <sebastian.held at gmx.de>
+ */
+
+#ifndef GNC_PLUGIN_BI_IMPORT_H
+#define GNC_PLUGIN_BI_IMPORT_H
+
+#include <glib.h>
+
+#include "gnc-plugin.h"
+
+G_BEGIN_DECLS
+
+/* type macros */
+#define GNC_TYPE_PLUGIN_BI_IMPORT (gnc_plugin_bi_import_get_type())
+#define GNC_PLUGIN_BI_IMPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNC_TYPE_PLUGIN_BI_IMPORT, GncPluginbi_import))
+#define GNC_PLUGIN_BI_IMPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNC_TYPE_PLUGIN_BI_IMPORT, GncPluginbi_importClass))
+#define GNC_IS_PLUGIN_BI_IMPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNC_TYPE_PLUGIN_BI_IMPORT))
+#define GNC_IS_PLUGIN_BI_IMPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNC_TYPE_PLUGIN_BI_IMPORT))
+#define GNC_PLUGIN_BI_IMPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNC_TYPE_PLUGIN_BI_IMPORT, GncPluginbi_importClass))
+
+#define GNC_PLUGIN_BI_IMPORT_NAME "gnc-plugin-bi_import"
+
+/* typedefs & structures */
+typedef struct
+{
+ GncPlugin gnc_plugin;
+} GncPluginbi_import;
+
+typedef struct
+{
+ GncPluginClass gnc_plugin;
+} GncPluginbi_importClass;
+
+/* function prototypes */
+/**
+ * @return The glib runtime type of an bi_import plugin page
+ **/
+GType gnc_plugin_bi_import_get_type (void);
+
+/**
+ * @return A new GncPluginbi_import object
+ */
+GncPlugin* gnc_plugin_bi_import_new (void);
+
+/**
+ * Create a new GncPluginbi_import object and register it.
+ */
+void gnc_plugin_bi_import_create_plugin (void);
+
+G_END_DECLS
+
+/** @} */
+
+#endif /* GNC_PLUGIN_BI_IMPORT_H */
Added: gnucash/trunk/src/plugins/bi_import/gtkbuilder/Makefile.am
===================================================================
--- gnucash/trunk/src/plugins/bi_import/gtkbuilder/Makefile.am (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/gtkbuilder/Makefile.am 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,4 @@
+gtkbuilderdir = $(GNC_GTKBUILDER_DIR)
+gtkbuilder_DATA = dialog-bi-import-gui.glade
+
+EXTRA_DIST = ${gtkbuilder_DATA}
Added: gnucash/trunk/src/plugins/bi_import/gtkbuilder/dialog-bi-import-gui.glade
===================================================================
--- gnucash/trunk/src/plugins/bi_import/gtkbuilder/dialog-bi-import-gui.glade (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/gtkbuilder/dialog-bi-import-gui.glade 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,487 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkDialog" id="bi-import Dialog">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Import transactions from text file</property>
+ <property name="type_hint">dialog</property>
+ <signal name="destroy" handler="gnc_bi_import_gui_destroy_cb" swapped="no"/>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">3</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkEntry" id="entryFilename">
+ <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>
+ <signal name="changed" handler="gnc_bi_import_gui_filenameChanged_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="buttonOpen">
+ <property name="label">gtk-open</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="gnc_bi_import_gui_buttonOpen_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">1. Choose the file to import</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkAlignment" id="alignment5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBill">
+ <property name="label" translatable="yes">Bill</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup">Import bill CSV data</property>
+ <property name="tooltip_text" translatable="yes">Import bill CSV data</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0.4699999988079071</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="gnc_import_gui_type_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonInvoice">
+ <property name="label" translatable="yes">Invoice</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup">Import invoice CSV data</property>
+ <property name="tooltip_text" translatable="yes">Import invoice CSV data</property>
+ <property name="use_action_appearance">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBill</property>
+ <signal name="toggled" handler="gnc_import_gui_type_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">2. Select import type</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">3</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton1">
+ <property name="label" translatable="yes">Semicolon separated</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="gnc_bi_import_gui_option1_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton2">
+ <property name="label" translatable="yes">Comma separated</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton1</property>
+ <signal name="toggled" handler="gnc_bi_import_gui_option2_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton3">
+ <property name="label" translatable="yes">Semicolon separated with quotes</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton1</property>
+ <signal name="toggled" handler="gnc_bi_import_gui_option3_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton4">
+ <property name="label" translatable="yes">Comma separated with quotes</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton1</property>
+ <signal name="toggled" handler="gnc_bi_import_gui_option4_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton5">
+ <property name="label" translatable="yes">Custom regular expression</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton1</property>
+ <signal name="clicked" handler="gnc_bi_import_gui_option5_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">3. Select import options</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">3</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkAlignment" id="alignment3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="treeview1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">4. Preview</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">3</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkAlignment" id="alignment6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonOpenAll">
+ <property name="label" translatable="yes">Open imported documents in tabs</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="gnc_bi_import_gui_open_mode_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonOpenNotPosted">
+ <property name="label" translatable="yes">Open not yet posted documents in tabs </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonOpenAll</property>
+ <signal name="toggled" handler="gnc_bi_import_gui_open_mode_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonOpenNone">
+ <property name="label" translatable="yes">Don't open imported documents in tabs</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonOpenAll</property>
+ <signal name="toggled" handler="gnc_bi_import_gui_open_mode_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">5. Afterwards</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="helpbutton">
+ <property name="label">gtk-help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="gnc_bi_import_gui_help_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancelbutton">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="gnc_bi_import_gui_cancel_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="okbutton">
+ <property name="label">gtk-ok</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="gnc_bi_import_gui_ok_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">helpbutton</action-widget>
+ <action-widget response="-6">cancelbutton</action-widget>
+ <action-widget response="-5">okbutton</action-widget>
+ </action-widgets>
+ </object>
+</interface>
Added: gnucash/trunk/src/plugins/bi_import/ui/gnc-plugin-bi-import-ui.xml
===================================================================
--- gnucash/trunk/src/plugins/bi_import/ui/gnc-plugin-bi-import-ui.xml (rev 0)
+++ gnucash/trunk/src/plugins/bi_import/ui/gnc-plugin-bi-import-ui.xml 2012-01-21 16:22:45 UTC (rev 21871)
@@ -0,0 +1,13 @@
+<ui>
+ <menubar>
+ <placeholder name="AdditionalMenusPlaceholder">
+ <menu name="Business" action="BusinessAction">
+ <placeholder name="BusinessPlaceholderBottom">
+ <menu name="ImportMenu" action="ImportMenuAction">
+ <menuitem name="bi_import" action="bi_importAction"/>
+ </menu>
+ </placeholder>
+ </menu>
+ </placeholder>
+ </menubar>
+</ui>
More information about the gnucash-changes
mailing list