GnuCash c935c2f+
Loading...
Searching...
No Matches
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 gnu@gnu.org *
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"
39#include "dialog-utils.h"
40#include "Query.h"
41#include "Transaction.h"
42
44#include "csv-tree-export.h"
46
47#define GNC_PREFS_GROUP "dialogs.export.csv"
48#define GNC_PREF_PANED_POS "paned-position"
49#define ASSISTANT_CSV_EXPORT_CM_CLASS "assistant-csv-export"
50
51/* This static indicates the debugging module that this .o belongs to. */
52static QofLogModule log_module = GNC_MOD_ASSISTANT;
53
54/*************************************************************************/
55
56void csv_export_assistant_prepare (GtkAssistant *assistant, GtkWidget *page, gpointer user_data);
57void csv_export_assistant_finish (GtkAssistant *gtkassistant, gpointer user_data);
58void csv_export_assistant_cancel (GtkAssistant *gtkassistant, gpointer user_data);
59void csv_export_assistant_close (GtkAssistant *gtkassistant, gpointer user_data);
60
61void csv_export_assistant_start_page_prepare (GtkAssistant *assistant, gpointer user_data);
62void csv_export_assistant_account_page_prepare (GtkAssistant *gtkassistant, gpointer user_data);
63void csv_export_assistant_file_page_prepare (GtkAssistant *assistant, gpointer user_data);
64void csv_export_assistant_finish_page_prepare (GtkAssistant *assistant, gpointer user_data);
65void csv_export_assistant_summary_page_prepare (GtkAssistant *assistant, gpointer user_data);
66
67void csv_export_quote_cb (GtkToggleButton *button, gpointer user_data);
68void csv_export_simple_cb (GtkToggleButton *button, gpointer user_data);
69void csv_export_sep_cb (GtkWidget *radio, gpointer user_data);
70void csv_export_custom_entry_cb (GtkWidget *widget, gpointer user_data);
71
72void csv_export_show_range_cb (GtkRadioButton *button, gpointer user_data);
73void csv_export_start_date_cb (GtkWidget *radio, gpointer user_data);
74void csv_export_end_date_cb (GtkWidget *radio, gpointer user_data);
75
76void csv_export_file_chooser_file_activated_cb (GtkFileChooser *chooser, CsvExportInfo *info);
77void csv_export_file_chooser_selection_changed_cb (GtkFileChooser *chooser, CsvExportInfo *info);
78
79static const gchar *start_tree_string = N_(
80 "This assistant will help you export the Account Tree to a file "
81 "with the separator specified below.\n\n"
82 "Select the settings you require for the file and then click \"Next\" "
83 "to proceed or \"Cancel\" to abort the export.\n");
84
85static const gchar *start_trans_common_string = N_(
86 /* Translators: %s is one of the following paragraphs about rows/transaction. */
87 "This assistant will help you export the Transactions to a file "
88 "with the separator specified below.\n\n"
89 "%s\n\n"
90 "While a transaction may have splits in several of the selected accounts "
91 "it will only be exported once. It will appear under the first processed "
92 "account it has a split in.\n\n"
93 "The Price/Rate output format is controlled by the preference\n"
94 "\"Numbers, Date, Time\"->\"Force Prices to display as decimals\".\n\n"
95 "Select the settings you require for the file and then click \"Next\" "
96 "to proceed or \"Cancel\" to abort the export.\n");
97
98static const gchar *start_trans_multi_string = N_(
99 "There will be multiple rows for each transaction with each row "
100 "representing one split.");
101
102static const gchar *start_trans_simple_string = N_(
103 "There will be one row for each transaction, equivalent to a single row "
104 "in a register in 'Basic Ledger' mode. As such some transfer detail "
105 "could be lost.");
106
107static const gchar *finish_tree_string = N_(
108 /* Translators: %s is the file name. */
109 "The account tree will be exported to the file '%s' when you click \"Apply\".\n\n"
110 "You can also verify your selections by clicking on \"Back\" or \"Cancel\" to abort the export.\n");
111
112static const gchar *finish_trans_string = N_(
113 /* Translators: %s is the file name and %u the number of accounts. */
114 "When you click \"Apply\", the transactions will be exported to the file '%s' "
115 "and the number of accounts exported will be %u.\n\n"
116 "You can also verify your selections by clicking on \"Back\" or \"Cancel\" to abort the export.\n");
117
118static const gchar *finish_trans_search_gl_string = N_(
119 /* Translators: %s is the file name. */
120 "When you click \"Apply\", the transactions will be exported to the file '%s'.\n\n"
121 "You can also verify your selections by clicking on \"Back\" or \"Cancel\" to abort the export.\n");
122
123
124/**************************************************
125 * csv_export_assistant_check_filename
126 *
127 * check for a valid filename for GtkFileChooser callbacks
128 **************************************************/
129static gboolean
130csv_export_assistant_check_filename (GtkFileChooser *chooser,
131 CsvExportInfo *info)
132{
133 gchar *file_name = gtk_file_chooser_get_filename (chooser);
134
135 /* Test for a valid filename and not a directory */
136 if (file_name && !g_file_test (file_name, G_FILE_TEST_IS_DIR))
137 {
138 gchar *filepath = gnc_uri_get_path (file_name);
139 gchar *filedir = g_path_get_dirname (filepath);
140
141 g_free (info->file_name);
142 info->file_name = g_strdup (file_name);
143
144 g_free (info->starting_dir);
145 info->starting_dir = g_strdup (filedir);
146
147 g_free (filedir);
148 g_free (filepath);
149 g_free (file_name);
150
151 DEBUG("file_name selected is %s", info->file_name);
152 DEBUG("starting directory is %s", info->starting_dir);
153 return TRUE;
154 }
155 g_free (file_name);
156 return FALSE;
157}
158
159
160/**************************************************
161 * csv_export_file_chooser_file_activated_cb
162 *
163 * call back for GtkFileChooser file-activated signal
164 **************************************************/
165void
166csv_export_file_chooser_file_activated_cb (GtkFileChooser *chooser,
167 CsvExportInfo *info)
168{
169 GtkAssistant *assistant = GTK_ASSISTANT(info->assistant);
170 gtk_assistant_set_page_complete (assistant, info->file_page, FALSE);
171
172 /* Test for a valid filename and not a directory */
173 if (csv_export_assistant_check_filename (chooser, info))
174 {
175 gtk_assistant_set_page_complete (assistant, info->file_page, TRUE);
176 gtk_assistant_next_page (assistant);
177 }
178}
179
180
181/**************************************************
182 * csv_export_file_chooser_selection_changed_cb
183 *
184 * call back for GtkFileChooser widget
185 **************************************************/
186void
187csv_export_file_chooser_selection_changed_cb (GtkFileChooser *chooser,
188 CsvExportInfo *info)
189{
190 GtkAssistant *assistant = GTK_ASSISTANT(info->assistant);
191
192 /* Enable the "Next" button based on a valid filename */
193 gtk_assistant_set_page_complete (assistant, info->file_page,
194 csv_export_assistant_check_filename (chooser, info));
195}
196
197
198/*******************************************************
199 * csv_export_sep_cb
200 *
201 * call back for type of separator required
202 *******************************************************/
203void
204csv_export_sep_cb (GtkWidget *radio, gpointer user_data)
205{
206 CsvExportInfo *info = user_data;
207 GtkAssistant *assistant = GTK_ASSISTANT(info->assistant);
208 const gchar *name;
209
210 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
211 {
212 LEAVE("1st callback of pair. Defer to 2nd callback.");
213 return;
214 }
215
216 name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
217
218 gtk_widget_set_sensitive (info->custom_entry, FALSE);
219 info->use_custom = FALSE;
220 gtk_assistant_set_page_complete (assistant, info->start_page, TRUE);
221
222 if (g_strcmp0 (name, "comma_radio") == 0)
223 info->separator_str = ",";
224 if (g_strcmp0 (name, "colon_radio") == 0)
225 info->separator_str = ":";
226 if (g_strcmp0 (name, "semicolon_radio") == 0)
227 info->separator_str = ";";
228
229 if (g_strcmp0 (name, "custom_radio") == 0)
230 {
231 gtk_widget_set_sensitive (info->custom_entry, TRUE);
232 info->use_custom = TRUE;
233 if (gtk_entry_get_text_length (GTK_ENTRY(info->custom_entry)) == 0)
234 gtk_assistant_set_page_complete (assistant, info->start_page, FALSE);
235 }
236}
237
238
239/*******************************************************
240 * csv_export_quote_cb
241 *
242 * call back for use of quotes
243 *******************************************************/
244void
245csv_export_quote_cb (GtkToggleButton *button, gpointer user_data)
246{
247 CsvExportInfo *info = user_data;
248
249 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button)))
250 info->use_quotes = TRUE;
251 else
252 info->use_quotes = FALSE;
253}
254
255/*******************************************************
256 * csv_export_simple_cb
257 *
258 * call back for use of simple_layout
259 *******************************************************/
260void
261csv_export_simple_cb (GtkToggleButton *button, gpointer user_data)
262{
263 CsvExportInfo *info = user_data;
264
265 info->simple_layout = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
266
267 gchar *msg = NULL;
268 if (info->simple_layout)
269 msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_simple_string));
270 else
271 msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_multi_string));
272
273 gtk_label_set_text (GTK_LABEL(info->start_label), msg);
274 g_free (msg);
275}
276
277/*******************************************************
278 * csv_export_custom_entry_cb
279 *
280 * call back for custom separator
281 *******************************************************/
282void
283csv_export_custom_entry_cb (GtkWidget *widget, gpointer user_data)
284{
285 CsvExportInfo *info = user_data;
286 GtkAssistant *assistant = GTK_ASSISTANT(info->assistant);
287 const gchar *custom_str;
288
289 custom_str = gtk_entry_get_text (GTK_ENTRY(info->custom_entry));
290 info->separator_str = strdup (custom_str);
291
292 if (info->use_custom == TRUE && gtk_entry_get_text_length (GTK_ENTRY(info->custom_entry)) == 0)
293 gtk_assistant_set_page_complete (assistant, info->start_page, FALSE);
294 else
295 gtk_assistant_set_page_complete (assistant, info->start_page, TRUE);
296}
297
298
299/*******************************************************
300 * load_settings
301 *
302 * load the default settings for the assistant
303 *******************************************************/
304static void
305load_settings (CsvExportInfo *info)
306{
307 info->use_quotes = FALSE;
308 info->simple_layout = FALSE;
309 info->separator_str = ",";
310 info->file_name = NULL;
311 info->starting_dir = NULL;
312
313 /* The default directory for the user to select files. */
314 info->starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP);
315}
316
317/* =============================================================== */
318
319/*******************************************************
320 * csv_export_cursor_changed_cb
321 *
322 * call back for cursor selection in account tree
323 *******************************************************/
324static void
325csv_export_cursor_changed_cb (GtkWidget *widget, gpointer user_data)
326{
327 CsvExportInfo *info = user_data;
328 GncTreeViewAccount *account_tree;
329 Account *account;
330 gint num_children;
331
332 account_tree = GNC_TREE_VIEW_ACCOUNT (info->csva.account_treeview);
333 account = gnc_tree_view_account_get_cursor_account (account_tree);
334 if (!account)
335 {
336 gtk_widget_set_sensitive (info->csva.select_button, FALSE);
337 return;
338 }
339 num_children = gnc_tree_view_account_count_children (account_tree, account);
340 gtk_widget_set_sensitive (info->csva.select_button, num_children > 0);
341}
342
343
344/*******************************************************
345 * show_acct_type_accounts
346 *
347 * show required accounts in account tree
348 *******************************************************/
349static void
350show_acct_type_accounts (CsvExportInfo *info)
351{
352 GncTreeViewAccount *tree;
353 AccountViewInfo Viewinfo;
354 GNCAccountType type;
355
356 tree = GNC_TREE_VIEW_ACCOUNT (info->csva.account_treeview);
357
358 gnc_tree_view_account_get_view_info (tree, &Viewinfo);
359
360 for (type = 0; type < NUM_ACCOUNT_TYPES; type++) /* from Account.h */
361 {
362 Viewinfo.include_type[type] = ((type == ACCT_TYPE_BANK) ||
363 (type == ACCT_TYPE_CASH) ||
364 (type == ACCT_TYPE_CREDIT) ||
365 (type == ACCT_TYPE_ASSET) ||
366 (type == ACCT_TYPE_LIABILITY) ||
367 (type == ACCT_TYPE_STOCK) ||
368 (type == ACCT_TYPE_MUTUAL) ||
369 (type == ACCT_TYPE_INCOME) ||
370 (type == ACCT_TYPE_EXPENSE) ||
371 (type == ACCT_TYPE_EQUITY) ||
372 (type == ACCT_TYPE_RECEIVABLE)||
373 (type == ACCT_TYPE_PAYABLE) ||
374 (type == ACCT_TYPE_ROOT) ||
375 (type == ACCT_TYPE_TRADING));
376 }
377 gnc_tree_view_account_set_view_info (tree, &Viewinfo);
378 csv_export_cursor_changed_cb (GTK_WIDGET(tree), info);
379}
380
381
382/*******************************************************
383 * update_accounts_tree
384 *
385 * update the account tree
386 *******************************************************/
387static void
388update_accounts_tree (CsvExportInfo *info)
389{
390 GncTreeViewAccount *tree;
391 GtkTreeSelection* selection;
392 GtkWidget *label;
393 int num_accounts;
394 char *string;
395
396 tree = GNC_TREE_VIEW_ACCOUNT(info->csva.account_treeview);
397 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree));
398 num_accounts = gtk_tree_selection_count_selected_rows (selection);
399
400 label = info->csva.num_acct_label;
401 string = g_strdup_printf (_("Accounts Selected: %d"), num_accounts);
402 gtk_label_set_text (GTK_LABEL (label), string);
403 g_free (string);
404}
405
406
407/*******************************************************
408 * csv_export_account_changed_cb
409 *
410 * update account list after selection changed
411 *******************************************************/
412static void
413csv_export_account_changed_cb (GtkTreeSelection *selection,
414 gpointer user_data)
415{
416
417 g_return_if_fail(GTK_IS_TREE_SELECTION(selection));
418
419 CsvExportInfo *info = user_data;
420
421 GncTreeViewAccount *view = GNC_TREE_VIEW_ACCOUNT(info->csva.account_treeview);
422 info->csva.account_list = gnc_tree_view_account_get_selected_accounts (view);
423
424 /* Enable the "Next" Assistant Button if we have accounts */
425 GtkAssistant *assistant = GTK_ASSISTANT(info->assistant);
426 if (g_list_length (info->csva.account_list) > 0)
427 gtk_assistant_set_page_complete (assistant, info->account_page, TRUE);
428 else
429 gtk_assistant_set_page_complete (assistant, info->account_page, FALSE);
430
431 update_accounts_tree (info);
432}
433
434
435/*******************************************************
436 * csv_export_select_all_clicked_cb
437 *
438 * select all the accounts
439 *******************************************************/
440static void
441csv_export_select_all_clicked_cb (GtkWidget *widget, gpointer user_data)
442{
443 CsvExportInfo *info = user_data;
444 GtkTreeSelection *selection = gtk_tree_view_get_selection
445 (GTK_TREE_VIEW (info->csva.account_treeview));
446
447 gtk_tree_view_expand_all (GTK_TREE_VIEW (info->csva.account_treeview));
448 gtk_tree_selection_select_all (selection);
449
450 gtk_widget_grab_focus (info->csva.account_treeview);
451}
452
453
454/*******************************************************
455 * csv_export_select_subaccounts_clicked_cb
456 *
457 * select all the sub accounts
458 *******************************************************/
459static void
460csv_export_select_subaccounts_clicked_cb (GtkWidget *widget, gpointer user_data)
461{
462 CsvExportInfo *info = user_data;
463 GncTreeViewAccount *account_tree;
464 Account *account;
465
466 account_tree = GNC_TREE_VIEW_ACCOUNT (info->csva.account_treeview);
467 account = gnc_tree_view_account_get_cursor_account (account_tree);
468 if (!account)
469 return;
470
471 gnc_tree_view_account_select_subaccounts (account_tree, account);
472
473 gtk_widget_grab_focus (info->csva.account_treeview);
474}
475
476/* =============================================================== */
477
478/*******************************************************
479 * get_filter_times
480 *
481 * get the start and end times from the dialog
482 *******************************************************/
483static void
484get_filter_times (CsvExportInfo *info)
485{
486 time64 time_val;
487
488 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csvd.start_date_choose)))
489 {
490 time_val = gnc_date_edit_get_date (GNC_DATE_EDIT(info->csvd.start_date));
491 time_val = gnc_time64_get_day_start (time_val);
492 info->csvd.start_time = time_val;
493 }
494 else
495 {
496 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csvd.start_date_today)))
497 info->csvd.start_time = gnc_time64_get_today_start();
498 else
499 info->csvd.start_time = info->csvd.earliest_time;
500 }
501
502 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csvd.end_date_choose)))
503 {
504 time_val = gnc_date_edit_get_date (GNC_DATE_EDIT(info->csvd.end_date));
505 time_val = gnc_time64_get_day_end (time_val);
506 info->csvd.end_time = time_val;
507 }
508 else
509 {
510 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csvd.end_date_today)))
511 info->csvd.end_time = gnc_time64_get_today_end();
512 else
513 info->csvd.end_time = info->csvd.latest_time;
514 }
515}
516
517
518/*******************************************************
519 * csv_export_show_range_cb
520 *
521 * call back for show range button
522 *******************************************************/
523void
524csv_export_show_range_cb (GtkRadioButton *button, gpointer user_data)
525{
526 CsvExportInfo *info = user_data;
527 gboolean active;
528
529 g_return_if_fail (GTK_IS_RADIO_BUTTON(button));
530
531 active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
532
533 if (!active)
534 {
535 info->csvd.start_time = info->csvd.earliest_time;
536 info->csvd.end_time = info->csvd.latest_time;
537 }
538 else
539 get_filter_times (info);
540
541 gtk_widget_set_sensitive (info->csvd.table, active);
542}
543
544
545/*******************************************************
546 * csv_export_date_changed_cb
547 *
548 * call back for when a date changes
549 *******************************************************/
550static void
551csv_export_date_changed_cb (GtkWidget *w, gpointer user_data)
552{
553 CsvExportInfo *info = user_data;
554
555 get_filter_times (info);
556}
557
558
559/*******************************************************
560 * csv_export_start_date_cb
561 *
562 * call back for when the start date changes
563 *******************************************************/
564void
565csv_export_start_date_cb (GtkWidget *radio, gpointer user_data)
566{
567 CsvExportInfo *info = user_data;
568 const gchar *name;
569 gboolean active;
570
571 g_return_if_fail (GTK_IS_RADIO_BUTTON(radio));
572
573 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
574 {
575 LEAVE("1st callback of pair. Defer to 2nd callback.");
576 return;
577 }
578
579 name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
580 active = (g_strcmp0 (name, "start_date_choose") == 0 ? 1 : 0 );
581 gtk_widget_set_sensitive (info->csvd.start_date, active);
582 get_filter_times (info);
583}
584
585
586/*******************************************************
587 * csv_export_end_date_cb
588 *
589 * call back for when the end date changes
590 *******************************************************/
591void
592csv_export_end_date_cb (GtkWidget *radio, gpointer user_data)
593{
594 CsvExportInfo *info = user_data;
595 const gchar *name;
596 gboolean active;
597
598 g_return_if_fail (GTK_IS_RADIO_BUTTON(radio));
599
600 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
601 {
602 LEAVE("1st callback of pair. Defer to 2nd callback.");
603 return;
604 }
605
606 name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
607 active = (g_strcmp0 (name, "end_date_choose") == 0 ? 1 : 0 );
608 gtk_widget_set_sensitive (info->csvd.end_date, active);
609 get_filter_times (info);
610}
611
612
613/*******************************************************************
614 * get_earliest_and_latest_in_book
615 *
616 * Find the earliest and latest dates occurring in the book.
617 *******************************************************************/
618static void
619get_earliest_and_latest_in_book (CsvExportInfo *info, QofBook *book)
620{
621 QofQuery *q;
622 GSList *p1, *p2;
623 GList *res;
624 time64 etime, ltime;
625
626 q = qof_query_create_for (GNC_ID_SPLIT);
627 qof_query_set_book (q, book);
628
629 /* Sort by transaction date */
630 p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED);
631 p1 = g_slist_prepend (p1, SPLIT_TRANS);
632 p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT);
633 qof_query_set_sort_order (q, p1, p2, NULL);
634
635 /* Run the query, find the earliest and latest transaction dates */
636 res = qof_query_run (q);
637
638 if (res)
639 {
640 etime = xaccQueryGetEarliestDateFound (q);
641 ltime = xaccQueryGetLatestDateFound (q);
642 }
643 else
644 {
645 /* If no results, we don't want to bomb totally */
646 etime = gnc_time (0);
647 ltime = gnc_time (NULL);
648 }
649 info->csvd.earliest_time = gnc_time64_get_day_start (etime);
650 info->csvd.latest_time = gnc_time64_get_day_end (ltime);
651
653}
654
655
656/* =============================================================== */
657
658
659/*******************************************************
660 * Assistant page prepare functions
661 *******************************************************/
662void
663csv_export_assistant_start_page_prepare (GtkAssistant *assistant,
664 gpointer user_data)
665{
666 CsvExportInfo *info = user_data;
667 gchar *msg = NULL;
668
669 if (info->export_type == XML_EXPORT_TREE)
670 msg = g_strdup (_(start_tree_string));
671 else
672 msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_multi_string));
673
674 gtk_label_set_text (GTK_LABEL(info->start_label), msg);
675 g_free (msg);
676
677 /* Enable the Assistant Buttons */
678 gtk_assistant_set_page_complete (assistant, info->start_page, TRUE);
679}
680
681
682void
683csv_export_assistant_account_page_prepare (GtkAssistant *assistant,
684 gpointer user_data)
685{
686 CsvExportInfo *info = user_data;
687
688 /* Enable the "Next" Assistant Button if we have accounts */
689 if (g_list_length(info->csva.account_list) > 0)
690 gtk_assistant_set_page_complete (assistant, info->account_page, TRUE);
691 else
692 gtk_assistant_set_page_complete (assistant, info->account_page, FALSE);
693}
694
695
696void
697csv_export_assistant_file_page_prepare (GtkAssistant *assistant,
698 gpointer user_data)
699{
700 CsvExportInfo *info = user_data;
701
702 /* Set the default directory */
703 if (info->starting_dir)
704 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(info->file_chooser), info->starting_dir);
705 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(info->file_chooser), "");
706
707 /* Disable the "Next" Assistant Button */
708 gtk_assistant_set_page_complete (assistant, info->file_page, FALSE);
709}
710
711
712void
713csv_export_assistant_finish_page_prepare (GtkAssistant *assistant,
714 gpointer user_data)
715{
716 CsvExportInfo *info = user_data;
717 gchar *text;
718
719 /* Set Finish page text */
720 if (info->export_type == XML_EXPORT_TREE)
721 text = g_strdup_printf (gettext (finish_tree_string), info->file_name);
722 else
723 {
724 if ((info->export_type == XML_EXPORT_REGISTER) &&
725 (g_list_length (info->csva.account_list) == 0))
726 text = g_strdup_printf (gettext (finish_trans_search_gl_string), info->file_name);
727 else
728 text = g_strdup_printf (gettext (finish_trans_string),
729 info->file_name,
730 g_list_length (info->csva.account_list));
731 }
732 gtk_label_set_text (GTK_LABEL(info->finish_label), text);
733 g_free (text);
734
735 /* Test if the filename exists */
736 if (g_file_test (info->file_name, G_FILE_TEST_EXISTS))
737 {
738 const char *format = _("The file %s already exists. "
739 "Are you sure you want to overwrite it?");
740
741 /* if user says cancel, we should go back a page */
742 if (!gnc_verify_dialog (GTK_WINDOW (assistant), FALSE, format, info->file_name))
743 gtk_assistant_previous_page (assistant);
744 }
745 /* Enable the Assistant Buttons */
746 gtk_assistant_set_page_complete (assistant, info->finish_label, TRUE);
747}
748
749
750void
751csv_export_assistant_summary_page_prepare (GtkAssistant *assistant,
752 gpointer user_data)
753{
754 CsvExportInfo *info = user_data;
755 gchar *text, *mtext;
756 gnc_set_default_directory (GNC_PREFS_GROUP, info->starting_dir);
757
758 if (info->failed)
759 text = _("There was a problem with the export, this could be due to lack of space, "
760 "permissions or unable to access folder. Check the trace file for further logging!\n"
761 "You may need to enable debugging.\n");
762 else
763 text = _("File exported successfully!\n");
764
765 mtext = g_strdup_printf ("<span size=\"medium\"><b>%s</b></span>", text);
766
767 gtk_label_set_markup (GTK_LABEL(info->summary_label), mtext);
768
769 g_free (mtext);
770}
771
772
773void
774csv_export_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
775 gpointer user_data)
776{
777 CsvExportInfo *info = user_data;
778
779 if (page == info->start_page)
780 csv_export_assistant_start_page_prepare (assistant, user_data);
781 else if (page == info->account_page)
782 csv_export_assistant_account_page_prepare (assistant, user_data);
783 else if (page == info->file_page)
784 csv_export_assistant_file_page_prepare (assistant, user_data);
785 else if (page == info->finish_label)
786 csv_export_assistant_finish_page_prepare (assistant, user_data);
787 else if (page == info->summary_label)
788 csv_export_assistant_summary_page_prepare (assistant, user_data);
789 else
790 g_assert_not_reached();
791}
792
793
794/*******************************************************
795 * Assistant call back functions
796 *******************************************************/
797static void
798csv_export_assistant_destroy_cb (GtkWidget *object, gpointer user_data)
799{
800 CsvExportInfo *info = user_data;
801 gnc_unregister_gui_component_by_data (ASSISTANT_CSV_EXPORT_CM_CLASS, info);
802 g_list_free (info->csva.account_list);
803 g_free (info);
804}
805
806void
807csv_export_assistant_cancel (GtkAssistant *assistant, gpointer user_data)
808{
809 CsvExportInfo *info = user_data;
810 gnc_close_gui_component_by_data (ASSISTANT_CSV_EXPORT_CM_CLASS, info);
811}
812
813void
814csv_export_assistant_close (GtkAssistant *assistant, gpointer user_data)
815{
816 CsvExportInfo *info = user_data;
817 gnc_close_gui_component_by_data (ASSISTANT_CSV_EXPORT_CM_CLASS, info);
818}
819
820void
821csv_export_assistant_finish (GtkAssistant *assistant, gpointer user_data)
822{
823 CsvExportInfo *info = user_data;
824
825 if (info->export_type == XML_EXPORT_TREE)
826 csv_tree_export (info);
827 else
828 csv_transactions_export (info);
829}
830
831static void
832csv_export_close_handler (gpointer user_data)
833{
834 CsvExportInfo *info = user_data;
835
836 g_free (info->file_name);
837 g_free (info->starting_dir);
838 if (info->mid_sep)
839 g_free (info->mid_sep);
840
841 gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->assistant));
842 gtk_widget_destroy (info->assistant);
843}
844
845/*******************************************************
846 * Create the Assistant
847 *******************************************************/
848static GtkWidget *
849csv_export_assistant_create (CsvExportInfo *info)
850{
851 GtkBuilder *builder;
852 GtkWidget *button;
853 GtkWidget *table, *hbox;
854
855 builder = gtk_builder_new();
856 gnc_builder_add_from_file (builder , "assistant-csv-export.glade", "csv_export_assistant");
857 info->assistant = GTK_WIDGET(gtk_builder_get_object (builder, "csv_export_assistant"));
858
859 // Set the name for this assistant so it can be easily manipulated with css
860 gtk_widget_set_name (GTK_WIDGET(info->assistant), "gnc-id-assistant-csv-export");
861 gnc_widget_style_context_add_class (GTK_WIDGET(info->assistant), "gnc-class-exports");
862
863 /* Load default settings */
864 load_settings (info);
865
866 /* Start Page */
867 info->start_page = GTK_WIDGET(gtk_builder_get_object(builder, "start_page"));
868 info->start_label = GTK_WIDGET(gtk_builder_get_object(builder, "start_label"));
869 info->custom_entry = GTK_WIDGET(gtk_builder_get_object(builder, "custom_entry"));
870 gtk_widget_set_sensitive (info->custom_entry, FALSE);
871
872 /* Account Page */
873 info->account_page = GTK_WIDGET(gtk_builder_get_object(builder, "account_page"));
874
875 if ((info->export_type == XML_EXPORT_TREE) || (info->export_type == XML_EXPORT_REGISTER))
876 {
877 GtkWidget *chkbox = GTK_WIDGET(gtk_builder_get_object(builder, "simple_layout"));
878
879 // Don't provide simple export layout for search registers and General Journal
880 if ((info->export_type == XML_EXPORT_TREE) ||
881 (g_list_length (info->csva.account_list) == 0))
882 gtk_widget_destroy (chkbox);
883 gtk_assistant_remove_page (GTK_ASSISTANT(info->assistant), 1); //remove accounts page
884 }
885 else
886 {
887 GtkTreeView *tree_view;
888 GtkTreeSelection *selection;
889 GtkWidget *box, *label;
890
891 info->csva.acct_info = GTK_WIDGET(gtk_builder_get_object (builder, "acct_info_vbox"));
892 info->csva.num_acct_label = GTK_WIDGET(gtk_builder_get_object (builder, "num_accounts_label"));
893
894 tree_view = gnc_tree_view_account_new (FALSE);
895 info->csva.account_treeview = GTK_WIDGET(tree_view);
896
897 selection = gtk_tree_view_get_selection (tree_view);
898 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
899 g_signal_connect (G_OBJECT(selection), "changed",
900 G_CALLBACK(csv_export_account_changed_cb), info);
901
902 gtk_widget_show (info->csva.account_treeview);
903 box = GTK_WIDGET(gtk_builder_get_object (builder, "account_scroll"));
904 gtk_container_add (GTK_CONTAINER(box), info->csva.account_treeview);
905
906 label = GTK_WIDGET(gtk_builder_get_object (builder, "accounts_label"));
907 gtk_label_set_mnemonic_widget (GTK_LABEL(label), GTK_WIDGET(tree_view));
908
909 /* select subaccounts button */
910 button = GTK_WIDGET(gtk_builder_get_object (builder, "select_subaccounts_button"));
911 info->csva.select_button = button;
912 g_signal_connect (G_OBJECT(button), "clicked",
913 G_CALLBACK(csv_export_select_subaccounts_clicked_cb), info);
914
915 button = GTK_WIDGET(gtk_builder_get_object (builder, "select_all_button"));
916 info->csva.select_button = button;
917 g_signal_connect (G_OBJECT(button), "clicked",
918 G_CALLBACK(csv_export_select_all_clicked_cb), info);
919
920 g_signal_connect (G_OBJECT(info->csva.account_treeview), "cursor_changed",
921 G_CALLBACK(csv_export_cursor_changed_cb), info);
922
923 /* Set the date info */
924 button = GTK_WIDGET(gtk_builder_get_object (builder, "show_range"));
925
926 /* Get the Earliest and Latest dates in Book */
927 get_earliest_and_latest_in_book (info, gnc_get_current_book());
928
929 info->csvd.start_time = info->csvd.earliest_time;
930 info->csvd.end_time = info->csvd.latest_time;
931 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), FALSE);
932
933 table = GTK_WIDGET(gtk_builder_get_object (builder, "select_range_table"));
934 info->csvd.table = table;
935 gtk_widget_set_sensitive (GTK_WIDGET(table), FALSE);
936
937 info->csvd.start_date_choose = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_choose"));
938 info->csvd.start_date_today = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_today"));
939 info->csvd.end_date_choose = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_choose"));
940 info->csvd.end_date_today = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_today"));
941
942 /* Start date info */
943 info->csvd.start_date = gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE);
944 gtk_widget_set_sensitive (info->csvd.start_date, FALSE);
945 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_hbox"));
946 gtk_box_pack_start (GTK_BOX(hbox), info->csvd.start_date, TRUE, TRUE, 0);
947 gtk_widget_show (info->csvd.start_date);
948 gnc_date_edit_set_time (GNC_DATE_EDIT(info->csvd.start_date), info->csvd.start_time);
949 g_signal_connect (G_OBJECT(info->csvd.start_date), "date-changed",
950 G_CALLBACK(csv_export_date_changed_cb), info);
951
952 /* End date info */
953 info->csvd.end_date = gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE);
954 gtk_widget_set_sensitive (info->csvd.end_date, FALSE);
955 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_hbox"));
956 gtk_box_pack_start (GTK_BOX(hbox), info->csvd.end_date, TRUE, TRUE, 0);
957 gtk_widget_show (info->csvd.end_date);
958 gnc_date_edit_set_time (GNC_DATE_EDIT(info->csvd.end_date), info->csvd.end_time);
959 g_signal_connect (G_OBJECT (info->csvd.end_date), "date-changed",
960 G_CALLBACK (csv_export_date_changed_cb), info);
961
962 /* Load Accounts */
963 show_acct_type_accounts (info);
964 update_accounts_tree (info);
965 }
966
967 /* File chooser Page */
968 info->file_page = GTK_WIDGET(gtk_builder_get_object(builder, "file_page"));
969 info->file_chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_SAVE);
970
971 g_signal_connect (G_OBJECT(info->file_chooser), "selection-changed",
972 G_CALLBACK(csv_export_file_chooser_selection_changed_cb), info);
973
974 g_signal_connect (G_OBJECT(info->file_chooser), "file-activated",
975 G_CALLBACK(csv_export_file_chooser_file_activated_cb), info);
976
977 gtk_box_pack_start (GTK_BOX (info->file_page), info->file_chooser, TRUE, TRUE, 6);
978 gtk_widget_show (info->file_chooser);
979
980 /* Finish Page */
981 info->finish_label = GTK_WIDGET(gtk_builder_get_object (builder, "end_page"));
982
983 /* Summary Page */
984 info->summary_label = GTK_WIDGET(gtk_builder_get_object (builder, "summary_page"));
985
986 g_signal_connect (G_OBJECT(info->assistant), "destroy",
987 G_CALLBACK(csv_export_assistant_destroy_cb), info);
988
989 gnc_restore_window_size (GNC_PREFS_GROUP,
990 GTK_WINDOW(info->assistant), gnc_ui_get_main_window(NULL));
991 if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_GEOMETRY))
992 {
993 GObject *object = gtk_builder_get_object (builder, "paned");
994 gnc_prefs_bind (GNC_PREFS_GROUP, GNC_PREF_PANED_POS, NULL, object, "position");
995 }
996
997 gtk_builder_connect_signals (builder, info);
998 g_object_unref (G_OBJECT(builder));
999 return info->assistant;
1000}
1001
1002static void
1003gnc_file_csv_export_internal (CsvExportType export_type, Query *q, Account *acc)
1004{
1005 CsvExportInfo *info;
1006
1007 info = g_new0 (CsvExportInfo, 1);
1008 info->export_type = export_type;
1009
1010 if (q)
1011 info->query = q;
1012 if (acc)
1013 info->csva.account_list = g_list_prepend(info->csva.account_list, acc);
1014
1015 csv_export_assistant_create (info);
1016 gnc_register_gui_component (ASSISTANT_CSV_EXPORT_CM_CLASS,
1017 NULL, csv_export_close_handler,
1018 info);
1019 gtk_widget_show_all (info->assistant);
1020 gnc_window_adjust_for_screen (GTK_WINDOW(info->assistant));
1021}
1022
1023
1024/********************************************************************\
1025 * gnc_file_csv_export *
1026 * opens up a assistant to export accounts or transactions based on *
1027 * the type. *
1028 * Args: export_type *
1029 * Return: nothing *
1030\********************************************************************/
1031void
1032gnc_file_csv_export (CsvExportType export_type)
1033{
1034 gnc_file_csv_export_internal (export_type, NULL, NULL);
1035}
1036
1037
1038/********************************************************************\
1039 * gnc_file_csv_export_register *
1040 * opens up a assistant to export register transactions based. *
1041 * Args: export_type *
1042 * Args: Query *
1043 * Args: Account *
1044 * Return: nothing *
1045\********************************************************************/
1046void
1047gnc_file_csv_export_register (CsvExportType export_type, Query *q, Account *acc)
1048{
1049 gnc_file_csv_export_internal (export_type, q, acc);
1050}
API for Transactions and Splits (journal entries)
void gnc_file_csv_export(CsvExportType export_type)
The gnc_file_csv_export() will let the user export the account tree or transactions to a delimited fi...
void gnc_file_csv_export_register(CsvExportType export_type, Query *q, Account *acc)
The gnc_file_csv_export_register() will let the user export the active register transactions to a del...
CSV Export Assistant.
CSV Export Transactions.
CSV Export Account Tree.
Generic api to store and retrieve preferences.
GtkTreeView implementation for gnucash account tree.
Utility functions for convert uri in separate components and back.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed.
Definition Account.h:103
@ ACCT_TYPE_MUTUAL
Mutual Fund accounts will typically be shown in registers which show three columns: price,...
Definition Account.h:125
@ ACCT_TYPE_ROOT
The hidden root account of an account tree.
Definition Account.h:153
@ ACCT_TYPE_EXPENSE
Expense accounts are used to denote expenses.
Definition Account.h:143
@ ACCT_TYPE_BANK
The bank account type denotes a savings or checking account held at a bank.
Definition Account.h:107
@ ACCT_TYPE_RECEIVABLE
A/R account type.
Definition Account.h:149
@ ACCT_TYPE_LIABILITY
liability (and asset) accounts indicate generic, generalized accounts that are none of the above.
Definition Account.h:119
@ ACCT_TYPE_CREDIT
The Credit card account is used to denote credit (e.g.
Definition Account.h:113
@ NUM_ACCOUNT_TYPES
stop here; the following types just aren't ready for prime time
Definition Account.h:161
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
time64 gnc_time64_get_day_start(time64 time_val)
The gnc_time64_get_day_start() routine will take the given time in seconds and adjust it to the first...
time64 gnc_time64_get_today_start(void)
The gnc_time64_get_today_start() routine returns a time64 value corresponding to the first second of ...
time64 gnc_time64_get_day_end(time64 time_val)
The gnc_time64_get_day_end() routine will take the given time in seconds and adjust it to the last se...
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
time64 gnc_time64_get_today_end(void)
The gnc_time64_get_today_end() routine returns a time64 value corresponding to the last second of tod...
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
void gnc_tree_view_account_select_subaccounts(GncTreeViewAccount *view, Account *account)
This function selects all sub-accounts of an account in the account tree view.
GList * gnc_tree_view_account_get_selected_accounts(GncTreeViewAccount *view)
This function returns a list of the accounts associated with the selected items in the account tree v...
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
Create a new account tree view.
Account * gnc_tree_view_account_get_cursor_account(GncTreeViewAccount *view)
This function returns the account in the account tree view at the current location of the cursor.
void gnc_tree_view_account_get_view_info(GncTreeViewAccount *view, AccountViewInfo *avi)
Given pointers to an account tree and old style filter block, this function will copy the current con...
void gnc_tree_view_account_set_view_info(GncTreeViewAccount *view, AccountViewInfo *avi)
Given pointers to an account tree and old style filter block, this function will applies the settings...
gint gnc_tree_view_account_count_children(GncTreeViewAccount *view, Account *account)
This function determines if an account in the account tree view has any visible children.
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
void gnc_prefs_bind(const gchar *group, const gchar *pref_name, const gchar *pref_value, gpointer object, const gchar *property)
Bind a setting to a g_object property.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
#define QUERY_DEFAULT_SORT
Default sort object type.
Definition qofquery.h:105
void qof_query_set_book(QofQuery *query, QofBook *book)
Set the book to be searched.
void qof_query_set_sort_order(QofQuery *q, QofQueryParamList *params1, QofQueryParamList *params2, QofQueryParamList *params3)
When a query is run, the results are sorted before being returned.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
GList * qof_query_run(QofQuery *query)
Perform the query, return the results.
gchar * gnc_uri_get_path(const gchar *uri)
Extracts the path part from a uri.
STRUCTS.
QofBook reference.
Definition qofbook-p.hpp:47
A Query.
Definition qofquery.cpp:75