GnuCash  5.6-150-g038405b370+
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"
41 #include "dialog-customer-import.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
57 void gnc_customer_import_gui_ok_cb (GtkWidget *widget, gpointer data);
58 void gnc_customer_import_gui_cancel_cb (GtkWidget *widget, gpointer data);
59 void gnc_customer_import_gui_help_cb (GtkWidget *widget, gpointer data);
60 void gnc_customer_import_gui_destroy_cb (GtkWidget *widget, gpointer data);
61 static void gnc_customer_import_gui_close_handler (gpointer user_data);
62 void gnc_customer_import_gui_buttonOpen_cb (GtkWidget *widget, gpointer data);
63 void gnc_customer_import_gui_filenameChanged_cb (GtkWidget *widget, gpointer data);
64 void gnc_customer_import_gui_option1_cb (GtkWidget *widget, gpointer data);
65 void gnc_customer_import_gui_option2_cb (GtkWidget *widget, gpointer data);
66 void gnc_customer_import_gui_option3_cb (GtkWidget *widget, gpointer data);
67 void gnc_customer_import_gui_option4_cb (GtkWidget *widget, gpointer data);
68 void gnc_customer_import_gui_option5_cb (GtkWidget *widget, gpointer data);
69 void gnc_customer_import_gui_type_cb (GtkWidget *widget, gpointer data);
70 
71 CustomerImportGui *
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 
155 static gchar *
156 gnc_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 
177 void
178 gnc_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 
216 void
217 gnc_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 
224 void
225 gnc_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 
231 static void
232 gnc_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 
241 void
242 gnc_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 
255 void 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 
268 void 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.
280 void 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.
289 void 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.
298 void 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.
307 void 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 }
315 void 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  * ****************************************************************/
336 void 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 }
CustomerImportGui * gnc_plugin_customer_import_showGUI(GtkWindow *parent)
File chooser.
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&#39;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&#39;s yelp for linux, and open to a given link within a gi...
GUI handling for customer import plugin.