GnuCash c935c2f+
Loading...
Searching...
No Matches
dialog-customer-import-gui.c
1/*
2 * dialog-customer-import-gui.c --
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, contact:
16 *
17 * Free Software Foundation Voice: +1-617-542-5942
18 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
19 * Boston, MA 02110-1301, USA gnu@gnu.org
20 */
21
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32
33#include <glib/gi18n.h>
34
35#include "gnc-ui.h"
36#include "gnc-ui-util.h"
37#include "gnc-component-manager.h"
38#include "dialog-utils.h"
39#include "gnc-gui-query.h"
40#include "gnc-file.h"
43
45{
46 GtkWidget *dialog;
47 GtkWidget *tree_view;
48 GtkWidget *entryFilename;
49 GtkListStore *store;
50 gint component_id;
51 GString *regexp;
52 gchar *type;
53 QofBook *book;
54};
55
56// callback routines
57void gnc_customer_import_gui_ok_cb (GtkWidget *widget, gpointer data);
58void gnc_customer_import_gui_cancel_cb (GtkWidget *widget, gpointer data);
59void gnc_customer_import_gui_help_cb (GtkWidget *widget, gpointer data);
60void gnc_customer_import_gui_destroy_cb (GtkWidget *widget, gpointer data);
61static void gnc_customer_import_gui_close_handler (gpointer user_data);
62void gnc_customer_import_gui_buttonOpen_cb (GtkWidget *widget, gpointer data);
63void gnc_customer_import_gui_filenameChanged_cb (GtkWidget *widget, gpointer data);
64void gnc_customer_import_gui_option1_cb (GtkWidget *widget, gpointer data);
65void gnc_customer_import_gui_option2_cb (GtkWidget *widget, gpointer data);
66void gnc_customer_import_gui_option3_cb (GtkWidget *widget, gpointer data);
67void gnc_customer_import_gui_option4_cb (GtkWidget *widget, gpointer data);
68void gnc_customer_import_gui_option5_cb (GtkWidget *widget, gpointer data);
69void gnc_customer_import_gui_type_cb (GtkWidget *widget, gpointer data);
70
71CustomerImportGui *
73{
74 CustomerImportGui *gui;
75 //gktbuilderXML *xml;
76 GtkBuilder *builder;
77 GList *glist;
78 GtkCellRenderer *renderer;
79 GtkTreeViewColumn *column;
80
81 // if window exists already, activate it
82 glist = gnc_find_gui_components ("dialog-customer-import-gui", NULL, NULL);
83 if (glist)
84 {
85 // window found
86 gui = g_list_nth_data (glist, 0);
87 g_list_free (glist);
88 gtk_window_present (GTK_WINDOW(gui->dialog));
89 return gui;
90 }
91
92 // create new window
93 gui = g_new0 (CustomerImportGui, 1);
94
95 builder = gtk_builder_new();
96 gnc_builder_add_from_file (builder, "dialog-customer-import-gui.glade", "customer_import_dialog");
97 gui->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "customer_import_dialog"));
98 gui->tree_view = GTK_WIDGET(gtk_builder_get_object (builder, "treeview1"));
99 gui->entryFilename = GTK_WIDGET(gtk_builder_get_object (builder, "entryFilename"));
100 gui->type = "CUSTOMER"; // Set a default type to import
101
102 // Set the name for this dialog so it can be easily manipulated with css
103 gtk_widget_set_name (GTK_WIDGET(gui->dialog), "gnc-id-customer-import");
104 gnc_widget_style_context_add_class (GTK_WIDGET(gui->dialog), "gnc-class-imports");
105
106 gtk_window_set_transient_for (GTK_WINDOW (gui->dialog), parent);
107
108 gui->regexp = g_string_new ( "^(\\x{FEFF})?(?<id>[^;]*);(?<company>[^;]*);(?<name>[^;]*);(?<addr1>[^;]*);(?<addr2>[^;]*);(?<addr3>[^;]*);(?<addr4>[^;]*);(?<phone>[^;]*);(?<fax>[^;]*);(?<email>[^;]*);(?<notes>[^;]*);(?<shipname>[^;]*);(?<shipaddr1>[^;]*);(?<shipaddr2>[^;]*);(?<shipaddr3>[^;]*);(?<shipaddr4>[^;]*);(?<shipphone>[^;]*);(?<shipfax>[^;]*);(?<shipemail>[^;]*)$");
109 gui->book = gnc_get_current_book();
110
111 // create model and bind to view
112 gui->store = gtk_list_store_new (CI_N_COLUMNS,
113 G_TYPE_STRING, G_TYPE_STRING,
114 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
115 G_TYPE_STRING,
116 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
117 gtk_tree_view_set_model( GTK_TREE_VIEW(gui->tree_view), GTK_TREE_MODEL(gui->store) );
118#define CREATE_COLUMN(description,column_id) \
119 renderer = gtk_cell_renderer_text_new (); \
120 column = gtk_tree_view_column_new_with_attributes (description, renderer, "text", column_id, NULL); \
121 gtk_tree_view_column_set_resizable (column, TRUE); \
122 gtk_tree_view_append_column (GTK_TREE_VIEW (gui->tree_view), column);
123 CREATE_COLUMN (_("ID"), CI_ID);
124 CREATE_COLUMN (_("Company"), CI_COMPANY);
125 CREATE_COLUMN (_("Name"), CI_NAME);
126 CREATE_COLUMN (_("Address 1"), CI_ADDR1);
127 CREATE_COLUMN (_("Address 2"), CI_ADDR2);
128 CREATE_COLUMN (_("Address 3"), CI_ADDR3);
129 CREATE_COLUMN (_("Address 4"), CI_ADDR4);
130 CREATE_COLUMN (_("Phone"), CI_PHONE);
131 CREATE_COLUMN (_("Fax"), CI_FAX);
132 CREATE_COLUMN (_("Email"), CI_EMAIL);
133 CREATE_COLUMN (_("Notes"), CI_NOTES);
134 CREATE_COLUMN (_("Shipping Name"), CI_SHIPNAME);
135 CREATE_COLUMN (_("Shipping Address 1"), CI_SHIPADDR1);
136 CREATE_COLUMN (_("Shipping Address 2"), CI_SHIPADDR2);
137 CREATE_COLUMN (_("Shipping Address 3"), CI_SHIPADDR3);
138 CREATE_COLUMN (_("Shipping Address 4"), CI_SHIPADDR4);
139 CREATE_COLUMN (_("Shipping Phone"), CI_SHIPPHONE);
140 CREATE_COLUMN (_("Shipping Fax"), CI_SHIPFAX);
141 CREATE_COLUMN (_("Shipping Email"), CI_SHIPEMAIL);
142
143 gui->component_id = gnc_register_gui_component ("dialog-customer-import-gui",
144 NULL,
145 gnc_customer_import_gui_close_handler,
146 gui);
147
148 /* Setup signals */
149 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, gui);
150 gtk_widget_show_all ( gui->dialog );
151 g_object_unref (G_OBJECT (builder));
152 return gui;
153}
154
155static gchar *
156gnc_plugin_customer_import_getFilename (GtkWindow *parent)
157{
158 // prepare file import dialog
159 gchar *filename;
160 GList *filters;
161 GtkFileFilter *filter;
162 filters = NULL;
163 filter = gtk_file_filter_new ();
164 gtk_file_filter_set_name (filter, "comma separated values (*.csv)");
165 gtk_file_filter_add_pattern (filter, "*.csv");
166 filters = g_list_append( filters, filter );
167 filter = gtk_file_filter_new ();
168 gtk_file_filter_set_name (filter, "text files (*.txt)");
169 gtk_file_filter_add_pattern (filter, "*.txt");
170 filters = g_list_append( filters, filter );
171 filename = gnc_file_dialog(parent,
172 _("Import Customers from CSV"), filters, NULL, GNC_FILE_DIALOG_IMPORT);
173
174 return filename;
175}
176
177void
178gnc_customer_import_gui_ok_cb (GtkWidget *widget, gpointer data)
179{
180 CustomerImportGui *gui = data;
181 gchar *filename = g_strdup( gtk_entry_get_text( GTK_ENTRY(gui->entryFilename) ) );
182 customer_import_stats stats;
183 customer_import_result res;
184 guint n_fixed, n_deleted, n_customers_created, n_customers_updated;
185 gchar *cv_type_text;
186
187 // import
188 if (g_ascii_strcasecmp (gui->type, "CUSTOMER") == 0) cv_type_text = _("customers");
189 else cv_type_text = _("vendors");
190
191 gtk_list_store_clear (gui->store);
192 res = gnc_customer_import_read_file (filename, gui->regexp->str, gui->store, 0, &stats);
193 if (res == CI_RESULT_OK)
194 {
195 gnc_customer_import_fix_customers (gui->store, &n_fixed, &n_deleted, gui->type);
196 gnc_customer_import_create_customers (gui->store, gui->book, &n_customers_created, &n_customers_updated, gui->type);
197 gnc_info_dialog (GTK_WINDOW (gui->dialog), _("Import results:\n%i lines were ignored\n%i lines imported:\n %u %s fixed\n %u %s ignored (not fixable)\n\n %u %s created\n %u %s updated (based on id)"), \
198 stats.n_ignored, stats.n_imported, n_fixed, cv_type_text, n_deleted, cv_type_text, n_customers_created, cv_type_text, n_customers_updated, cv_type_text);
199
200 if (stats.n_ignored > 0)
201 gnc_info2_dialog (gui->dialog, _("These lines were ignored during import"), stats.ignored_lines->str);
202
203 g_string_free (stats.ignored_lines, TRUE);
204 gnc_close_gui_component (gui->component_id);
205 }
206 else if (res == CI_RESULT_OPEN_FAILED)
207 {
208 gnc_error_dialog (GTK_WINDOW (gui->dialog), _("The input file can not be opened."));
209 }
210 else if (res == CI_RESULT_ERROR_IN_REGEXP)
211 {
212 //gnc_error_dialog (GTK_WINDOW (gui->dialog), "The regular expression is faulty:\n\n%s", stats.err->str);
213 }
214}
215
216void
217gnc_customer_import_gui_cancel_cb (GtkWidget *widget, gpointer data)
218{
219 CustomerImportGui *gui = data;
220
221 gnc_close_gui_component (gui->component_id);
222}
223
224void
225gnc_customer_import_gui_help_cb (GtkWidget *widget, gpointer data)
226{
227 CustomerImportGui *gui = data;
228 gnc_gnome_help (GTK_WINDOW(gui->dialog), DF_GUIDE, DL_IMPORT_CUST);
229}
230
231static void
232gnc_customer_import_gui_close_handler (gpointer user_data)
233{
234 CustomerImportGui *gui = user_data;
235
236 gtk_widget_destroy (gui->dialog);
237 // gui has already been freed by this point.
238 // gui->dialog = NULL;
239}
240
241void
242gnc_customer_import_gui_destroy_cb (GtkWidget *widget, gpointer data)
243{
244 CustomerImportGui *gui = data;
245
246 gnc_suspend_gui_refresh ();
247 gnc_unregister_gui_component (gui->component_id);
248 gnc_resume_gui_refresh ();
249
250 g_object_unref (gui->store);
251 g_string_free (gui->regexp, TRUE);
252 g_free (gui);
253}
254
255void gnc_customer_import_gui_buttonOpen_cb (GtkWidget *widget, gpointer data)
256{
257 gchar *filename;
258 CustomerImportGui *gui = data;
259
260 filename = gnc_plugin_customer_import_getFilename (gnc_ui_get_gtk_window (widget));
261 if (filename)
262 {
263 gtk_entry_set_text( GTK_ENTRY(gui->entryFilename), filename );
264 g_free( filename );
265 }
266}
267
268void gnc_customer_import_gui_filenameChanged_cb (GtkWidget *widget, gpointer data)
269{
270 CustomerImportGui *gui = data;
271 gchar *filename = g_strdup( gtk_entry_get_text( GTK_ENTRY(gui->entryFilename) ) );
272
273 // generate preview
274 gtk_list_store_clear (gui->store);
275 gnc_customer_import_read_file (filename, gui->regexp->str, gui->store, 10, NULL);
276
277 g_free( filename );
278}
279// Semicolon separated.
280void gnc_customer_import_gui_option1_cb (GtkWidget *widget, gpointer data)
281{
282 CustomerImportGui *gui = data;
283 if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
284 return;
285 g_string_assign (gui->regexp, "^(\\x{FEFF})?(?<id>[^;]*);(?<company>[^;]*);(?<name>[^;]*);(?<addr1>[^;]*);(?<addr2>[^;]*);(?<addr3>[^;]*);(?<addr4>[^;]*);(?<phone>[^;]*);(?<fax>[^;]*);(?<email>[^;]*);(?<notes>[^;]*);(?<shipname>[^;]*);(?<shipaddr1>[^;]*);(?<shipaddr2>[^;]*);(?<shipaddr3>[^;]*);(?<shipaddr4>[^;]*);(?<shipphone>[^;]*);(?<shipfax>[^;]*);(?<shipemail>[^;]*)$");
286 gnc_customer_import_gui_filenameChanged_cb (gui->entryFilename, gui);
287}
288// Comma separated.
289void gnc_customer_import_gui_option2_cb (GtkWidget *widget, gpointer data)
290{
291 CustomerImportGui *gui = data;
292 if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
293 return;
294 g_string_assign (gui->regexp, "^(\\x{FEFF})?(?<id>[^,]*),(?<company>[^,]*),(?<name>[^,]*),(?<addr1>[^,]*),(?<addr2>[^,]*),(?<addr3>[^,]*),(?<addr4>[^,]*),(?<phone>[^,]*),(?<fax>[^,]*),(?<email>[^,]*),(?<notes>[^,]*),(?<shipname>[^,]*),(?<shipaddr1>[^,]*),(?<shipaddr2>[^,]*),(?<shipaddr3>[^,]*),(?<shipaddr4>[^,]*),(?<shipphone>[^,]*),(?<shipfax>[^,]*),(?<shipemail>[^,]*)$");
295 gnc_customer_import_gui_filenameChanged_cb (gui->entryFilename, gui);
296}
297// Semicolon separated with quoted strings.
298void gnc_customer_import_gui_option3_cb (GtkWidget *widget, gpointer data)
299{
300 CustomerImportGui *gui = data;
301 if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
302 return;
303 g_string_assign (gui->regexp, "^(\\x{FEFF})?((?<id>[^\";]*)|\"(?<id>[^\"]*)\");((?<company>[^\";]*)|\"(?<company>[^\"]*)\");((?<name>[^\";]*)|\"(?<name>[^\"]*)\");((?<addr1>[^\";]*)|\"(?<addr1>[^\"]*)\");((?<addr2>[^\";]*)|\"(?<addr2>[^\"]*)\");((?<addr3>[^\";]*)|\"(?<addr3>[^\"]*)\");((?<addr4>[^\";]*)|\"(?<addr4>[^\"]*)\");((?<phone>[^\";]*)|\"(?<phone>[^\"]*)\");((?<fax>[^\";]*)|\"(?<fax>[^\"]*)\");((?<email>[^\";]*)|\"(?<email>[^\"]*)\");((?<notes>[^\";]*)|\"(?<notes>[^\"]*)\");((?<shipname>[^\";]*)|\"(?<shipname>[^\"]*)\");((?<shipaddr1>[^\";]*)|\"(?<shipaddr1>[^\"]*)\");((?<shipaddr2>[^\";]*)|\"(?<shipaddr2>[^\"]*)\");((?<shipaddr3>[^\";]*)|\"(?<shipaddr3>[^\"]*)\");((?<shipaddr4>[^\";]*)|\"(?<shipaddr4>[^\"]*)\");((?<shipphone>[^\";]*)|\"(?<shipphone>[^\"]*)\");((?<shipfax>[^\";]*)|\"(?<shipfax>[^\"]*)\");((?<shipemail>[^;]*)|\"(?<shipemail>[^\"]*)\")$");
304 gnc_customer_import_gui_filenameChanged_cb (gui->entryFilename, gui);
305}
306// Comma separated with quoted strings.
307void gnc_customer_import_gui_option4_cb (GtkWidget *widget, gpointer data)
308{
309 CustomerImportGui *gui = data;
310 if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
311 return;
312 g_string_assign (gui->regexp, "^(\\x{FEFF})?((?<id>[^\",]*)|\"(?<id>[^\"]*)\"),((?<company>[^\",]*)|\"(?<company>[^\"]*)\"),((?<name>[^\",]*)|\"(?<name>[^\"]*)\"),((?<addr1>[^\",]*)|\"(?<addr1>[^\"]*)\"),((?<addr2>[^\",]*)|\"(?<addr2>[^\"]*)\"),((?<addr3>[^\",]*)|\"(?<addr3>[^\"]*)\"),((?<addr4>[^\",]*)|\"(?<addr4>[^\"]*)\"),((?<phone>[^\",]*)|\"(?<phone>[^\"]*)\"),((?<fax>[^\",]*)|\"(?<fax>[^\"]*)\"),((?<email>[^\",]*)|\"(?<email>[^\"]*)\"),((?<notes>[^\",]*)|\"(?<notes>[^\"]*)\"),((?<shipname>[^\",]*)|\"(?<shipname>[^\"]*)\"),((?<shipaddr1>[^\",]*)|\"(?<shipaddr1>[^\"]*)\"),((?<shipaddr2>[^\",]*)|\"(?<shipaddr2>[^\"]*)\"),((?<shipaddr3>[^\",]*)|\"(?<shipaddr3>[^\"]*)\"),((?<shipaddr4>[^\",]*)|\"(?<shipaddr4>[^\"]*)\"),((?<shipphone>[^\",]*)|\"(?<shipphone>[^\"]*)\"),((?<shipfax>[^\",]*)|\"(?<shipfax>[^\"]*)\"),((?<shipemail>[^\",]*)|\"(?<shipemail>[^\"]*)\")$");
313 gnc_customer_import_gui_filenameChanged_cb (gui->entryFilename, gui);
314}
315void gnc_customer_import_gui_option5_cb (GtkWidget *widget, gpointer data)
316{
317 CustomerImportGui *gui = data;
318 gchar *temp;
319 if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
320 return;
321 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);
322 if (temp)
323 {
324 g_string_assign (gui->regexp, temp);
325 g_free (temp);
326 gnc_customer_import_gui_filenameChanged_cb (gui->entryFilename, gui);
327 }
328}
329
330
331
332
333/*****************************************************************
334 * Set whether we are importing a Customer or Vendor
335 * ****************************************************************/
336void gnc_customer_import_gui_type_cb (GtkWidget *widget, gpointer data)
337{
338 CustomerImportGui *gui = data;
339 const gchar *name;
340 if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
341 return;
342 name = gtk_buildable_get_name(GTK_BUILDABLE(widget));
343 if (name)
344 {
345 if (g_ascii_strcasecmp(name, "radiobutton_customer") == 0)gui->type = "CUSTOMER";
346 else if (g_ascii_strcasecmp(name, "radiobutton_vendor") == 0)gui->type = "VENDOR";
347 }
348 //printf ("TYPE set to, %s\n",gui->type); // DEBUG
349
350}
GUI handling for customer import plugin.
core import functions for customer import plugin
utility functions for the GnuCash UI
GtkWindow * gnc_ui_get_gtk_window(GtkWidget *widget)
Get a pointer to the widget's immediate top level GtkWindow.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
CustomerImportGui * gnc_plugin_customer_import_showGUI(GtkWindow *parent)
File chooser.
QofBook reference.
Definition qofbook-p.hpp:47