GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
assistant-csv-export.c
Go to the documentation of this file.
1 /*******************************************************************\
2  * assistant-csv-export.c -- An assistant for exporting Accounts *
3  * and Transactions to a file *
4  * *
5  * Copyright (C) 2012 Robert Fewell *
6  * *
7  * This program is free software; you can redistribute it and/or *
8  * modify it under the terms of the GNU General Public License as *
9  * published by the Free Software Foundation; either version 2 of *
10  * the License, or (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License*
18  * along with this program; if not, contact: *
19  * *
20  * Free Software Foundation Voice: +1-617-542-5942 *
21  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
22  * Boston, MA 02110-1301, USA [email protected] *
23 \********************************************************************/
28 #include "config.h"
29 
30 #include <gtk/gtk.h>
31 #include <glib/gi18n.h>
32 
33 #include "gnc-ui.h"
34 #include "gnc-uri-utils.h"
35 #include "gnc-component-manager.h"
36 #include "gnc-date-edit.h"
37 #include "gnc-prefs.h"
38 #include "gnc-tree-view-account.h"
39 #include "dialog-utils.h"
40 #include "Query.h"
41 #include "Transaction.h"
42 
43 #include "assistant-utils.h"
44 #include "assistant-csv-export.h"
45 #include "csv-tree-export.h"
47 
48 #define GNC_PREFS_GROUP "dialogs.export.csv"
49 #define GNC_PREF_PANED_POS "paned-position"
50 #define ASSISTANT_CSV_EXPORT_CM_CLASS "assistant-csv-export"
51 
52 /* This static indicates the debugging module that this .o belongs to. */
53 static QofLogModule log_module = GNC_MOD_ASSISTANT;
54 
55 /*************************************************************************/
56 
57 void csv_export_assistant_prepare (GtkAssistant *assistant, GtkWidget *page, gpointer user_data);
58 void csv_export_assistant_finish (GtkAssistant *gtkassistant, gpointer user_data);
59 void csv_export_assistant_cancel (GtkAssistant *gtkassistant, gpointer user_data);
60 void csv_export_assistant_close (GtkAssistant *gtkassistant, gpointer user_data);
61 
62 void csv_export_assistant_start_page_prepare (GtkAssistant *assistant, gpointer user_data);
63 void csv_export_assistant_account_page_prepare (GtkAssistant *gtkassistant, gpointer user_data);
64 void csv_export_assistant_file_page_prepare (GtkAssistant *assistant, gpointer user_data);
65 void csv_export_assistant_finish_page_prepare (GtkAssistant *assistant, gpointer user_data);
66 void csv_export_assistant_summary_page_prepare (GtkAssistant *assistant, gpointer user_data);
67 
68 void csv_export_quote_cb (GtkToggleButton *button, gpointer user_data);
69 void csv_export_sep_cb (GtkWidget *radio, gpointer user_data);
70 void csv_export_custom_entry_cb (GtkWidget *widget, gpointer user_data);
71 
72 void csv_export_show_range_cb (GtkRadioButton *button, gpointer user_data);
73 void csv_export_start_date_cb (GtkWidget *radio, gpointer user_data);
74 void csv_export_end_date_cb (GtkWidget *radio, gpointer user_data);
75 
76 void csv_export_file_chooser_confirm_cb (GtkWidget *button, CsvExportInfo *info);
77 
78 static const gchar *finish_tree_string = N_(
79  /* Translators: %s is the file name string. */
80  "The account tree will be exported to the file '%s' when you click 'Apply'.\n\n"
81  "You can also verify your selections by clicking on 'Back' or 'Cancel' to Abort Export.\n");
82 
83 static const gchar *finish_trans_string = N_(
84  /* Translators: %s is the file name string and %u the number of accounts. */
85  "When you click 'Apply', the transactions will be exported to the file '%s' and"
86  " the number of accounts exported will be %u.\n\n"
87  "You can also verify your selections by clicking on 'Back' or 'Cancel' to Abort Export.\n");
88 
89 static const gchar *start_tree_string = N_(
90  "This assistant will help you export the Account Tree to a file\n"
91  " with the separator specified below.\n\n"
92  "Select the settings you require for the file and then click 'Forward' to proceed"
93  " or 'Cancel' to Abort Export.\n");
94 
95 static const gchar *start_trans_string = N_(
96  "This assistant will help you export the Transactions to a file\n"
97  " with the separator specified below.\n\n"
98  "There will be multiple rows for each transaction and may"
99  " require further manipulation to get them in a format you can use.\n\n"
100  "Each Transaction will appear once in the export and will be listed in"
101  " the order the accounts were processed\n\n"
102  "Select the settings you require for the file and then click 'Forward' to proceed"
103  " or 'Cancel' to Abort Export.\n");
104 
105 
106 /**************************************************
107  * csv_export_file_chooser_confirm_cb
108  *
109  * call back for ok button in file chooser widget
110  **************************************************/
111 void
112 csv_export_file_chooser_confirm_cb (GtkWidget *button, CsvExportInfo *info)
113 {
114  GtkAssistant *assistant = GTK_ASSISTANT(info->window);
115  gint num = gtk_assistant_get_current_page (assistant);
116  GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
117 
118  gchar *file_name;
119 
120  gtk_assistant_set_page_complete (assistant, page, FALSE);
121 
122  file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(info->file_chooser));
123 
124  if (file_name)
125  {
126  if (g_file_test (file_name, G_FILE_TEST_EXISTS))
127  {
128  const char *format = _("The file %s already exists. "
129  "Are you sure you want to overwrite it?");
130 
131  /* if user says cancel, we should break out */
132  if (!gnc_verify_dialog (NULL, FALSE, format, file_name))
133  return;
134  }
135 
136  info->file_name = g_strdup (file_name);
137  gtk_assistant_set_page_complete (assistant, page, TRUE);
138  }
139 
140  if (file_name)
141  {
142  gchar *filepath = gnc_uri_get_path (file_name);
143  gchar *filedir = g_path_get_dirname (filepath);
144  info->starting_dir = g_strdup (filedir);
145  g_free (filedir);
146  g_free (filepath);
147  }
148  g_free (file_name);
149 
150  DEBUG("file_name selected is %s", info->file_name);
151  DEBUG("starting directory is %s", info->starting_dir);
152 
153  /* Step to next page if page is complete */
154  if(gtk_assistant_get_page_complete (assistant, page))
155  gtk_assistant_set_current_page (assistant, num + 1);
156 }
157 
158 
159 /*******************************************************
160  * csv_export_sep_cb
161  *
162  * call back for type of separartor required
163  *******************************************************/
164 void csv_export_sep_cb (GtkWidget *radio, gpointer user_data)
165 {
166  CsvExportInfo *info = user_data;
167  const gchar *name;
168 
169  GtkAssistant *assistant = GTK_ASSISTANT(info->window);
170  gint num = gtk_assistant_get_current_page (assistant);
171  GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
172 
173  if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
174  {
175  LEAVE("1st callback of pair. Defer to 2nd callback.");
176  return;
177  }
178 
179  name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
180 
181  gtk_widget_set_sensitive (info->custom_entry, FALSE);
182  info->use_custom = FALSE;
183  gtk_assistant_set_page_complete (assistant, page, TRUE);
184 
185  if (g_strcmp0 (name, "comma_radio") == 0)
186  info->separator_str = ",";
187  if (g_strcmp0 (name, "colon_radio") == 0)
188  info->separator_str = ":";
189  if (g_strcmp0 (name, "semicolon_radio") == 0)
190  info->separator_str = ";";
191 
192  if (g_strcmp0 (name, "custom_radio") == 0)
193  {
194  gtk_widget_set_sensitive (info->custom_entry, TRUE);
195  info->use_custom = TRUE;
196  if (gtk_entry_get_text_length (GTK_ENTRY(info->custom_entry)) == 0)
197  gtk_assistant_set_page_complete (assistant, page, FALSE);
198  }
199 }
200 
201 
202 /*******************************************************
203  * csv_export_quote_cb
204  *
205  * call back for use of quotes
206  *******************************************************/
207 void csv_export_quote_cb (GtkToggleButton *button, gpointer user_data)
208 {
209  CsvExportInfo *info = user_data;
210 
211  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button)))
212  info->use_quotes = TRUE;
213  else
214  info->use_quotes = FALSE;
215 }
216 
217 
218 /*******************************************************
219  * csv_export_custom_entry_cb
220  *
221  * call back for custom separator
222  *******************************************************/
223 void csv_export_custom_entry_cb (GtkWidget *widget, gpointer user_data)
224 {
225  CsvExportInfo *info = user_data;
226  const gchar *custom_str;
227 
228  GtkAssistant *assistant = GTK_ASSISTANT(info->window);
229  gint num = gtk_assistant_get_current_page (assistant);
230  GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
231 
232  custom_str = gtk_entry_get_text (GTK_ENTRY(info->custom_entry));
233  info->separator_str = strdup (custom_str);
234 
235  if (info->use_custom == TRUE && gtk_entry_get_text_length (GTK_ENTRY(info->custom_entry)) == 0)
236 
237  gtk_assistant_set_page_complete (assistant, page, FALSE);
238  else
239  gtk_assistant_set_page_complete (assistant, page, TRUE);
240 }
241 
242 
243 /*******************************************************
244  * load_settings
245  *
246  * load the default settings for the assistant
247  *******************************************************/
248 static
249 void load_settings (CsvExportInfo *info)
250 {
251  info->use_quotes = FALSE;
252  info->separator_str = ",";
253  info->file_name = NULL;
254  info->starting_dir = NULL;
255  info->trans_list = NULL;
256 
257  /* The default directory for the user to select files. */
258  info->starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP);
259 }
260 
261 /* =============================================================== */
262 
263 /*******************************************************
264  * csv_export_cursor_changed_cb
265  *
266  * call back for cursor selection in account tree
267  *******************************************************/
268 static void
269 csv_export_cursor_changed_cb (GtkWidget *widget, gpointer user_data)
270 {
271  CsvExportInfo *info = user_data;
272  GncTreeViewAccount *account_tree;
273  Account *account;
274  gint num_children;
275 
276  account_tree = GNC_TREE_VIEW_ACCOUNT (info->csva.account_treeview);
277  account = gnc_tree_view_account_get_cursor_account (account_tree);
278  if (!account)
279  {
280  gtk_widget_set_sensitive (info->csva.select_button, FALSE);
281  return;
282  }
283  num_children = gnc_tree_view_account_count_children (account_tree, account);
284  gtk_widget_set_sensitive (info->csva.select_button, num_children > 0);
285 }
286 
287 
288 /*******************************************************
289  * show_acct_type_accounts
290  *
291  * show required accounts in account tree
292  *******************************************************/
293 static void
294 show_acct_type_accounts (CsvExportInfo *info)
295 {
296  GncTreeViewAccount *tree;
297  AccountViewInfo Viewinfo;
298  GNCAccountType type;
299 
300  tree = GNC_TREE_VIEW_ACCOUNT (info->csva.account_treeview);
301 
302  gnc_tree_view_account_get_view_info (tree, &Viewinfo);
303 
304  for (type = 0; type < NUM_ACCOUNT_TYPES; type++) /* from Account.h */
305  {
306  Viewinfo.include_type[type] = ((type == ACCT_TYPE_BANK) ||
307  (type == ACCT_TYPE_CASH) ||
308  (type == ACCT_TYPE_CREDIT) ||
309  (type == ACCT_TYPE_ASSET) ||
310  (type == ACCT_TYPE_LIABILITY) ||
311  (type == ACCT_TYPE_STOCK) ||
312  (type == ACCT_TYPE_MUTUAL) ||
313  (type == ACCT_TYPE_INCOME) ||
314  (type == ACCT_TYPE_EXPENSE) ||
315  (type == ACCT_TYPE_EQUITY) ||
316  (type == ACCT_TYPE_RECEIVABLE)||
317  (type == ACCT_TYPE_PAYABLE) ||
318  (type == ACCT_TYPE_ROOT) ||
319  (type == ACCT_TYPE_TRADING));
320  }
321  gnc_tree_view_account_set_view_info (tree, &Viewinfo);
322  csv_export_cursor_changed_cb (GTK_WIDGET(tree), info);
323 }
324 
325 
326 /*******************************************************
327  * update_accounts_tree
328  *
329  * update the account tree
330  *******************************************************/
331 static int
332 update_accounts_tree (CsvExportInfo *info)
333 {
334  GncTreeViewAccount *tree;
335  GtkTreeSelection* selection;
336  GtkWidget *label;
337  int num_accounts;
338  char *string;
339 
340  tree = GNC_TREE_VIEW_ACCOUNT(info->csva.account_treeview);
341  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree));
342  num_accounts = gtk_tree_selection_count_selected_rows (selection);
343 
344  label = info->csva.num_acct_label;
345 
346  string = g_strdup_printf ("%d", num_accounts);
347  gtk_label_set_text (GTK_LABEL (label), string);
348  g_free (string);
349 
350  return num_accounts;
351 }
352 
353 
354 /*******************************************************
355  * csv_export_account_changed_cb
356  *
357  * update account list after selection changed
358  *******************************************************/
359 static void
360 csv_export_account_changed_cb (GtkTreeSelection *selection,
361  gpointer user_data)
362 {
363  CsvExportInfo *info = user_data;
364  GtkAssistant *assistant = GTK_ASSISTANT(info->window);
365  gint num = gtk_assistant_get_current_page (assistant);
366  GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
367 
368  GncTreeViewAccount *view;
369 
370  g_return_if_fail(GTK_IS_TREE_SELECTION(selection));
371 
372  info->csva.num_accounts = update_accounts_tree (info);
373 
374  /* Enable the Forward Assistant Button if we have accounts */
375  if (info->csva.num_accounts > 0)
376  gtk_assistant_set_page_complete (assistant, page, TRUE);
377  else
378  gtk_assistant_set_page_complete (assistant, page, FALSE);
379 
380  view = GNC_TREE_VIEW_ACCOUNT(info->csva.account_treeview);
381  info->csva.account_list = gnc_tree_view_account_get_selected_accounts (view);
382 }
383 
384 
385 /*******************************************************
386  * csv_export_select_subaccounts_clicked_cb
387  *
388  * select all the sub accounts
389  *******************************************************/
390 static void
391 csv_export_select_subaccounts_clicked_cb (GtkWidget *widget, gpointer user_data)
392 {
393  CsvExportInfo *info = user_data;
394  GncTreeViewAccount *account_tree;
395  Account *account;
396 
397  account_tree = GNC_TREE_VIEW_ACCOUNT (info->csva.account_treeview);
398  account = gnc_tree_view_account_get_cursor_account (account_tree);
399  if (!account)
400  return;
401 
402  gnc_tree_view_account_select_subaccounts (account_tree, account);
403 
404  gtk_widget_grab_focus (info->csva.account_treeview);
405 }
406 
407 /* =============================================================== */
408 
409 /*******************************************************
410  * get_filter_times
411  *
412  * get the start and end times from the dialog
413  *******************************************************/
414 static void
415 get_filter_times (CsvExportInfo *info)
416 {
417  time64 time_val;
418 
419  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csvd.start_date_choose)))
420  {
421  time_val = gnc_date_edit_get_date (GNC_DATE_EDIT(info->csvd.start_date));
422  time_val = gnc_time64_get_day_start (time_val);
423  info->csvd.start_time = time_val;
424  }
425  else
426  {
427  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csvd.start_date_today)))
428  info->csvd.start_time = gnc_time64_get_today_start();
429  else
430  info->csvd.start_time = 0;
431  }
432 
433  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csvd.end_date_choose)))
434  {
435  time_val = gnc_date_edit_get_date (GNC_DATE_EDIT(info->csvd.end_date));
436  time_val = gnc_time64_get_day_end (time_val);
437  info->csvd.end_time = time_val;
438  }
439  else
440  {
441  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csvd.start_date_today)))
442  info->csvd.end_time = gnc_time64_get_today_end();
443  else
444  info->csvd.end_time = gnc_time (NULL);
445  }
446 }
447 
448 
449 /*******************************************************
450  * csv_export_show_range_cb
451  *
452  * call back for show range button
453  *******************************************************/
454 void
455 csv_export_show_range_cb (GtkRadioButton *button, gpointer user_data)
456 {
457  CsvExportInfo *info = user_data;
458  gboolean active;
459 
460  g_return_if_fail (GTK_IS_RADIO_BUTTON(button));
461 
462  active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
463  gtk_widget_set_sensitive (info->csvd.table, active);
464 }
465 
466 
467 /*******************************************************
468  * csv_export_date_changed_cb
469  *
470  * call back for when a date changes
471  *******************************************************/
472 static void
473 csv_export_date_changed_cb (GtkWidget *w, gpointer user_data)
474 {
475  CsvExportInfo *info = user_data;
476 
477  get_filter_times (info);
478 }
479 
480 
481 /*******************************************************
482  * csv_export_start_date_cb
483  *
484  * call back for when the start date changes
485  *******************************************************/
486 void
487 csv_export_start_date_cb (GtkWidget *radio, gpointer user_data)
488 {
489  CsvExportInfo *info = user_data;
490  const gchar *name;
491  gboolean active;
492 
493  g_return_if_fail (GTK_IS_RADIO_BUTTON(radio));
494 
495  if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
496  {
497  LEAVE("1st callback of pair. Defer to 2nd callback.");
498  return;
499  }
500 
501  name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
502  active = (g_strcmp0 (name, "start_date_choose") == 0 ? 1 : 0 );
503  gtk_widget_set_sensitive (info->csvd.start_date, active);
504  get_filter_times (info);
505 }
506 
507 
508 /*******************************************************
509  * csv_export_end_date_cb
510  *
511  * call back for when the end date changes
512  *******************************************************/
513 void
514 csv_export_end_date_cb (GtkWidget *radio, gpointer user_data)
515 {
516  CsvExportInfo *info = user_data;
517  const gchar *name;
518  gboolean active;
519 
520  g_return_if_fail (GTK_IS_RADIO_BUTTON(radio));
521 
522  if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
523  {
524  LEAVE("1st callback of pair. Defer to 2nd callback.");
525  return;
526  }
527 
528  name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
529  active = (g_strcmp0 (name, "end_date_choose") == 0 ? 1 : 0 );
530  gtk_widget_set_sensitive (info->csvd.end_date, active);
531  get_filter_times (info);
532 }
533 
534 
535 /*******************************************************************
536  * get_earliest_in_book
537  *
538  * Find the earliest date occuring in the book. Do this by making
539  * a query and sorting by date. Since the truncated sort returns
540  * only the *last* search results, sort in decreasing order.
541  *******************************************************************/
542 static time64
543 get_earliest_in_book (QofBook *book)
544 {
545  QofQuery *q;
546  GSList *p1, *p2;
547  GList *res;
548  time64 earliest;
549 
550  q = qof_query_create_for (GNC_ID_SPLIT);
552  qof_query_set_book (q, book);
553 
554  /* Sort by transaction date */
555  p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED);
556  p1 = g_slist_prepend (p1, SPLIT_TRANS);
557  p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT);
558  qof_query_set_sort_order (q, p1, p2, NULL);
559 
560  /* Reverse the sort order */
561  qof_query_set_sort_increasing (q, FALSE, FALSE, FALSE);
562 
563  /* Run the query, find the earliest transaction date */
564  res = qof_query_run (q);
565 
566  if (res)
567  {
568  earliest = xaccQueryGetEarliestDateFound (q);
569  }
570  else
571  {
572  /* If no results, we don't want to bomb totally */
573  earliest = gnc_time (0);
574  }
575 
576  qof_query_destroy (q);
577  return earliest;
578 }
579 
580 
581 /* =============================================================== */
582 
583 
584 /*******************************************************
585  * Assistant page prepare functions
586  *******************************************************/
587 void
588 csv_export_assistant_start_page_prepare (GtkAssistant *assistant,
589  gpointer user_data)
590 {
591  CsvExportInfo *info = user_data;
592  gint num = gtk_assistant_get_current_page (assistant);
593  GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
594 
595  /* Set Start page text */
596  if (info->export_type == XML_EXPORT_TREE)
597  gtk_label_set_text (GTK_LABEL(info->start_label), gettext (start_tree_string));
598  else
599  gtk_label_set_text (GTK_LABEL(info->start_label), gettext (start_trans_string));
600 
601  /* Enable the Assistant Buttons */
602  gtk_assistant_set_page_complete (assistant, page, TRUE);
603 }
604 
605 
606 void
607 csv_export_assistant_account_page_prepare (GtkAssistant *assistant,
608  gpointer user_data)
609 {
610  CsvExportInfo *info = user_data;
611  gint num = gtk_assistant_get_current_page (assistant);
612  GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
613 
614  /* Enable the Forward Assistant Button if we have accounts */
615  if (info->csva.num_accounts > 0)
616  gtk_assistant_set_page_complete (assistant, page, TRUE);
617  else
618  gtk_assistant_set_page_complete (assistant, page, FALSE);
619 }
620 
621 
622 void
623 csv_export_assistant_file_page_prepare (GtkAssistant *assistant,
624  gpointer user_data)
625 {
626  CsvExportInfo *info = user_data;
627  gint num = gtk_assistant_get_current_page (assistant);
628  GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
629 
630  /* Set the default directory */
631  if (info->starting_dir)
632  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(info->file_chooser), info->starting_dir);
633  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(info->file_chooser), "");
634 
635  /* Disable the Forward Assistant Button */
636  gtk_assistant_set_page_complete (assistant, page, FALSE);
637 }
638 
639 
640 void
641 csv_export_assistant_finish_page_prepare (GtkAssistant *assistant,
642  gpointer user_data)
643 {
644  CsvExportInfo *info = user_data;
645  gint num = gtk_assistant_get_current_page (assistant);
646  GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
647  gchar *text;
648 
649  /* Set Finish page text */
650  if (info->export_type == XML_EXPORT_TREE)
651  text = g_strdup_printf (gettext (finish_tree_string), info->file_name);
652  else
653  text = g_strdup_printf (gettext (finish_trans_string), info->file_name, info->csva.num_accounts);
654 
655  gtk_label_set_text (GTK_LABEL(info->finish_label), text);
656  g_free (text);
657 
658  /* Enable the Assistant Buttons */
659  gtk_assistant_set_page_complete (assistant, page, TRUE);
660 }
661 
662 
663 void
664 csv_export_assistant_summary_page_prepare (GtkAssistant *assistant,
665  gpointer user_data)
666 {
667  CsvExportInfo *info = user_data;
668  gchar *text, *mtext;
669  gnc_set_default_directory (GNC_PREFS_GROUP, info->starting_dir);
670 
671  if (info->failed)
672  text = _("There was a problem with the export, this could be due to lack of space, "
673  "permissions or unable to access folder. Check the trace file for further logging!\n"
674  "You may need to enable debugging.\n");
675  else
676  text = _("File exported successfully!\n");
677 
678  mtext = g_strdup_printf ("<span size=\"medium\"><b>%s</b></span>", text);
679 
680  gtk_label_set_markup (GTK_LABEL(info->summary_label), mtext);
681 
682  g_free (mtext);
683 }
684 
685 
686 void
687 csv_export_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
688  gpointer user_data)
689 {
690  CsvExportInfo *info = user_data;
691 
692  if (page == info->start_page)
693  csv_export_assistant_start_page_prepare (assistant, user_data);
694  else if (page == info->account_page)
695  csv_export_assistant_account_page_prepare (assistant, user_data);
696  else if (page == info->file_page)
697  csv_export_assistant_file_page_prepare (assistant, user_data);
698  else if (page == info->finish_label)
699  csv_export_assistant_finish_page_prepare (assistant, user_data);
700  else if (page == info->summary_label)
701  csv_export_assistant_summary_page_prepare (assistant, user_data);
702  else
703  g_assert_not_reached();
704 }
705 
706 
707 /*******************************************************
708  * Assistant call back functions
709  *******************************************************/
710 static void
711 csv_export_assistant_destroy_cb (GtkObject *object, gpointer user_data)
712 {
713  CsvExportInfo *info = user_data;
714  gnc_unregister_gui_component_by_data (ASSISTANT_CSV_EXPORT_CM_CLASS, info);
715  g_free (info);
716 }
717 
718 void
719 csv_export_assistant_cancel (GtkAssistant *assistant, gpointer user_data)
720 {
721  CsvExportInfo *info = user_data;
722  gnc_close_gui_component_by_data (ASSISTANT_CSV_EXPORT_CM_CLASS, info);
723 }
724 
725 void
726 csv_export_assistant_close (GtkAssistant *assistant, gpointer user_data)
727 {
728  CsvExportInfo *info = user_data;
729  gnc_close_gui_component_by_data (ASSISTANT_CSV_EXPORT_CM_CLASS, info);
730 }
731 
732 void
733 csv_export_assistant_finish (GtkAssistant *assistant, gpointer user_data)
734 {
735  CsvExportInfo *info = user_data;
736 
737  if (info->export_type == XML_EXPORT_TREE)
738  csv_tree_export (info);
739  else
741 }
742 
743 static void
744 csv_export_close_handler (gpointer user_data)
745 {
746  CsvExportInfo *info = user_data;
747 
748  g_free (info->file_name);
749  g_free (info->starting_dir);
750 
751  gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->window));
752  gtk_widget_destroy (info->window);
753 }
754 
755 /*******************************************************
756  * Create the Assistant
757  *******************************************************/
758 static GtkWidget *
759 csv_export_assistant_create (CsvExportInfo *info)
760 {
761  GtkBuilder *builder;
762  GtkWidget *window;
763  GtkWidget *box, *h_box;
764  GtkWidget *button;
765  GtkWidget *table, *hbox;
766  time64 start_time, end_time;
767 
768  builder = gtk_builder_new();
769  gnc_builder_add_from_file (builder , "assistant-csv-export.glade", "CSV Export Assistant");
770  window = GTK_WIDGET(gtk_builder_get_object (builder, "CSV Export Assistant"));
771  info->window = window;
772 
773  /* Set the assistant colors */
774  gnc_assistant_set_colors (GTK_ASSISTANT (info->window));
775 
776  /* Load default settings */
777  load_settings (info);
778 
779  /* Start Page */
780  info->start_page = GTK_WIDGET(gtk_builder_get_object(builder, "start_page"));
781  info->start_label = GTK_WIDGET(gtk_builder_get_object(builder, "start_label"));
782  info->custom_entry = GTK_WIDGET(gtk_builder_get_object(builder, "custom_entry"));
783  gtk_widget_set_sensitive (info->custom_entry, FALSE);
784 
785  /* Account Page */
786  info->account_page = GTK_WIDGET(gtk_builder_get_object(builder, "account_page"));
787 
788  if (info->export_type == XML_EXPORT_TREE)
789  gtk_widget_destroy (info->account_page);
790  else
791  {
792  GtkTreeView *tree_view;
793  GtkTreeSelection *selection;
794  GtkWidget *box, *label;
795 
796  info->csva.acct_info = GTK_WIDGET(gtk_builder_get_object (builder, "acct_info_vbox"));
797  info->csva.num_acct_label = GTK_WIDGET(gtk_builder_get_object (builder, "num_accounts_label"));
798 
799  tree_view = gnc_tree_view_account_new (FALSE);
800  info->csva.account_treeview = GTK_WIDGET(tree_view);
801 
802  selection = gtk_tree_view_get_selection (tree_view);
803  gtk_tree_selection_set_mode (selection, GTK_SELECTION_EXTENDED);
804  g_signal_connect (G_OBJECT(selection), "changed",
805  G_CALLBACK(csv_export_account_changed_cb), info);
806 
807  gtk_widget_show (info->csva.account_treeview);
808  box = GTK_WIDGET(gtk_builder_get_object (builder, "account_scroll"));
809  gtk_container_add (GTK_CONTAINER(box), info->csva.account_treeview);
810 
811  label = GTK_WIDGET(gtk_builder_get_object (builder, "accounts_label"));
812  gtk_label_set_mnemonic_widget (GTK_LABEL(label), GTK_WIDGET(tree_view));
813 
814  /* select subaccounts button */
815  button = GTK_WIDGET(gtk_builder_get_object (builder, "select_subaccounts_button"));
816  info->csva.select_button = button;
817 
818  g_signal_connect (G_OBJECT(button), "clicked",
819  G_CALLBACK(csv_export_select_subaccounts_clicked_cb), info);
820  g_signal_connect (G_OBJECT(info->csva.account_treeview), "cursor_changed",
821  G_CALLBACK(csv_export_cursor_changed_cb), info);
822 
823  /* Set the date info */
824  button = GTK_WIDGET(gtk_builder_get_object (builder, "show_range"));
825 
826  /* Earliest and Latest in Book */
827  start_time = get_earliest_in_book (gnc_get_current_book());
828  end_time = gnc_time (NULL);
829 
830  info->csvd.start_time = start_time;
831  info->csvd.end_time = end_time;
832  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), FALSE);
833 
834  table = GTK_WIDGET(gtk_builder_get_object (builder, "select_range_table"));
835  info->csvd.table = table;
836  gtk_widget_set_sensitive (GTK_WIDGET(table), FALSE);
837 
838  info->csvd.start_date_choose = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_choose"));
839  info->csvd.start_date_today = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_today"));
840  info->csvd.end_date_choose = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_choose"));
841  info->csvd.end_date_today = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_today"));
842 
843  /* Start date info */
844  info->csvd.start_date = gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE);
845  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_hbox"));
846  gtk_box_pack_start (GTK_BOX(hbox), info->csvd.start_date, TRUE, TRUE, 0);
847  gtk_widget_show (info->csvd.start_date);
848  gnc_date_edit_set_time (GNC_DATE_EDIT(info->csvd.start_date), start_time);
849  g_signal_connect (G_OBJECT(info->csvd.start_date), "date-changed",
850  G_CALLBACK(csv_export_date_changed_cb), info);
851 
852  /* End date info */
853  info->csvd.end_date = gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE);
854  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_hbox"));
855  gtk_box_pack_start (GTK_BOX(hbox), info->csvd.end_date, TRUE, TRUE, 0);
856  gtk_widget_show (info->csvd.end_date);
857  gnc_date_edit_set_time (GNC_DATE_EDIT(info->csvd.end_date), end_time);
858  g_signal_connect (G_OBJECT (info->csvd.end_date), "date-changed",
859  G_CALLBACK (csv_export_date_changed_cb), info);
860 
861  /* Load Accounts */
862  show_acct_type_accounts (info);
863  update_accounts_tree (info);
864  }
865 
866  /* File chooser Page */
867  info->file_page = GTK_WIDGET(gtk_builder_get_object(builder, "file_page"));
868  info->file_chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_SAVE);
869  button = gtk_button_new_from_stock (GTK_STOCK_OK);
870  gtk_widget_set_size_request (button, 100, -1);
871  gtk_widget_show (button);
872  h_box = gtk_hbox_new (TRUE, 0);
873  gtk_box_pack_start(GTK_BOX(h_box), button, FALSE, FALSE, 0);
874  gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(info->file_chooser), h_box);
875  g_signal_connect (G_OBJECT(button), "clicked",
876  G_CALLBACK(csv_export_file_chooser_confirm_cb), info);
877 
878  box = GTK_WIDGET(gtk_builder_get_object (builder, "file_page"));
879  gtk_box_pack_start (GTK_BOX (box), info->file_chooser, TRUE, TRUE, 6);
880  gtk_widget_show (info->file_chooser);
881 
882  /* Finish Page */
883  info->finish_label = GTK_WIDGET(gtk_builder_get_object (builder, "end_page"));
884 
885  /* Summary Page */
886  info->summary_label = GTK_WIDGET(gtk_builder_get_object (builder, "summary_page"));
887 
888  g_signal_connect (G_OBJECT(window), "destroy",
889  G_CALLBACK(csv_export_assistant_destroy_cb), info);
890 
891  gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->window));
892  if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_GEOMETRY))
893  {
894  GObject *object = gtk_builder_get_object (builder, "paned");
895  gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_PANED_POS, object, "position");
896  }
897 
898  gtk_builder_connect_signals (builder, info);
899  g_object_unref (G_OBJECT(builder));
900  return window;
901 }
902 
903 
904 /********************************************************************\
905  * gnc_file_csv_export *
906  * opens up a assistant to export accounts or transactions based on *
907  * the type. *
908  * Args: export_type *
909  * Return: nothing *
910 \********************************************************************/
911 void
912 gnc_file_csv_export (CsvExportType export_type)
913 {
914  CsvExportInfo *info;
915 
916  info = g_new0 (CsvExportInfo, 1);
917  info->export_type = export_type;
918  csv_export_assistant_create (info);
919  gnc_register_gui_component (ASSISTANT_CSV_EXPORT_CM_CLASS,
920  NULL, csv_export_close_handler,
921  info);
922  gtk_widget_show_all (info->window);
923  gnc_window_adjust_for_screen (GTK_WINDOW(info->window));
924 }
void gnc_tree_view_account_get_view_info(GncTreeViewAccount *account_view, AccountViewInfo *avi)
time64 gnc_time64_get_today_start(void)
GList * gnc_tree_view_account_get_selected_accounts(GncTreeViewAccount *view)
Account * gnc_tree_view_account_get_cursor_account(GncTreeViewAccount *view)
time64 gnc_time64_get_today_end(void)
void qof_query_set_sort_order(QofQuery *q, QofQueryParamList *primary_sort_params, QofQueryParamList *secondary_sort_params, QofQueryParamList *tertiary_sort_params)
CSV Export Account Tree.
#define DEBUG(format, args...)
Definition: qoflog.h:255
void csv_transactions_export(CsvExportInfo *info)
gchar * gnc_uri_get_path(const gchar *uri)
void gnc_tree_view_account_set_view_info(GncTreeViewAccount *account_view, AccountViewInfo *avi)
void qof_query_set_sort_increasing(QofQuery *q, gboolean prim_inc, gboolean sec_inc, gboolean tert_inc)
struct _QofQuery QofQuery
Definition: qofquery.h:90
void qof_query_set_max_results(QofQuery *q, int n)
CSV Export Assistant.
void gnc_tree_view_account_select_subaccounts(GncTreeViewAccount *view, Account *account)
void qof_query_destroy(QofQuery *q)
void gnc_prefs_bind(const gchar *group, const gchar *pref_name, gpointer object, const gchar *property)
Definition: gnc-prefs.c:186
GtkTreeView implementation for gnucash account tree.
void csv_tree_export(CsvExportInfo *info)
time64 gnc_time64_get_day_end(time64 time_val)
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
void qof_query_set_book(QofQuery *q, QofBook *book)
void gnc_file_csv_export(CsvExportType export_type)
GNCAccountType
Definition: Account.h:96
CSV Export Transactions.
Generic api to store and retrieve preferences.
time64 gnc_time64_get_day_start(time64 time_val)
GList * qof_query_run(QofQuery *query)
gint gnc_tree_view_account_count_children(GncTreeViewAccount *view, Account *account)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:196
#define LEAVE(format, args...)
Definition: qoflog.h:271
#define QUERY_DEFAULT_SORT
Definition: qofquery.h:106
time64 gnc_time(time64 *tbuf)
get the current local time
Utility functions for convert uri in separate components and back.
gint64 time64
Definition: gnc-date.h:83
API for Transactions and Splits (journal entries)
const gchar * QofLogModule
Definition: qofid.h:89