PageRenderTime 42ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/grisbi-0.8.8/src/import.c

#
C | 4950 lines | 3489 code | 784 blank | 677 comment | 404 complexity | 6cde808f4aec59a0b9161b996d6d121e MD5 | raw file
Possible License(s): GPL-2.0
  1. /* ************************************************************************** */
  2. /* */
  3. /* Copyright (C) 2000-2008 Cédric Auger (cedric@grisbi.org) */
  4. /* 2004-2008 Benjamin Drieu (bdrieu@april.org) */
  5. /* 2008-2009 Pierre Biava (grisbi@pierre.biava.name) */
  6. /* http://www.grisbi.org */
  7. /* */
  8. /* This program is free software; you can redistribute it and/or modify */
  9. /* it under the terms of the GNU General Public License as published by */
  10. /* the Free Software Foundation; either version 2 of the License, or */
  11. /* (at your option) any later version. */
  12. /* */
  13. /* This program is distributed in the hope that it will be useful, */
  14. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  15. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  16. /* GNU General Public License for more details. */
  17. /* */
  18. /* You should have received a copy of the GNU General Public License */
  19. /* along with this program; if not, write to the Free Software */
  20. /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
  21. /* */
  22. /* ************************************************************************** */
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26. #include "include.h"
  27. /*START_INCLUDE*/
  28. #include "import.h"
  29. #include "utils.h"
  30. #include "bet_data.h"
  31. #include "import_csv.h"
  32. #include "dialog.h"
  33. #include "utils_file_selection.h"
  34. #include "go-charmap-sel.h"
  35. #include "gsb_account.h"
  36. #include "gsb_account_property.h"
  37. #include "gsb_assistant.h"
  38. #include "gsb_assistant_file.h"
  39. #include "gsb_automem.h"
  40. #include "utils_buttons.h"
  41. #include "gsb_combo_box.h"
  42. #include "gsb_currency_config.h"
  43. #include "gsb_currency.h"
  44. #include "gsb_data_account.h"
  45. #include "gsb_data_budget.h"
  46. #include "gsb_data_category.h"
  47. #include "gsb_data_currency.h"
  48. #include "gsb_data_form.h"
  49. #include "gsb_data_fyear.h"
  50. #include "gsb_data_import_rule.h"
  51. #include "gsb_data_payee.h"
  52. #include "gsb_data_payment.h"
  53. #include "gsb_data_transaction.h"
  54. #include "utils_dates.h"
  55. #include "gsb_file.h"
  56. #include "gsb_file_util.h"
  57. #include "gsb_form_scheduler.h"
  58. #include "gsb_form_transaction.h"
  59. #include "navigation.h"
  60. #include "menu.h"
  61. #include "tiers_onglet.h"
  62. #include "gsb_real.h"
  63. #include "gsb_status.h"
  64. #include "utils_str.h"
  65. #include "gsb_transactions_list.h"
  66. #include "gtk_combofix.h"
  67. #include "traitement_variables.h"
  68. #include "main.h"
  69. #include "accueil.h"
  70. #include "parametres.h"
  71. #include "qif.h"
  72. #include "transaction_list.h"
  73. #include "utils_files.h"
  74. #include "structures.h"
  75. #include "erreur.h"
  76. /*END_INCLUDE*/
  77. /*START_STATIC*/
  78. static gboolean affichage_recapitulatif_importation ( GtkWidget * assistant );
  79. static const gchar * autodetect_file_type ( gchar * filename,
  80. gchar * pointeur_char );
  81. static gboolean changement_valeur_echelle_recherche_date_import ( GtkWidget *spin_button );
  82. static gboolean click_dialog_ope_orphelines ( GtkWidget *dialog,
  83. gint result,
  84. GtkWidget *liste_ope_celibataires );
  85. static gboolean click_sur_liste_opes_orphelines ( GtkCellRendererToggle *renderer,
  86. gchar *ligne,
  87. GtkTreeModel *store );
  88. static void confirmation_enregistrement_ope_import ( struct struct_compte_importation *imported_account,
  89. gint account_number );
  90. static void cree_liens_virements_ope_import ( void );
  91. static GtkWidget *cree_ligne_recapitulatif ( struct struct_compte_importation * compte );
  92. static gint gsb_import_add_currency ( struct struct_compte_importation * compte );
  93. static void gsb_import_add_imported_transactions ( struct struct_compte_importation *imported_account,
  94. gint account_number );
  95. static void gsb_import_associations_add_assoc ( GtkWidget *button, GtkWidget *main_widget );
  96. static void gsb_import_associations_cell_edited (GtkCellRendererText *cell,
  97. const gchar *path_string,
  98. const gchar *new_text,
  99. GObject * main_widget );
  100. static gboolean gsb_import_associations_check_add_button ( GObject * main_widget );
  101. static void gsb_import_associations_combo_changed ( GtkEditable *editable,
  102. GObject * main_widget );
  103. static void gsb_import_associations_del_assoc ( GtkWidget *button, GtkWidget *main_widget );
  104. static void gsb_import_associations_fill_model ( GtkListStore *list_store );
  105. static gint gsb_import_associations_find_payee ( gchar *imported_tiers);
  106. static gboolean gsb_import_associations_select_func ( GtkTreeSelection *selection,
  107. GtkTreeModel *model,
  108. GtkTreePath *path,
  109. gboolean path_currently_selected,
  110. GObject *main_widget );
  111. static gchar **gsb_import_by_rule_ask_filename ( gint rule );
  112. static gboolean gsb_import_by_rule_get_file ( GtkWidget *button,
  113. GtkWidget *entry );
  114. static void gsb_import_check_ope_import ( GtkWidget *widget, gpointer data );
  115. static gboolean gsb_import_check_transaction_link ( gint transaction_number,
  116. gint tested_transaction );
  117. static GSList *gsb_import_create_file_chooser ( const char *enc, GtkWidget *parent );
  118. static gint gsb_import_create_imported_account ( struct struct_compte_importation *imported_account );
  119. void gsb_import_create_imported_transactions ( struct struct_compte_importation *imported_account,
  120. gint account_number );
  121. static gint gsb_import_create_transaction ( struct struct_ope_importation *imported_transaction,
  122. gint account_number, gchar * origine );
  123. static gboolean gsb_import_define_action ( struct struct_compte_importation *imported_account,
  124. gint account_number,
  125. GDate *first_date_import );
  126. static GDate *gsb_import_get_first_date ( GSList *import_list );
  127. static gboolean gsb_import_gunzip_file ( gchar *filename );
  128. static void gsb_import_lookup_budget ( struct struct_ope_importation *imported_transaction,
  129. gint transaction_number);
  130. static GtkWidget *gsb_import_progress_bar_affiche ( struct struct_compte_importation *imported_account );
  131. static void gsb_import_progress_bar_pulse ( GtkWidget *progress, gint nbre_transaction );
  132. static gboolean gsb_import_ope_import_test_toggled ( GtkWidget *vbox , gboolean test );
  133. static void gsb_import_ope_import_toggled ( GtkWidget *button, GtkWidget *vbox );
  134. static gboolean gsb_import_set_id_compte ( gint account_nb, gchar *imported_id );
  135. static gboolean gsb_import_set_tmp_file ( gchar *filename,
  136. gchar * pointeur_char );
  137. static void gsb_import_show_orphan_transactions ( GSList *orphan_list,
  138. gint account_number );
  139. static gboolean import_account_action_activated ( GtkWidget * radio, gint action );
  140. static gboolean import_active_toggled ( GtkCellRendererToggle * cell, gchar *path_str,
  141. gpointer model );
  142. static GtkWidget *import_create_file_selection_page ( GtkWidget * assistant );
  143. static GtkWidget *import_create_final_page ( GtkWidget * assistant );
  144. static GtkWidget *import_create_resume_page ( GtkWidget * assistant );
  145. static gboolean import_enter_file_selection_page ( GtkWidget * assistant );
  146. static gboolean import_enter_resume_page ( GtkWidget * assistant );
  147. static void import_preview_maybe_sensitive_next ( GtkWidget * assistant, GtkTreeModel * model );
  148. static gboolean import_select_file ( GtkWidget * button, GtkWidget * assistant );
  149. static gboolean import_switch_type ( GtkCellRendererText *cell, const gchar *path,
  150. const gchar *value, GtkListStore * model );
  151. static void pointe_opes_importees ( struct struct_compte_importation *imported_account,
  152. gint account_number );
  153. static void traitement_operations_importees ( void );
  154. /*END_STATIC*/
  155. /*START_EXTERN*/
  156. extern GtkWidget *menu_import_rules;
  157. extern gint mise_a_jour_liste_comptes_accueil;
  158. extern gint mise_a_jour_soldes_minimaux;
  159. extern gint no_devise_totaux_categ;
  160. extern gint no_devise_totaux_ib;
  161. extern gint no_devise_totaux_tiers;
  162. extern GtkWidget *window;
  163. /*END_EXTERN*/
  164. /* recopie des types de transaction de la libofx en attendant une version propre */
  165. typedef enum
  166. {
  167. OFX_CREDIT, /**< Generic credit */
  168. OFX_DEBIT, /**< Generic debit */
  169. OFX_INT, /**< Interest earned or paid (Note: Depends on signage of amount) */
  170. OFX_DIV, /**< Dividend */
  171. OFX_FEE, /**< FI fee */
  172. OFX_SRVCHG, /**< Service charge */
  173. OFX_DEP, /**< Deposit */
  174. OFX_ATM, /**< ATM debit or credit (Note: Depends on signage of amount) */
  175. OFX_POS, /**< Point of sale debit or credit (Note: Depends on signage of amount) */
  176. OFX_XFER, /**< Transfer */
  177. OFX_CHECK, /**< Check */
  178. OFX_PAYMENT, /**< Electronic payment */
  179. OFX_CASH, /**< Cash withdrawal */
  180. OFX_DIRECTDEP, /**< Direct deposit */
  181. OFX_DIRECTDEBIT,/**< Merchant initiated debit */
  182. OFX_REPEATPMT, /**< Repeating payment/standing order */
  183. OFX_OTHER /**< Somer other type of transaction */
  184. } OFXTransactionType;
  185. /** Suppported import formats. Plugins may register themselves. */
  186. static GSList *import_formats = NULL;
  187. /* set to TRUE if we import some marked R transactions
  188. * grisbi cannot associate them to a reconcile number, so if TRUE,
  189. * grisbi will show a dialog to tell people to manually associate them */
  190. static gboolean marked_r_transactions_imported;
  191. /** Known built-in import formats. Others are plugins. */
  192. struct import_format builtin_formats[] =
  193. {
  194. { "CSV", N_("Comma Separated Values"), "csv", (import_function) csv_import_csv_account },
  195. { "QIF", N_("Quicken Interchange Format"), "qif", (import_function) recuperation_donnees_qif },
  196. { NULL, NULL, NULL, NULL },
  197. };
  198. /** used to keep the number of the mother transaction while importing split transactions */
  199. static gint mother_transaction_number;
  200. gint valeur_echelle_recherche_date_import;
  201. GSList *liste_comptes_importes;
  202. GSList *liste_comptes_importes_error;
  203. static gint virements_a_chercher;
  204. gchar *charmap_imported;
  205. /* gestion des associations entre un tiers et sa chaine de recherche */
  206. GSList *liste_associations_tiers = NULL;
  207. /* nombre de transaction ŕ importer qui affiche une barre de progression */
  208. #define NBRE_TRANSACTION_FOR_PROGRESS_BAR 250
  209. enum import_filesel_columns
  210. {
  211. IMPORT_FILESEL_SELECTED = 0,
  212. IMPORT_FILESEL_TYPENAME,
  213. IMPORT_FILESEL_FILENAME,
  214. IMPORT_FILESEL_REALNAME,
  215. IMPORT_FILESEL_TYPE,
  216. IMPORT_FILESEL_CODING,
  217. IMPORT_FILESEL_NUM_COLS,
  218. };
  219. /** Page numbering for the import wizard. */
  220. enum import_pages
  221. {
  222. IMPORT_STARTUP_PAGE,
  223. IMPORT_FILESEL_PAGE,
  224. IMPORT_CSV_PAGE,
  225. IMPORT_RESUME_PAGE,
  226. IMPORT_FIRST_ACCOUNT_PAGE,
  227. };
  228. /**
  229. * Register built-in import formats as known.
  230. */
  231. void register_import_formats ( void )
  232. {
  233. gint i;
  234. for ( i = 0; builtin_formats [ i ] . name != NULL ; i ++ )
  235. {
  236. register_import_format ( &builtin_formats [ i ] );
  237. }
  238. }
  239. /**
  240. * Register a known import format as known.
  241. *
  242. * \param format A pointer to a structure describing
  243. * this import format.
  244. *
  245. */
  246. G_MODULE_EXPORT void register_import_format ( struct import_format *format )
  247. {
  248. gchar *tmp_str;
  249. tmp_str = g_strdup_printf ( _("Adding '%s' as an import format"), format -> name );
  250. devel_debug ( tmp_str );
  251. g_free ( tmp_str );
  252. import_formats = g_slist_append ( import_formats, format );
  253. }
  254. /**
  255. *
  256. *
  257. *
  258. */
  259. void importer_fichier ( void )
  260. {
  261. GtkWidget *assistant;
  262. gchar* tmp_str;
  263. gchar *format_str;
  264. /* if nothing opened, we need to create a new file to set up all the variables */
  265. if (!gsb_data_currency_get_currency_list ())
  266. {
  267. init_variables ();
  268. gsb_assistant_file_run (FALSE, TRUE);
  269. return;
  270. }
  271. liste_comptes_importes = NULL;
  272. liste_comptes_importes_error = NULL;
  273. virements_a_chercher = 0;
  274. format_str = gsb_import_formats_get_list_formats_to_string ( );
  275. tmp_str = g_strconcat ( _("This assistant will help you import one or several "
  276. "files into Grisbi."
  277. "\n\n"
  278. "Grisbi will try to do its best to guess which format are imported, "
  279. "but you may have to manually set them in the list of next page. "
  280. "So far, the following formats are supported:"
  281. "\n\n"),
  282. format_str, NULL );
  283. assistant = gsb_assistant_new ( _("Importing transactions into Grisbi"),
  284. tmp_str,
  285. "impexp.png",
  286. NULL );
  287. g_free ( format_str );
  288. g_free ( tmp_str );
  289. gsb_assistant_add_page ( assistant,
  290. import_create_file_selection_page ( assistant ),
  291. IMPORT_FILESEL_PAGE,
  292. IMPORT_STARTUP_PAGE,
  293. IMPORT_RESUME_PAGE,
  294. G_CALLBACK ( import_enter_file_selection_page ) );
  295. gsb_assistant_add_page ( assistant,
  296. import_create_csv_preview_page ( assistant ),
  297. IMPORT_CSV_PAGE,
  298. IMPORT_FILESEL_PAGE,
  299. IMPORT_RESUME_PAGE,
  300. G_CALLBACK ( import_enter_csv_preview_page ) );
  301. gsb_assistant_add_page ( assistant,
  302. import_create_resume_page ( assistant ),
  303. IMPORT_RESUME_PAGE,
  304. IMPORT_FILESEL_PAGE,
  305. IMPORT_FIRST_ACCOUNT_PAGE,
  306. G_CALLBACK ( import_enter_resume_page ) );
  307. if ( gsb_assistant_run ( assistant ) == GTK_RESPONSE_APPLY )
  308. {
  309. gsb_status_wait ( TRUE );
  310. traitement_operations_importees ();
  311. gtk_widget_destroy ( assistant );
  312. gsb_status_stop_wait ( TRUE );
  313. }
  314. else
  315. {
  316. gtk_widget_destroy ( assistant );
  317. }
  318. }
  319. /**
  320. *
  321. *
  322. *
  323. */
  324. gchar *gsb_import_formats_get_list_formats_to_string ( void )
  325. {
  326. GSList *tmp_list = import_formats;
  327. gchar *format_str = NULL;
  328. while ( tmp_list )
  329. {
  330. gchar* tmp_str;
  331. struct import_format *format;
  332. format = (struct import_format *) tmp_list -> data;
  333. tmp_str = g_strdup_printf (" • %s (%s)\n", _(format -> complete_name), format -> name );
  334. if ( format_str == NULL )
  335. format_str = tmp_str;
  336. else
  337. {
  338. gchar* old_str = format_str;
  339. format_str = g_strconcat ( format_str, tmp_str, NULL );
  340. g_free ( tmp_str );
  341. g_free ( old_str );
  342. }
  343. tmp_list = tmp_list -> next;
  344. }
  345. return format_str;
  346. }
  347. /**
  348. *
  349. *
  350. *
  351. */
  352. GtkWidget *import_create_file_selection_page ( GtkWidget * assistant )
  353. {
  354. GtkWidget * vbox, * paddingbox, * chooser, * tree_view, * sw;
  355. GtkTreeViewColumn *column;
  356. GtkCellRenderer *renderer;
  357. GtkTreeModel * model, * list_acc;
  358. GSList * tmp;
  359. gchar* tmpstr;
  360. vbox = gtk_vbox_new ( FALSE, 6 );
  361. gtk_container_set_border_width ( GTK_CONTAINER(vbox), 12 );
  362. paddingbox = new_paddingbox_with_title ( vbox, TRUE, _("Choose file to import"));
  363. chooser = gtk_button_new_with_label ( _("Add file to import..." ));
  364. tmpstr = g_build_filename ( GRISBI_PIXMAPS_DIR, "import.png", NULL );
  365. gtk_button_set_image ( GTK_BUTTON(chooser),
  366. gtk_image_new_from_file ( tmpstr ) );
  367. g_free ( tmpstr );
  368. gtk_box_pack_start ( GTK_BOX(paddingbox), chooser, FALSE, FALSE, 6 );
  369. g_signal_connect ( G_OBJECT ( chooser ), "clicked", G_CALLBACK ( import_select_file ),
  370. assistant );
  371. /* Scroll for tree view. */
  372. sw = gtk_scrolled_window_new (NULL, NULL);
  373. gtk_widget_set_size_request ( sw, 480, 120 );
  374. gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
  375. gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC,
  376. GTK_POLICY_AUTOMATIC);
  377. gtk_box_pack_start ( GTK_BOX(paddingbox), sw, TRUE, TRUE, 6 );
  378. /* Tree view and model. */
  379. model = GTK_TREE_MODEL ( gtk_tree_store_new ( IMPORT_FILESEL_NUM_COLS, G_TYPE_BOOLEAN,
  380. G_TYPE_STRING, G_TYPE_STRING,
  381. G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING));
  382. tree_view = gtk_tree_view_new_with_model ( GTK_TREE_MODEL ( model ) );
  383. gtk_container_add ( GTK_CONTAINER ( sw ), tree_view );
  384. /* Toggle column. */
  385. renderer = gtk_cell_renderer_toggle_new ();
  386. g_signal_connect ( renderer, "toggled", G_CALLBACK (import_active_toggled), model);
  387. column = gtk_tree_view_column_new_with_attributes ( _("Import"), renderer,
  388. "active", IMPORT_FILESEL_SELECTED,
  389. NULL);
  390. gtk_tree_view_append_column (GTK_TREE_VIEW ( tree_view ), column );
  391. /* Type column. */
  392. renderer = gtk_cell_renderer_combo_new ();
  393. g_signal_connect ( G_OBJECT (renderer), "edited", G_CALLBACK ( import_switch_type),
  394. model );
  395. list_acc = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
  396. tmp = import_formats;
  397. while ( tmp )
  398. {
  399. GtkTreeIter iter;
  400. struct import_format *format = (struct import_format *) tmp -> data;
  401. gtk_list_store_append (GTK_LIST_STORE (list_acc), &iter);
  402. gtk_list_store_set (GTK_LIST_STORE (list_acc), &iter, 0, format -> name, -1);
  403. tmp = tmp -> next;
  404. }
  405. g_object_set ( renderer,
  406. "model", list_acc,
  407. "text-column", 0,
  408. "editable", TRUE,
  409. "editable-set", FALSE,
  410. "has-entry", FALSE,
  411. NULL );
  412. column = gtk_tree_view_column_new_with_attributes ( _("Type"), renderer,
  413. "text", IMPORT_FILESEL_TYPENAME,
  414. NULL);
  415. gtk_tree_view_append_column (GTK_TREE_VIEW ( tree_view ), column );
  416. /* Name column. */
  417. renderer = gtk_cell_renderer_text_new ();
  418. column = gtk_tree_view_column_new_with_attributes ( _("File name"), renderer,
  419. "text", IMPORT_FILESEL_FILENAME,
  420. NULL);
  421. gtk_tree_view_append_column (GTK_TREE_VIEW ( tree_view ), column );
  422. g_object_set_data ( G_OBJECT(assistant), "tree_view", tree_view );
  423. g_object_set_data ( G_OBJECT(assistant), "model", model );
  424. g_object_set_data ( G_OBJECT(model), "assistant", assistant );
  425. return vbox;
  426. }
  427. /**
  428. *
  429. *
  430. */
  431. gboolean import_switch_type ( GtkCellRendererText *cell, const gchar *path,
  432. const gchar *value, GtkListStore * model )
  433. {
  434. GtkTreeIter iter;
  435. GtkWidget * assistant;
  436. assistant = g_object_get_data ( G_OBJECT (model), "assistant" );
  437. if ( gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL ( model ), &iter, path ))
  438. {
  439. GSList * tmp = import_formats;
  440. while ( tmp )
  441. {
  442. gchar *contents;
  443. gchar *nom_fichier;
  444. gchar *tmp_str;
  445. GError *error = NULL;
  446. struct import_format * format;
  447. format = (struct import_format *) tmp -> data;
  448. if ( ! strcmp ( value, format -> name ) )
  449. {
  450. gtk_tree_store_set ( GTK_TREE_STORE (model), &iter,
  451. IMPORT_FILESEL_TYPENAME, value,
  452. IMPORT_FILESEL_TYPE, format -> name,
  453. -1 );
  454. /* CSV is special because it needs configuration, so
  455. * we add a conditional jump there. */
  456. if ( ! strcmp ( value, "CSV" ) )
  457. {
  458. gsb_assistant_set_next ( assistant, IMPORT_FILESEL_PAGE,
  459. IMPORT_CSV_PAGE );
  460. gsb_assistant_set_prev ( assistant, IMPORT_RESUME_PAGE,
  461. IMPORT_CSV_PAGE );
  462. }
  463. gtk_tree_model_get ( GTK_TREE_MODEL ( model ), &iter,
  464. IMPORT_FILESEL_REALNAME, &nom_fichier,
  465. -1 );
  466. /* get contents of file */
  467. if ( ! g_file_get_contents ( nom_fichier, &tmp_str, NULL, &error ) )
  468. {
  469. g_print ( _("Unable to read file: %s\n"), error -> message);
  470. g_error_free ( error );
  471. return FALSE;
  472. }
  473. /* Convert in UTF8 */
  474. contents = g_convert ( tmp_str, -1, "UTF-8", charmap_imported, NULL, NULL, NULL );
  475. if ( contents == NULL )
  476. {
  477. charmap_imported = utils_files_create_sel_charset ( assistant, tmp_str,
  478. charmap_imported,
  479. g_path_get_basename ( nom_fichier ) );
  480. gtk_tree_store_set ( GTK_TREE_STORE ( model ), &iter,
  481. IMPORT_FILESEL_CODING, charmap_imported,
  482. -1 );
  483. g_free ( contents );
  484. }
  485. g_free ( tmp_str );
  486. import_preview_maybe_sensitive_next ( assistant, GTK_TREE_MODEL ( model ));
  487. }
  488. tmp = tmp -> next;
  489. }
  490. }
  491. return FALSE;
  492. }
  493. /**
  494. *
  495. *
  496. */
  497. gboolean import_enter_file_selection_page ( GtkWidget * assistant )
  498. {
  499. GtkTreeModel * model;
  500. model = g_object_get_data ( G_OBJECT ( assistant ), "model" );
  501. import_preview_maybe_sensitive_next ( assistant, model );
  502. return FALSE;
  503. }
  504. /**
  505. *
  506. *
  507. *
  508. */
  509. gboolean import_active_toggled ( GtkCellRendererToggle * cell, gchar *path_str,
  510. gpointer model )
  511. {
  512. GtkWidget * assistant;
  513. GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
  514. GtkTreeIter iter;
  515. gboolean toggle_item;
  516. assistant = g_object_get_data ( G_OBJECT ( model ), "assistant" );
  517. gtk_tree_model_get_iter ( GTK_TREE_MODEL ( model ), &iter, path);
  518. gtk_tree_model_get ( GTK_TREE_MODEL ( model ), &iter,
  519. IMPORT_FILESEL_SELECTED, &toggle_item, -1 );
  520. gtk_tree_store_set ( GTK_TREE_STORE ( model ), &iter,
  521. IMPORT_FILESEL_SELECTED, !toggle_item, -1 );
  522. import_preview_maybe_sensitive_next ( assistant, model );
  523. return FALSE;
  524. }
  525. /**
  526. *
  527. *
  528. *
  529. */
  530. void import_preview_maybe_sensitive_next ( GtkWidget * assistant, GtkTreeModel * model )
  531. {
  532. GtkTreeIter iter;
  533. /* Don't allow going to next page if no file is selected yet. */
  534. gtk_widget_set_sensitive ( g_object_get_data ( G_OBJECT (assistant), "button_next" ), FALSE );
  535. gtk_tree_model_get_iter_first ( model, &iter );
  536. if ( ! gtk_tree_store_iter_is_valid ( GTK_TREE_STORE (model), &iter ))
  537. {
  538. return;
  539. }
  540. /* Iterate over lines so we check if some are checked. */
  541. do
  542. {
  543. gboolean selected;
  544. gchar * type;
  545. gtk_tree_model_get ( GTK_TREE_MODEL ( model ), &iter,
  546. IMPORT_FILESEL_SELECTED, &selected,
  547. IMPORT_FILESEL_TYPE, &type,
  548. - 1 );
  549. if ( selected && strcmp ( type, _("Unknown") ) )
  550. {
  551. gtk_widget_set_sensitive ( g_object_get_data ( G_OBJECT (assistant),
  552. "button_next" ),
  553. TRUE );
  554. return;
  555. }
  556. }
  557. while ( gtk_tree_model_iter_next ( model, &iter ) );
  558. }
  559. /**
  560. *
  561. *
  562. *
  563. */
  564. gboolean import_select_file ( GtkWidget * button, GtkWidget * assistant )
  565. {
  566. GSList * filenames, * iterator;
  567. GtkTreeModel * model;
  568. filenames = gsb_import_create_file_chooser ( NULL, assistant );
  569. if (!filenames)
  570. return FALSE;
  571. iterator = filenames;
  572. model = g_object_get_data ( G_OBJECT ( assistant ), "model" );
  573. while ( iterator && model )
  574. {
  575. GtkTreeIter iter;
  576. const gchar *type;
  577. gchar *nom_fichier;
  578. gchar *tmp_str;
  579. gchar *contents;
  580. gchar *charmap;
  581. GError *error = NULL;
  582. gchar * extension;
  583. /* Open file */
  584. extension = strrchr ( iterator -> data, '.' );
  585. /* unzip Gnucash file if necessary */
  586. if ( extension && strcmp ( extension, ".gnc" ) == 0 )
  587. gsb_import_gunzip_file ( iterator -> data );
  588. /* get contents of file */
  589. if ( ! g_file_get_contents ( iterator -> data, &tmp_str, NULL, &error ) )
  590. {
  591. g_print ( _("Unable to read file: %s\n"), error -> message);
  592. g_error_free ( error );
  593. return FALSE;
  594. }
  595. type = autodetect_file_type ( iterator -> data, tmp_str );
  596. /* passe par un fichier temporaire pour bipasser le bug libofx */
  597. if ( strcmp ( type, "OFX" ) == 0 )
  598. {
  599. nom_fichier = g_strconcat (g_get_tmp_dir (),G_DIR_SEPARATOR_S,
  600. g_path_get_basename ( iterator -> data ), NULL);
  601. if (! gsb_import_set_tmp_file (nom_fichier, tmp_str ) )
  602. {
  603. g_free ( tmp_str );
  604. return FALSE;
  605. }
  606. if ( ( charmap = utils_files_get_ofx_charset ( tmp_str ) ) != NULL )
  607. {
  608. if ( charmap_imported && strlen ( charmap_imported ) > 0 )
  609. g_free ( charmap_imported );
  610. charmap_imported = charmap;
  611. }
  612. }
  613. else
  614. nom_fichier = my_strdup (iterator -> data);
  615. /* CSV is special because it needs configuration, so we
  616. * add a conditional jump there. */
  617. if ( ! strcmp ( type, "CSV" ) )
  618. {
  619. gsb_assistant_set_next ( assistant, IMPORT_FILESEL_PAGE, IMPORT_CSV_PAGE );
  620. gsb_assistant_set_prev ( assistant, IMPORT_RESUME_PAGE, IMPORT_CSV_PAGE );
  621. }
  622. /* Convert to UTF8 */
  623. contents = g_convert ( tmp_str, -1, "UTF-8", charmap_imported, NULL, NULL, NULL );
  624. if ( contents == NULL )
  625. charmap_imported = utils_files_create_sel_charset ( assistant, tmp_str,
  626. charmap_imported,
  627. g_path_get_basename ( iterator -> data ) );
  628. else
  629. g_free ( contents );
  630. gtk_tree_store_append ( GTK_TREE_STORE ( model ), &iter, NULL );
  631. gtk_tree_store_set ( GTK_TREE_STORE ( model ), &iter,
  632. IMPORT_FILESEL_SELECTED, TRUE,
  633. IMPORT_FILESEL_TYPENAME, type,
  634. IMPORT_FILESEL_FILENAME, g_path_get_basename ( iterator -> data ),
  635. IMPORT_FILESEL_REALNAME, nom_fichier,
  636. IMPORT_FILESEL_TYPE, type,
  637. IMPORT_FILESEL_CODING, charmap_imported,
  638. -1 );
  639. g_free ( nom_fichier );
  640. g_free ( tmp_str );
  641. if ( strcmp ( type, _("Unknown") ) )
  642. {
  643. /* A valid file was selected, so we can now go ahead. */
  644. gtk_widget_set_sensitive ( g_object_get_data ( G_OBJECT (assistant), "button_next" ),
  645. TRUE );
  646. }
  647. iterator = iterator -> next;
  648. }
  649. if ( filenames )
  650. g_slist_free ( filenames );
  651. return FALSE;
  652. }
  653. /**
  654. * create an appropriate dialog file chooser
  655. * for importing files to grisbi and return the selected files
  656. *
  657. * \param
  658. *
  659. * \return a GtkFileChooser
  660. * */
  661. GSList *gsb_import_create_file_chooser ( const char *enc, GtkWidget *parent )
  662. {
  663. GtkWidget * dialog, * hbox, * go_charmap_sel;
  664. GtkFileFilter * filter, * default_filter;
  665. gchar * files;
  666. GSList * tmp;
  667. struct import_format * format;
  668. GSList *filenames = NULL;
  669. gchar* old_str;
  670. gchar* tmpstr;
  671. gchar* tmpchar;
  672. dialog = gtk_file_chooser_dialog_new ( _("Choose files to import."),
  673. GTK_WINDOW ( parent ),
  674. GTK_FILE_CHOOSER_ACTION_OPEN,
  675. GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
  676. GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
  677. NULL);
  678. gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER ( dialog ), TRUE );
  679. gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER ( dialog ), gsb_file_get_last_path () );
  680. /* Import filters */
  681. tmp = import_formats;
  682. format = (struct import_format *) tmp -> data;
  683. files = g_strconcat ( "*.", format -> extension, NULL );
  684. tmp = tmp -> next;
  685. while ( tmp )
  686. {
  687. format = (struct import_format *) tmp -> data;
  688. old_str = files;
  689. files = g_strconcat ( files, ", *.", format -> extension, NULL );
  690. g_free ( old_str );
  691. tmp = tmp -> next;
  692. }
  693. default_filter = gtk_file_filter_new ();
  694. tmpstr = g_strdup_printf ( _("Known files (%s)"), files );
  695. gtk_file_filter_set_name ( default_filter, tmpstr );
  696. g_free ( tmpstr );
  697. tmp = import_formats;
  698. while ( tmp )
  699. {
  700. GtkFileFilter * format_filter;
  701. format = (struct import_format *) tmp -> data;
  702. format_filter = gtk_file_filter_new ();
  703. tmpstr = g_strdup_printf ( _("%s files (*.%s)"),
  704. format -> name,
  705. format -> extension );
  706. gtk_file_filter_set_name ( format_filter, tmpstr );
  707. g_free ( tmpstr );
  708. /* Make it case insensitive */
  709. tmpstr = g_strdup ( "*." );
  710. tmpchar = format -> extension;
  711. while(*tmpchar != '\0' )
  712. {
  713. old_str=tmpstr;
  714. tmpstr = g_strdup_printf ( "%s[%c%c]",
  715. tmpstr,
  716. (int)g_ascii_toupper(*tmpchar),
  717. (int)*tmpchar );
  718. tmpchar++;
  719. g_free ( old_str );
  720. }
  721. gtk_file_filter_add_pattern ( format_filter, tmpstr );
  722. /* Add this pattern to the global filter as well*/
  723. gtk_file_filter_add_pattern ( default_filter, tmpstr );
  724. g_free ( tmpstr );
  725. gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog ), format_filter );
  726. tmp = tmp -> next;
  727. }
  728. gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog ), default_filter );
  729. gtk_file_chooser_set_filter ( GTK_FILE_CHOOSER ( dialog ), default_filter );
  730. filter = gtk_file_filter_new ();
  731. gtk_file_filter_set_name ( filter, _("All files") );
  732. gtk_file_filter_add_pattern ( filter, "*" );
  733. gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog ), filter );
  734. /* Add encoding preview */
  735. hbox = gtk_hbox_new ( FALSE, 6 );
  736. gtk_file_chooser_set_extra_widget ( GTK_FILE_CHOOSER ( dialog ), hbox );
  737. gtk_box_pack_start ( GTK_BOX ( hbox ), gtk_label_new ( _("Encoding: ") ),
  738. FALSE, FALSE, 0 );
  739. go_charmap_sel = go_charmap_sel_new (GO_CHARMAP_SEL_TO_UTF8);
  740. if (enc && strlen (enc))
  741. go_charmap_sel_set_encoding ((GOCharmapSel *) go_charmap_sel, enc);
  742. gtk_box_pack_start ( GTK_BOX ( hbox ), go_charmap_sel, TRUE, TRUE, 0 );
  743. gtk_widget_show_all ( hbox );
  744. if ( gtk_dialog_run ( GTK_DIALOG (dialog ) ) == GTK_RESPONSE_ACCEPT )
  745. filenames = gtk_file_chooser_get_filenames ( GTK_FILE_CHOOSER (dialog));
  746. /* save charmap */
  747. charmap_imported = g_strdup (go_charmap_sel_get_encoding ( (GOCharmapSel * )go_charmap_sel ));
  748. gsb_file_update_last_path (file_selection_get_last_directory (GTK_FILE_CHOOSER (dialog), TRUE));
  749. gtk_widget_destroy (dialog);
  750. return filenames;
  751. }
  752. /**
  753. *
  754. *
  755. */
  756. GtkWidget *import_create_resume_page ( GtkWidget * assistant )
  757. {
  758. GtkWidget *sw;
  759. GtkWidget *view;
  760. GtkTextBuffer *buffer;
  761. sw = gtk_scrolled_window_new (NULL, NULL);
  762. gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( sw ),
  763. GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
  764. view = gtk_text_view_new ();
  765. gtk_container_add (GTK_CONTAINER (sw), view);
  766. gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
  767. gtk_text_view_set_editable ( GTK_TEXT_VIEW (view), FALSE );
  768. gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW (view), FALSE );
  769. gtk_text_view_set_left_margin ( GTK_TEXT_VIEW (view), 12 );
  770. gtk_text_view_set_right_margin ( GTK_TEXT_VIEW (view), 12 );
  771. buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
  772. gtk_text_buffer_create_tag ( buffer, "bold",
  773. "weight", PANGO_WEIGHT_BOLD, NULL);
  774. gtk_text_buffer_create_tag ( buffer, "x-large",
  775. "scale", PANGO_SCALE_X_LARGE, NULL);
  776. gtk_text_buffer_create_tag (buffer, "indented",
  777. "left-margin", 24, NULL);
  778. g_object_set_data ( G_OBJECT ( assistant ), "text-buffer", buffer );
  779. return sw;
  780. }
  781. /**
  782. *
  783. *
  784. *
  785. */
  786. gboolean import_enter_resume_page ( GtkWidget * assistant )
  787. {
  788. GSList *files;
  789. GSList *list;
  790. GtkTextBuffer * buffer;
  791. GtkTextIter iter;
  792. gchar * error_message = "";
  793. gchar* tmpstr;
  794. liste_comptes_importes_error = NULL;
  795. liste_comptes_importes = NULL;
  796. /* fichiers sélectionnés dans legestionnaire de fichiers */
  797. files = import_selected_files ( assistant );
  798. while ( files )
  799. {
  800. struct imported_file *imported = files -> data;
  801. GSList * tmp = import_formats;
  802. while ( tmp )
  803. {
  804. struct import_format *format = (struct import_format *) tmp -> data;
  805. if ( !strcmp ( imported -> type, format -> name ) )
  806. {
  807. devel_print_str ( imported -> type );
  808. format -> import ( assistant, imported );
  809. tmp = tmp -> next;
  810. continue;
  811. }
  812. tmp = tmp -> next;
  813. }
  814. files = files -> next;
  815. }
  816. buffer = g_object_get_data ( G_OBJECT ( assistant ), "text-buffer" );
  817. gtk_text_buffer_set_text (buffer, "\n", -1 );
  818. gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
  819. if ( liste_comptes_importes )
  820. {
  821. gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
  822. _("Congratulations !"), -1,
  823. "x-large", NULL);
  824. gtk_text_buffer_insert (buffer, &iter, "\n\n", -1 );
  825. gtk_text_buffer_insert (buffer, &iter,
  826. _("You successfully imported files into Grisbi. The "
  827. "following pages will help you set up imported data for "
  828. "the following files"),
  829. -1 );
  830. gtk_text_buffer_insert (buffer, &iter, "\n\n", -1 );
  831. list = liste_comptes_importes;
  832. while ( list )
  833. {
  834. struct struct_compte_importation * compte;
  835. compte = list -> data;
  836. /* Fix account name if needed. */
  837. if ( ! compte -> nom_de_compte )
  838. {
  839. compte -> nom_de_compte = _("Unnamed Imported account");
  840. }
  841. devel_print_str ( compte -> nom_de_compte );
  842. tmpstr = g_strconcat ( "• ", compte -> nom_de_compte,
  843. " (",
  844. compte -> origine,
  845. ")\n\n",
  846. NULL );
  847. gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
  848. tmpstr ,
  849. -1, "indented", NULL );
  850. g_free ( tmpstr );
  851. list = list -> next;
  852. }
  853. while ( gtk_notebook_get_n_pages ( g_object_get_data ( G_OBJECT (assistant),
  854. "notebook" ) ) > IMPORT_FIRST_ACCOUNT_PAGE )
  855. {
  856. gtk_notebook_remove_page ( g_object_get_data ( G_OBJECT (assistant), "notebook" ), -1 );
  857. }
  858. affichage_recapitulatif_importation ( assistant );
  859. }
  860. else
  861. {
  862. gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
  863. _("Error !"), -1,
  864. "x-large", NULL);
  865. gtk_text_buffer_insert (buffer, &iter, "\n\n", -1 );
  866. gtk_text_buffer_insert (buffer, &iter,
  867. _("No file has been imported, please double check that they are "
  868. "valid files. Please make sure that they are not compressed and "
  869. "that their format is valid."),
  870. -1 );
  871. if ( strlen ( error_message ) )
  872. {
  873. gtk_text_buffer_insert (buffer, &iter, "\n\n", -1 );
  874. gtk_text_buffer_insert (buffer, &iter, error_message, -1 );
  875. }
  876. gtk_text_buffer_insert (buffer, &iter, "\n\n", -1 );
  877. }
  878. if ( liste_comptes_importes_error )
  879. {
  880. gtk_text_buffer_insert (buffer, &iter, _("The following files are in error: "), -1 );
  881. gtk_text_buffer_insert (buffer, &iter, "\n\n", -1 );
  882. list = liste_comptes_importes_error;
  883. while ( list )
  884. {
  885. struct struct_compte_importation * compte;
  886. compte = list -> data;
  887. tmpstr = g_strconcat ( "• ", compte -> nom_de_compte,
  888. " (",
  889. compte -> origine,
  890. ")\n\n",
  891. NULL );
  892. gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
  893. tmpstr,
  894. -1, "indented", NULL );
  895. g_free ( tmpstr );
  896. list = list -> next;
  897. }
  898. }
  899. return FALSE;
  900. }
  901. /**
  902. *
  903. *
  904. */
  905. GtkWidget *import_create_final_page ( GtkWidget *assistant )
  906. {
  907. GtkWidget * view;
  908. GtkTextBuffer * buffer;
  909. GtkTextIter iter;
  910. view = gtk_text_view_new ();
  911. gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
  912. gtk_text_view_set_editable ( GTK_TEXT_VIEW (view), FALSE );
  913. gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW (view), FALSE );
  914. gtk_text_view_set_left_margin ( GTK_TEXT_VIEW (view), 12 );
  915. gtk_text_view_set_right_margin ( GTK_TEXT_VIEW (view), 12 );
  916. buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
  917. gtk_text_buffer_create_tag ( buffer, "x-large",
  918. "scale", PANGO_SCALE_X_LARGE, NULL);
  919. gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
  920. gtk_text_buffer_insert (buffer, &iter, "\n", -1 );
  921. gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
  922. _("Import terminated"), -1,
  923. "x-large", NULL);
  924. gtk_text_buffer_insert (buffer, &iter, "\n\n", -1 );
  925. gtk_text_buffer_insert (buffer, &iter,
  926. _("You have successfully set up transactions import into Grisbi. "
  927. "Press the 'Close' button to terminate import."),
  928. -1 );
  929. gtk_text_buffer_insert (buffer, &iter, "\n\n", -1 );
  930. return view;
  931. }
  932. /**
  933. *
  934. *
  935. *
  936. */
  937. GSList *import_selected_files ( GtkWidget *assistant )
  938. {
  939. GSList *list = NULL;
  940. GtkTreeModel *model;
  941. GtkTreeIter iter;
  942. model = g_object_get_data ( G_OBJECT ( assistant ), "model" );
  943. g_return_val_if_fail ( model, NULL );
  944. gtk_tree_model_get_iter_first ( model, &iter );
  945. do
  946. {
  947. struct imported_file *imported;
  948. gboolean selected;
  949. imported = g_malloc0 ( sizeof ( struct imported_file ) );
  950. gtk_tree_model_get ( GTK_TREE_MODEL ( model ), &iter,
  951. IMPORT_FILESEL_SELECTED, &selected,
  952. IMPORT_FILESEL_REALNAME, &(imported -> name),
  953. IMPORT_FILESEL_TYPE, &(imported -> type),
  954. IMPORT_FILESEL_CODING, &(imported -> coding_system),
  955. -1 );
  956. if ( selected )
  957. {
  958. list = g_slist_append ( list, imported );
  959. }
  960. }
  961. while ( gtk_tree_model_iter_next ( model, &iter ) );
  962. return list;
  963. }
  964. /**
  965. * this is the summary page of the import assistant
  966. * show what accounts will be imported in grisbi
  967. * and create the next pages of the assistant, one per account
  968. *
  969. * \param assistant
  970. *
  971. * \return FALSE
  972. */
  973. gboolean affichage_recapitulatif_importation ( GtkWidget * assistant )
  974. {
  975. gint page;
  976. GSList *list_tmp;
  977. if (!assistant)
  978. return FALSE;
  979. /* Initial page is fourth. */
  980. page = IMPORT_FIRST_ACCOUNT_PAGE;
  981. /* First, iter to see if we need to create currencies */
  982. list_tmp = liste_comptes_importes;
  983. while ( list_tmp )
  984. {
  985. struct struct_compte_importation * compte;
  986. compte = list_tmp -> data;
  987. /* add one page per account */
  988. gsb_assistant_add_page ( assistant, cree_ligne_recapitulatif ( list_tmp -> data ),
  989. page, page - 1, page + 1, G_CALLBACK ( NULL ) );
  990. page ++;
  991. list_tmp = list_tmp -> next;
  992. }
  993. /* And final page */
  994. gsb_assistant_add_page ( assistant, import_create_final_page ( assistant ),
  995. page, page - 1, -1, G_CALLBACK ( NULL ) );
  996. /* Replace button. */
  997. gsb_assistant_change_button_next ( assistant, GTK_STOCK_GO_FORWARD, GTK_RESPONSE_YES );
  998. return ( FALSE );
  999. }
  1000. /**
  1001. *
  1002. *
  1003. *
  1004. */
  1005. GtkWidget *cree_ligne_recapitulatif ( struct struct_compte_importation * compte )
  1006. {
  1007. GtkWidget * vbox, * hbox, * label, * radio, * radio_add_account,* radiogroup;
  1008. GtkWidget * alignement;
  1009. gchar * short_filename;
  1010. gint size = 0, spacing = 0;
  1011. gint account_number;
  1012. GtkWidget *button;
  1013. gchar* tmpstr;
  1014. vbox = gtk_vbox_new ( FALSE, 6 );
  1015. gtk_container_set_border_width ( GTK_CONTAINER(vbox), 12 );
  1016. if ( compte -> filename )
  1017. short_filename = g_path_get_basename (compte -> filename);
  1018. else
  1019. {
  1020. if (compte -> real_filename)
  1021. short_filename = g_path_get_basename (compte -> real_filename);
  1022. else
  1023. short_filename = g_strdup (_("file"));
  1024. }
  1025. label = gtk_label_new ( NULL );
  1026. gtk_misc_set_alignment ( GTK_MISC ( label ), 0, 0.5);
  1027. gtk_label_set_justify ( GTK_LABEL ( label ), GTK_JUSTIFY_LEFT );
  1028. tmpstr = g_markup_printf_escaped ( _("<span size=\"x-large\">%s</span>\n\n"
  1029. "What do you want to do with contents from <span "
  1030. "foreground=\"blue\">%s</span> ?\n"),
  1031. compte -> nom_de_compte, short_filename );
  1032. gtk_label_set_markup ( GTK_LABEL ( label ), tmpstr );
  1033. g_free ( tmpstr );
  1034. g_free (short_filename);
  1035. gtk_box_pack_start ( GTK_BOX ( vbox ), label, FALSE, FALSE, 0 );
  1036. /* New account */
  1037. radio = gtk_radio_button_new_with_label ( NULL, _("Create a new account") );
  1038. radiogroup = radio;
  1039. gtk_box_pack_start ( GTK_BOX ( vbox ), radio, FALSE, FALSE, 0 );
  1040. gtk_widget_style_get (radio, "indicator_size", &size, NULL);
  1041. gtk_widget_style_get (radio, "indicator_spacing", &spacing, NULL);
  1042. compte -> hbox1 = gtk_hbox_new ( FALSE, 6 );
  1043. gtk_box_pack_start ( GTK_BOX ( vbox ), compte -> hbox1, FALSE, FALSE, 0 );
  1044. label = gtk_label_new ( _("Account type: ") );
  1045. alignement = gtk_alignment_new ( 0.5, 0.5, 1, 1 );
  1046. gtk_container_set_border_width ( GTK_CONTAINER ( alignement ), 2 );
  1047. gtk_alignment_set_padding ( GTK_ALIGNMENT ( alignement ), 0, 0, 2 * spacing + size, 0 );
  1048. gtk_container_add ( GTK_CONTAINER ( alignement ), label );
  1049. gtk_box_pack_start ( GTK_BOX ( compte -> hbox1 ), alignement, FALSE, FALSE, 0 );
  1050. compte -> bouton_type_compte = gsb_combo_box_new_with_index_by_list (
  1051. gsb_account_property_create_combobox_list (),
  1052. NULL, NULL );
  1053. gtk_box_pack_start ( GTK_BOX ( compte -> hbox1 ), compte -> bouton_type_compte,
  1054. TRUE, TRUE, 0 );
  1055. /* at this level imported_account -> type_de_compte was filled while importing transactions,
  1056. * in qif.c or ofx.c ; but we have only 4 kind of account for now, so try to place the combobox correctly
  1057. * and it's the user who will choose the kind of account */
  1058. switch (compte -> type_de_compte)
  1059. {
  1060. case 3:
  1061. gsb_combo_box_set_index ( compte -> bouton_type_compte,
  1062. GSB_TYPE_LIABILITIES );
  1063. break;
  1064. case 7:
  1065. gsb_combo_box_set_index ( compte -> bouton_type_compte,
  1066. GSB_TYPE_CASH );
  1067. break;
  1068. default:
  1069. gsb_combo_box_set_index ( compte -> bouton_type_compte,
  1070. GSB_TYPE_BANK );
  1071. }
  1072. g_object_set_data ( G_OBJECT ( radio ), "associated", compte -> hbox1 );
  1073. g_object_set_data ( G_OBJECT ( radio ), "account", compte );
  1074. g_signal_connect ( G_OBJECT ( radio ), "toggled",
  1075. G_CALLBACK ( import_account_action_activated ), IMPORT_CREATE_ACCOUNT );
  1076. /* Add to account */
  1077. radio_add_account = gtk_radio_button_new_with_label_from_widget ( GTK_RADIO_BUTTON ( radiogroup ),
  1078. _("Add transactions to an account") );
  1079. gtk_box_pack_start ( GTK_BOX ( vbox ), radio_add_account, FALSE, FALSE, 0 );
  1080. if (radio_add_account && GTK_WIDGET_VISIBLE (radio_add_account))
  1081. gtk_widget_set_sensitive ( radio_add_account, assert_account_loaded ( ) );
  1082. compte -> hbox2 = gtk_hbox_new ( FALSE, 6 );
  1083. gtk_box_pack_start ( GTK_BOX ( vbox ), compte -> hbox2, FALSE, FALSE, 0 );
  1084. label = gtk_label_new ( _("Account name: ") );
  1085. alignement = gtk_alignment_new ( 0.5, 0.5, 1, 1 );
  1086. gtk_container_set_border_width ( GTK_CONTAINER ( alignement ), 2 );
  1087. gtk_alignment_set_padding ( GTK_ALIGNMENT ( alignement ), 0, 0, 2 * spacing + size, 0 );
  1088. gtk_container_add ( GTK_CONTAINER ( alignement ), label );
  1089. gtk_box_pack_start ( GTK_BOX ( compte -> hbox2 ), alignement, FALSE, FALSE, 0 );
  1090. compte -> bouton_compte_add = gsb_account_create_combo_list (NULL, NULL, FALSE);
  1091. gtk_box_pack_start ( GTK_BOX ( compte -> hbox2 ), compte -> bouton_compte_add, TRUE, TRUE, 0 );
  1092. gtk_widget_set_sensitive ( compte -> hbox2, FALSE );
  1093. g_object_set_data ( G_OBJECT ( radio_add_account ), "associated", compte -> hbox2 );
  1094. g_object_set_data ( G_OBJECT ( radio_add_account ), "account", compte );
  1095. g_signal_connect ( G_OBJECT ( radio_add_account ), "toggled",
  1096. G_CALLBACK ( import_account_action_activated ),
  1097. GINT_TO_POINTER (IMPORT_ADD_TRANSACTIONS));
  1098. /* Mark account */
  1099. radio = gtk_radio_button_new_with_label_from_widget ( GTK_RADIO_BUTTON ( radiogroup ),
  1100. _("Mark transactions of an account") );
  1101. gtk_box_pack_start ( GTK_BOX ( vbox ), radio, FALSE, FALSE, 0 );
  1102. gtk_widget_set_sensitive ( radio, assert_account_loaded ( ) );
  1103. compte -> hbox3 = gtk_hbox_new ( FALSE, 6 );
  1104. gtk_box_pack_start ( GTK_BOX ( vbox ), compte -> hbox3, FALSE, FALSE, 0 );
  1105. label = gtk_label_new ( _("Account name: ") );
  1106. alignement = gtk_alignment_new ( 0.5, 0.5, 1, 1 );
  1107. gtk_container_set_border_width ( GTK_CONTAINER ( alignement ), 2 );
  1108. gtk_alignment_set_padding ( GTK_ALIGNMENT ( alignement ), 0, 0, 2 * spacing + size, 0 );
  1109. gtk_container_add ( GTK_CONTAINER ( alignement ), label );
  1110. gtk_box_pack_start ( GTK_BOX ( compte -> hbox3 ), alignement, FALSE, FALSE, 0 );
  1111. compte -> bouton_compte_mark = gsb_account_create_combo_list (NULL, NULL, FALSE);
  1112. gtk_box_pack_start ( GTK_BOX ( compte -> hbox3 ), compte -> bouton_compte_mark, TRUE, TRUE, 0 );
  1113. gtk_widget_set_sensitive ( compte -> hbox3, FALSE );
  1114. g_object_set_data ( G_OBJECT ( radio ), "associated", compte -> hbox3 );
  1115. g_object_set_data ( G_OBJECT ( radio ), "account", compte );
  1116. g_signal_connect ( G_OBJECT ( radio ), "toggled",
  1117. G_CALLBACK ( import_account_action_activated ),
  1118. GINT_TO_POINTER (IMPORT_MARK_TRANSACTIONS));
  1119. /* set on the right account */
  1120. account_number = gsb_data_account_get_account_by_id ( compte->id_compte );
  1121. if ( account_number >= 0 )
  1122. {
  1123. import_account_action_activated ( radio_add_account,IMPORT_ADD_TRANSACTIONS );
  1124. gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( radio_add_account ), TRUE );
  1125. gsb_account_set_combo_account_number ( compte -> bouton_compte_add, account_number );
  1126. gsb_account_set_combo_account_number ( compte -> bouton_compte_mark, account_number );
  1127. }
  1128. /* Currency */
  1129. hbox = gtk_hbox_new ( FALSE, 6 );
  1130. label = gtk_label_new ( _("Account currency: ") );
  1131. gtk_box_pack_start ( GTK_BOX ( hbox ), label, FALSE, FALSE, 0 );
  1132. gtk_box_pack_start ( GTK_BOX ( vbox ), hbox, FALSE, FALSE, 0 );
  1133. compte -> bouton_devise = gsb_currency_make_combobox ( TRUE );
  1134. /* create the currency if doesn't exist */
  1135. if ( compte -> devise )
  1136. {
  1137. gint currency_number;
  1138. /* First, we search currency from ISO4217 code for existing currencies */
  1139. currency_number = gsb_data_currency_get_number_by_code_iso4217 ( compte -> devise );
  1140. /* Then, by nickname for existing currencies */
  1141. if ( !currency_number )
  1142. {
  1143. currency_number = gsb_import_add_currency ( compte );
  1144. if ( currency_number == 0 )
  1145. currency_number = gsb_data_currency_get_number_by_name ( compte -> devise );
  1146. }
  1147. if ( currency_number )
  1148. gsb_currency_set_combobox_history ( compte -> bouton_devise,
  1149. currency_number );
  1150. else
  1151. currency_number = gsb_import_add_currency ( compte );
  1152. }
  1153. gtk_box_pack_start ( GTK_BOX ( hbox ), compte -> bouton_devise, FALSE, FALSE, 0 );
  1154. /* invert amount of transactions */
  1155. button = gsb_automem_checkbutton_new (_("Invert the amount of the imported transactions"),
  1156. &compte -> invert_transaction_amount, NULL, NULL);
  1157. gtk_box_pack_start ( GTK_BOX ( vbox ), button, FALSE, FALSE, 0 );
  1158. /* propose to create a rule */
  1159. compte -> hbox_rule = gtk_hbox_new (FALSE, 5);
  1160. gtk_box_pack_start ( GTK_BOX ( vbox ), compte -> hbox_rule, FALSE, FALSE, 0 );
  1161. compte -> entry_name_rule = gtk_entry_new ();
  1162. button = gsb_automem_checkbutton_new (_("Create a rule for this import. Name of the rule : "),
  1163. &compte -> create_rule, G_CALLBACK (
  1164. gsb_button_sensitive_by_checkbutton),
  1165. compte -> entry_name_rule);
  1166. gtk_box_pack_start ( GTK_BOX (compte -> hbox_rule), button, FALSE, FALSE, 0 );
  1167. /* we can create a rule only for qif or ofx */
  1168. if (strcmp (compte -> origine, "QIF") && strcmp (compte -> origine, "OFX"))
  1169. gtk_widget_set_sensitive (button, FALSE);
  1170. gtk_widget_set_sensitive (compte -> entry_name_rule, FALSE);
  1171. gtk_box_pack_start ( GTK_BOX (compte -> hbox_rule),
  1172. compte -> entry_name_rule, FALSE, FALSE, 0 );
  1173. return vbox;
  1174. }
  1175. /**
  1176. *
  1177. *
  1178. *
  1179. */
  1180. gint gsb_import_add_currency ( struct struct_compte_importation * compte )
  1181. {
  1182. GtkWidget *vbox, *checkbox, *dialog;
  1183. gint response;
  1184. gchar *tmpstr;
  1185. gchar *tmpstr2;
  1186. gchar *text;
  1187. gint currency_number = 0;
  1188. tmpstr = g_strdup_printf (
  1189. _("The account currency imported %s is %s.\nThis currency "
  1190. "doesn't exist so you have to create it by selecting OK.\n"
  1191. "\n"
  1192. "Do you create it ?"),
  1193. compte -> nom_de_compte,
  1194. compte -> devise );
  1195. tmpstr2 = g_strdup_printf (
  1196. _("Can't associate ISO 4217 code for currency '%s'."),
  1197. compte -> devise );
  1198. text = make_hint ( tmpstr2, tmpstr );
  1199. g_free ( tmpstr );
  1200. g_free ( tmpstr2 );
  1201. dialog = gtk_message_dialog_new ( GTK_WINDOW ( window ),
  1202. GTK_DIALOG_DESTROY_WITH_PARENT,
  1203. GTK_MESSAGE_QUESTION,
  1204. GTK_BUTTONS_YES_NO,
  1205. "%s", text );
  1206. gtk_label_set_markup ( GTK_LABEL ( GTK_MESSAGE_DIALOG ( dialog ) ->label ), text );
  1207. vbox = GTK_DIALOG(dialog) -> vbox;
  1208. checkbox = gtk_check_button_new_with_label (
  1209. _("Use this currency for totals for the payees categories\n"
  1210. "and budgetary lines") );
  1211. gtk_box_pack_start ( GTK_BOX ( vbox ), checkbox, TRUE, TRUE, 6 );
  1212. gtk_widget_show_all ( checkbox );
  1213. gtk_window_set_modal ( GTK_WINDOW ( dialog ), TRUE );
  1214. response = gtk_dialog_run (GTK_DIALOG (dialog));
  1215. if ( response == GTK_RESPONSE_YES
  1216. &&
  1217. gsb_currency_config_add_currency ( NULL, NULL ) )
  1218. {
  1219. currency_number = gsb_data_currency_get_number_by_code_iso4217 (
  1220. compte -> devise );
  1221. if ( gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbox ) ) )
  1222. {
  1223. no_devise_totaux_tiers = currency_number;
  1224. no_devise_totaux_categ = currency_number;
  1225. no_devise_totaux_ib = currency_number;
  1226. }
  1227. }
  1228. gtk_widget_destroy ( dialog );
  1229. return currency_number;
  1230. }
  1231. /**
  1232. *
  1233. *
  1234. */
  1235. gboolean import_account_action_activated ( GtkWidget * radio, gint action )
  1236. {
  1237. struct struct_compte_importation * account;
  1238. account = g_object_get_data ( G_OBJECT ( radio ), "account" );
  1239. if (account -> hbox1 && GTK_WIDGET_VISIBLE (account -> hbox1))
  1240. gtk_widget_set_sensitive ( account -> hbox1, FALSE );
  1241. if (account -> hbox2 && GTK_WIDGET_VISIBLE (account -> hbox2))
  1242. gtk_widget_set_sensitive ( account -> hbox2, FALSE );
  1243. if (account -> hbox3 && GTK_WIDGET_VISIBLE (account -> hbox3))
  1244. gtk_widget_set_sensitive ( account -> hbox3, FALSE );
  1245. gtk_widget_set_sensitive ( g_object_get_data ( G_OBJECT ( radio ), "associated" ), TRUE );
  1246. account -> action = action;
  1247. if ( account -> hbox_rule && GTK_WIDGET_VISIBLE (account -> hbox_rule) )
  1248. gtk_widget_set_sensitive ( account -> hbox_rule, action != IMPORT_CREATE_ACCOUNT );
  1249. return FALSE;
  1250. }
  1251. /**
  1252. * finish the import
  1253. * go throw all the imported accounts and does what the user asked with
  1254. * each of them
  1255. *
  1256. * \param
  1257. *
  1258. * \return
  1259. * */
  1260. void traitement_operations_importees ( void )
  1261. {
  1262. GSList *list_tmp;
  1263. gint new_file;
  1264. /* when come here, all the currencies are already created
  1265. * and init_variables is already called
  1266. * ( see affichage_recapitulatif_importation) */
  1267. /* if new file, init grisbi */
  1268. if ( gsb_data_account_get_accounts_amount () )
  1269. new_file = 0;
  1270. else
  1271. {
  1272. /* Create initial lists. */
  1273. new_file = 1;
  1274. }
  1275. /* for now, no marked transactions imported */
  1276. marked_r_transactions_imported = FALSE;
  1277. /* go throw the accounts and do what is asked */
  1278. list_tmp = liste_comptes_importes;
  1279. while ( list_tmp )
  1280. {
  1281. struct struct_compte_importation *compte;
  1282. gint account_number = 0;
  1283. compte = list_tmp -> data;
  1284. switch ( compte -> action )
  1285. {
  1286. case IMPORT_CREATE_ACCOUNT:
  1287. account_number = gsb_import_create_imported_account ( compte );
  1288. if ( account_number == -1 )
  1289. {
  1290. gchar* tmpstr = g_strdup_printf ( _("An error occured while creating the new "
  1291. "account %s,\nWe try to continue to import "
  1292. "but bad things can happen..."),
  1293. compte -> nom_de_compte);
  1294. dialogue_error ( tmpstr);
  1295. g_free ( tmpstr );
  1296. continue;
  1297. }
  1298. /* the next functions will add the transaction to the tree view list
  1299. * so if we create a new file, we need to finish the gui here to append
  1300. * the transactions */
  1301. if (new_file)
  1302. {
  1303. /* this should be the same as the end of gsb_file_new */
  1304. /* init the gui */
  1305. gsb_file_new_gui ();
  1306. new_file = 0;
  1307. }
  1308. else
  1309. gsb_gui_navigation_add_account ( account_number, FALSE );
  1310. gsb_import_create_imported_transactions ( compte, account_number );
  1311. break;
  1312. case IMPORT_ADD_TRANSACTIONS:
  1313. account_number = gsb_account_get_combo_account_number ( compte -> bouton_compte_add );
  1314. gsb_import_add_imported_transactions ( compte,account_number);
  1315. break;
  1316. case IMPORT_MARK_TRANSACTIONS:
  1317. account_number = gsb_account_get_combo_account_number ( compte -> bouton_compte_mark );
  1318. pointe_opes_importees ( compte, account_number );
  1319. transaction_list_update_element (ELEMENT_MARK);
  1320. break;
  1321. }
  1322. /* MAJ du solde du compte nécessaire suivant date des opérations existantes */
  1323. if ( conf.balances_with_scheduled == FALSE )
  1324. gsb_data_account_set_balances_are_dirty ( account_number );
  1325. /* MAJ des données du module bet */
  1326. gsb_data_account_set_bet_maj ( account_number, BET_MAJ_ALL );
  1327. /* first, we create the rule if asked */
  1328. if (compte -> create_rule && compte -> action != IMPORT_CREATE_ACCOUNT)
  1329. {
  1330. /* ok, we create the rule */
  1331. gint rule;
  1332. const gchar *name;
  1333. name = gtk_entry_get_text (GTK_ENTRY (compte -> entry_name_rule));
  1334. if (!strlen (name))
  1335. {
  1336. /* the user didn't enter a name, propose now */
  1337. gchar *tmpstr;
  1338. tmpstr = g_strdup_printf ( _("You want to create an import rule for the account %s "
  1339. "but didn't give a name to that rule. Please set a "
  1340. "name or let it empty to cancel the rule creation."),
  1341. gsb_data_account_get_name (account_number));
  1342. name = dialogue_hint_with_entry (tmpstr, _("No name for the import rule"),
  1343. _("Name of the rule: "));
  1344. g_free (tmpstr);
  1345. }
  1346. if (!strlen (name))
  1347. break;
  1348. rule = gsb_data_import_rule_new (name);
  1349. gsb_data_import_rule_set_account (rule, account_number);
  1350. gsb_data_import_rule_set_currency (rule, gsb_currency_get_currency_from_combobox (compte -> bouton_devise));
  1351. gsb_data_import_rule_set_invert (rule, compte -> invert_transaction_amount);
  1352. gsb_data_import_rule_set_charmap (rule, charmap_imported);
  1353. gsb_data_import_rule_set_last_file_name (rule, compte -> real_filename);
  1354. gsb_data_import_rule_set_action (rule, compte -> action);
  1355. }
  1356. if ( ! strcmp ( compte -> origine, "OFX" ) )
  1357. {
  1358. g_remove (compte -> real_filename);
  1359. }
  1360. list_tmp = list_tmp -> next;
  1361. }
  1362. /* if no account created, there is a problem
  1363. * show an error and go away */
  1364. if (!gsb_data_account_get_accounts_amount ())
  1365. {
  1366. dialogue_error (_("No account in memory now, this is bad...\nBetter to leave "
  1367. "the import before a crash.\n\nPlease contact the grisbi team "
  1368. "to find the problem."));
  1369. return;
  1370. }
  1371. /* create the links between transactions (transfer) */
  1372. if ( virements_a_chercher )
  1373. cree_liens_virements_ope_import ();
  1374. gsb_status_message ( _("Please wait") );
  1375. /* update the name of accounts in scheduler form */
  1376. gsb_account_update_combo_list (
  1377. gsb_form_scheduler_get_element_widget ( SCHEDULED_FORM_ACCOUNT ),
  1378. FALSE );
  1379. /* set the rule button if necessary */
  1380. if ( gsb_data_import_rule_account_has_rule (gsb_gui_navigation_get_current_account ()))
  1381. gtk_widget_show (menu_import_rules);
  1382. else
  1383. gtk_widget_hide (menu_import_rules);
  1384. /* show the account list */
  1385. gsb_menu_update_accounts_in_menus();
  1386. /* update main page */
  1387. mise_a_jour_liste_comptes_accueil = 1;
  1388. mise_a_jour_soldes_minimaux = 1;
  1389. mise_a_jour_accueil (FALSE);
  1390. gsb_status_clear();
  1391. /* if some R marked transactions are imported, show a message */
  1392. if (marked_r_transactions_imported)
  1393. dialogue ( _("You have just imported reconciled transactions but they not associated "
  1394. "with any reconcile number yet. You may associate them with a reconcilation "
  1395. "later via the preferences windows.") );
  1396. if ( etat.modification_fichier == 0 )
  1397. modification_fichier ( TRUE );
  1398. }
  1399. /**
  1400. * called at the end of an import, check all the transactions wich need a link
  1401. * to another transaction.
  1402. * we can find that transactions because they have contra_transaction_number to -1
  1403. * and the bank_references is the name of the contra account, with [ ]
  1404. *
  1405. * that function try to find the contra-transaction and create the link
  1406. *
  1407. * */
  1408. void cree_liens_virements_ope_import ( void )
  1409. {
  1410. GSList *list_tmp_transactions;
  1411. list_tmp_transactions = gsb_data_transaction_get_transactions_list ();
  1412. while ( list_tmp_transactions )
  1413. {
  1414. gint transaction_number_tmp;
  1415. transaction_number_tmp = gsb_data_transaction_get_transaction_number (list_tmp_transactions -> data);
  1416. /* if the contra transaction number is -1, it's a transfer,
  1417. * in that case, the name of the contra account is in the bank_references */
  1418. if ( gsb_data_transaction_get_contra_transaction_number (transaction_number_tmp)== -1
  1419. &&
  1420. gsb_data_transaction_get_bank_references (transaction_number_tmp))
  1421. {
  1422. /* the name of the contra account is in the bank references with [ and ] */
  1423. gchar *contra_account_name;
  1424. gint contra_account_number;
  1425. contra_account_name = my_strdelimit (gsb_data_transaction_get_bank_references (transaction_number_tmp),
  1426. "[]", "");
  1427. contra_account_number = gsb_data_account_get_no_account_by_name ( contra_account_name );
  1428. g_free (contra_account_name);
  1429. /* now we needn't the bank reference anymore */
  1430. gsb_data_transaction_set_bank_references ( transaction_number_tmp, NULL );
  1431. if ( contra_account_number == -1 )
  1432. {
  1433. /* we have not found the contra-account */
  1434. gsb_data_transaction_set_contra_transaction_number ( transaction_number_tmp,
  1435. 0);
  1436. }
  1437. else
  1438. {
  1439. /* we have found the contra-account, we look for the contra-transaction */
  1440. GSList *list_tmp_transactions_2;
  1441. gint transaction_account = gsb_data_transaction_get_account_number (transaction_number_tmp);
  1442. list_tmp_transactions_2 = gsb_data_transaction_get_transactions_list ();
  1443. while ( list_tmp_transactions_2 )
  1444. {
  1445. gint contra_transaction_number_tmp;
  1446. gint contra_transaction_account;
  1447. contra_transaction_number_tmp = gsb_data_transaction_get_transaction_number (list_tmp_transactions_2 -> data);
  1448. contra_transaction_account = gsb_data_transaction_get_account_number (contra_transaction_number_tmp);
  1449. if (contra_account_number == contra_transaction_account
  1450. &&
  1451. gsb_import_check_transaction_link (transaction_number_tmp, contra_transaction_number_tmp))
  1452. {
  1453. /* we have found the contra transaction, set all the values */
  1454. gint payment_number;
  1455. gsb_data_transaction_set_contra_transaction_number ( transaction_number_tmp,
  1456. contra_transaction_number_tmp );
  1457. gsb_data_transaction_set_contra_transaction_number ( contra_transaction_number_tmp,
  1458. transaction_number_tmp);
  1459. /* unset the reference of the contra transaction */
  1460. gsb_data_transaction_set_bank_references ( contra_transaction_number_tmp,
  1461. NULL );
  1462. /* try to set the good method of payment to transfer */
  1463. payment_number = gsb_data_payment_get_transfer_payment_number (transaction_account);
  1464. if (payment_number)
  1465. gsb_data_transaction_set_method_of_payment_number (transaction_number_tmp, payment_number);
  1466. payment_number = gsb_data_payment_get_transfer_payment_number (contra_transaction_account);
  1467. if (payment_number)
  1468. gsb_data_transaction_set_method_of_payment_number (contra_transaction_number_tmp, payment_number);
  1469. }
  1470. list_tmp_transactions_2 = list_tmp_transactions_2 -> next;
  1471. }
  1472. /* if no contra-transaction, that transaction becomes normal */
  1473. if (gsb_data_transaction_get_contra_transaction_number (transaction_number_tmp) == -1)
  1474. /* the contra transaction is still -1, so no contra transaction found, unset that */
  1475. gsb_data_transaction_set_contra_transaction_number ( transaction_number_tmp,
  1476. 0);
  1477. }
  1478. }
  1479. list_tmp_transactions = list_tmp_transactions -> next;
  1480. }
  1481. /* the transactions were already set in the list,
  1482. * and the transfer was not written, we need to update the categories values
  1483. * in the lists */
  1484. transaction_list_update_element (ELEMENT_CATEGORY);
  1485. transaction_list_update_element (ELEMENT_PAYMENT_TYPE);
  1486. }
  1487. /**
  1488. * check if the transaction 2 is the link of the transaction 1
  1489. * called after importing to create the link
  1490. *
  1491. * \param transaction_number
  1492. * \param tested_transaction
  1493. *
  1494. * \return TRUE : the transactions are linked, FALSE : the transactions are different
  1495. * */
  1496. gboolean gsb_import_check_transaction_link ( gint transaction_number,
  1497. gint tested_transaction )
  1498. {
  1499. gchar *contra_account_name;
  1500. gint contra_account_number;
  1501. gsb_real amount_1, amount_2;
  1502. /* we check first the easy and quick things, and if all ok, comes after the check
  1503. * which need some time */
  1504. /* check if the contra transaction number of the tested transaction is -1 (ie imported transfer) */
  1505. if (gsb_data_transaction_get_contra_transaction_number (tested_transaction) != -1)
  1506. return FALSE;
  1507. /* check if there is a contra account name */
  1508. if (!gsb_data_transaction_get_bank_references (tested_transaction))
  1509. return FALSE;
  1510. /* check same payee */
  1511. if (gsb_data_transaction_get_party_number (transaction_number) != gsb_data_transaction_get_party_number (tested_transaction))
  1512. return FALSE;
  1513. /* check same date */
  1514. if (g_date_compare ( gsb_data_transaction_get_date (transaction_number),
  1515. gsb_data_transaction_get_date (tested_transaction)))
  1516. return FALSE;
  1517. /* check if same amount (but opposite) */
  1518. amount_1 = gsb_real_abs (gsb_data_transaction_get_amount (transaction_number));
  1519. amount_2 = gsb_real_abs (gsb_data_transaction_get_adjusted_amount_for_currency ( tested_transaction,
  1520. gsb_data_transaction_get_currency_number (transaction_number),
  1521. -1));
  1522. if (gsb_real_cmp (amount_1, amount_2))
  1523. return FALSE;
  1524. /* check if the contra account name of the tested transaction is the account of the transaction */
  1525. contra_account_name = my_strdelimit (gsb_data_transaction_get_bank_references (tested_transaction),
  1526. "[]", "");
  1527. contra_account_number = gsb_data_account_get_no_account_by_name ( contra_account_name );
  1528. g_free (contra_account_name);
  1529. if (gsb_data_transaction_get_account_number (transaction_number) != contra_account_number)
  1530. return FALSE;
  1531. /* all seems the same, can return TRUE */
  1532. return TRUE;
  1533. }
  1534. /**
  1535. * create a new account with the datas in the imported account given in args
  1536. * don't work with the gui here, all the gui will be done later
  1537. *
  1538. * \param imported_account the account we want to create
  1539. *
  1540. * \return the number of the new account or -1 if problem
  1541. * */
  1542. gint gsb_import_create_imported_account ( struct struct_compte_importation *imported_account )
  1543. {
  1544. gint account_number;
  1545. gint kind_account;
  1546. if (!imported_account)
  1547. return -1;
  1548. /* create the new account,
  1549. * for now 3 kind of account, GSB_TYPE_BANK, GSB_TYPE_LIABILITIES or GSB_TYPE_CASH */
  1550. switch (gsb_combo_box_get_index (imported_account -> bouton_type_compte))
  1551. {
  1552. case 2:
  1553. kind_account = GSB_TYPE_LIABILITIES;
  1554. break;
  1555. case 1:
  1556. kind_account = GSB_TYPE_CASH;
  1557. break;
  1558. default:
  1559. kind_account = GSB_TYPE_BANK;
  1560. }
  1561. account_number = gsb_data_account_new (kind_account);
  1562. if ( account_number == -1 )
  1563. return -1;
  1564. /* set the default method of payment */
  1565. gsb_data_payment_create_default (account_number);
  1566. /* set the id and try to find the bank */
  1567. if ( imported_account -> id_compte )
  1568. {
  1569. gchar **tab_str;
  1570. gsb_data_account_set_id (account_number,
  1571. imported_account -> id_compte );
  1572. /* usually, the id is "bank_number guichet_number account_number key"
  1573. * try to get the datas */
  1574. tab_str = g_strsplit ( gsb_data_account_get_id (account_number),
  1575. " ",
  1576. 3 );
  1577. if ( tab_str[1] )
  1578. {
  1579. gsb_data_account_set_bank_branch_code ( account_number,
  1580. tab_str[1] );
  1581. if ( tab_str[2] )
  1582. {
  1583. gchar *temp;
  1584. gsb_data_account_set_bank_account_key ( account_number,
  1585. tab_str[2] + strlen ( tab_str[2] ) - 1 );
  1586. temp = my_strdup ( tab_str[2] );
  1587. if ( temp && strlen(temp) )
  1588. {
  1589. temp[strlen (temp) - 1 ] = 0;
  1590. gsb_data_account_set_bank_account_number ( account_number, temp );
  1591. g_free (temp);
  1592. }
  1593. }
  1594. }
  1595. g_strfreev ( tab_str );
  1596. }
  1597. /* set the name (the g_strstrip is VERY important !!!) */
  1598. if ( imported_account -> nom_de_compte )
  1599. gsb_data_account_set_name ( account_number,
  1600. g_strstrip (imported_account -> nom_de_compte));
  1601. else
  1602. gsb_data_account_set_name ( account_number,
  1603. _("Imported account"));
  1604. /* set the currency */
  1605. gsb_data_account_set_currency ( account_number,
  1606. gsb_currency_get_currency_from_combobox (imported_account -> bouton_devise));
  1607. /* set the initial balance */
  1608. gsb_data_account_set_init_balance ( account_number,
  1609. imported_account -> solde);
  1610. /* Use two lines view by default. */
  1611. gsb_data_account_set_nb_rows ( account_number, 2 );
  1612. /* set the new form organization */
  1613. gsb_data_form_new_organization ( account_number );
  1614. gsb_data_form_set_default_organization ( account_number );
  1615. return account_number;
  1616. }
  1617. /**
  1618. * import the transactions in a new account.
  1619. *
  1620. * \param imported_account an imported structure account which contains the transactions
  1621. * \param account_number the number of account where we want to put the new transations
  1622. *
  1623. * \return
  1624. * */
  1625. void gsb_import_create_imported_transactions ( struct struct_compte_importation *imported_account,
  1626. gint account_number )
  1627. {
  1628. GtkWidget *progress = NULL;
  1629. GSList *list_tmp;
  1630. gint nbre_transaction;
  1631. mother_transaction_number = 0;
  1632. list_tmp = imported_account -> operations_importees;
  1633. nbre_transaction = g_slist_length ( list_tmp );
  1634. if ( nbre_transaction > NBRE_TRANSACTION_FOR_PROGRESS_BAR )
  1635. progress = gsb_import_progress_bar_affiche ( imported_account );
  1636. while ( list_tmp )
  1637. {
  1638. struct struct_ope_importation *imported_transaction;
  1639. gint transaction_number;
  1640. if ( nbre_transaction > NBRE_TRANSACTION_FOR_PROGRESS_BAR )
  1641. {
  1642. gsb_import_progress_bar_pulse ( progress, nbre_transaction );
  1643. while ( gtk_events_pending () ) gtk_main_iteration ( );
  1644. nbre_transaction --;
  1645. }
  1646. imported_transaction = list_tmp -> data;
  1647. /* set the account currency to the transaction and create the transaction */
  1648. if (imported_account -> bouton_devise)
  1649. imported_transaction -> devise = gsb_currency_get_currency_from_combobox (
  1650. imported_account -> bouton_devise );
  1651. else
  1652. imported_transaction -> devise = gsb_data_currency_get_number_by_code_iso4217 (
  1653. imported_account -> devise );
  1654. transaction_number = gsb_import_create_transaction ( imported_transaction,
  1655. account_number, imported_account -> origine );
  1656. /* invert the amount of the transaction if asked */
  1657. if ( imported_account -> invert_transaction_amount )
  1658. gsb_data_transaction_set_amount ( transaction_number,
  1659. gsb_real_opposite (gsb_data_transaction_get_amount (
  1660. transaction_number ) ) );
  1661. /* we need to add the transaction now to the tree model here
  1662. * to avoid to write again all the account */
  1663. gsb_transactions_list_append_new_transaction ( transaction_number, FALSE );
  1664. list_tmp = list_tmp -> next;
  1665. }
  1666. if ( progress )
  1667. gtk_widget_destroy ( progress );
  1668. /* some payee should have been added, so update the combofix */
  1669. gsb_payee_update_combofix ();
  1670. }
  1671. /**
  1672. * import the transactions in an existent account
  1673. * check the id of the account and if the transaction already exists
  1674. * add too the transactions to the gui
  1675. *
  1676. * \param imported_account an imported structure account which contains the transactions
  1677. * \param account_number the number of account where we want to put the new transations
  1678. *
  1679. * \return
  1680. * */
  1681. void gsb_import_add_imported_transactions ( struct struct_compte_importation *imported_account,
  1682. gint account_number )
  1683. {
  1684. GSList *list_tmp;
  1685. GDate *first_date_import = NULL;
  1686. gint demande_confirmation;
  1687. /* check the imported account id, and set it in the grisbi account if it doesn't
  1688. * exist or if it's wrong */
  1689. if ( imported_account -> id_compte )
  1690. {
  1691. if ( ! gsb_import_set_id_compte ( account_number, imported_account -> id_compte ) )
  1692. return;
  1693. }
  1694. /* on fait un premier tour de la liste des opés pour repérer celles qui sont déjŕ entrées
  1695. * si on n'importe que du ofx, c'est facile, chaque opé est repérée par une id
  1696. * donc si l'opé importée a une id, il suffit de rechercher l'id dans le compte, si elle
  1697. * n'y est pas l'opé est ŕ enregistrer
  1698. * si on importe du qif, il n'y a pas d'id. donc soit on retrouve une opé semblable
  1699. * (cad męme montant et męme date, on ne fait pas joujou avec le tiers car l'utilisateur
  1700. * a pu le changer), et on demande ŕ l'utilisateur quoi faire, sinon on enregistre l'opé
  1701. */
  1702. /* pour gagner en rapidité, on va récupérer la date de la premičre
  1703. * opération qui est dans le fichier importé */
  1704. first_date_import = gsb_import_get_first_date ( imported_account -> operations_importees );
  1705. /* ok, now first_date_import contains the firt transaction date used in that account,
  1706. * can check the imported transactions */
  1707. demande_confirmation = gsb_import_define_action ( imported_account,
  1708. account_number,
  1709. first_date_import );
  1710. /* if we are not sure about some transactions, ask now */
  1711. if ( demande_confirmation )
  1712. confirmation_enregistrement_ope_import ( imported_account, account_number );
  1713. /* ok, now we know what to do for each transactions, can import to the account */
  1714. mother_transaction_number = 0;
  1715. list_tmp = imported_account -> operations_importees;
  1716. while ( list_tmp )
  1717. {
  1718. struct struct_ope_importation *imported_transaction;
  1719. imported_transaction = list_tmp -> data;
  1720. if ( imported_transaction -> action == IMPORT_TRANSACTION_GET_TRANSACTION )
  1721. {
  1722. gint transaction_number;
  1723. /* set the account currency to the transaction and create the transaction */
  1724. if (imported_account -> bouton_devise)
  1725. imported_transaction -> devise = gsb_currency_get_currency_from_combobox (
  1726. imported_account -> bouton_devise);
  1727. else
  1728. imported_transaction -> devise = gsb_data_currency_get_number_by_code_iso4217 (
  1729. imported_account -> devise);
  1730. transaction_number = gsb_import_create_transaction ( imported_transaction,
  1731. account_number, imported_account -> origine );
  1732. if ( etat.get_fusion_import_transactions &&
  1733. imported_transaction -> ope_correspondante > 0 )
  1734. {
  1735. gsb_transactions_list_update_transaction ( transaction_number );
  1736. list_tmp = list_tmp -> next;
  1737. continue;
  1738. }
  1739. /* invert the amount of the transaction if asked */
  1740. if (imported_account -> invert_transaction_amount)
  1741. gsb_data_transaction_set_amount ( transaction_number,
  1742. gsb_real_opposite (gsb_data_transaction_get_amount (
  1743. transaction_number ) ) );
  1744. /* we need to add the transaction now to the tree model here
  1745. * to avoid to write again all the account */
  1746. gsb_transactions_list_append_new_transaction ( transaction_number, FALSE );
  1747. }
  1748. list_tmp = list_tmp -> next;
  1749. }
  1750. /** some payee should have been added, so update the combofix */
  1751. gsb_payee_update_combofix ();
  1752. /* if we are on the current account, we need to update the tree_view */
  1753. if (gsb_gui_navigation_get_current_account () == account_number)
  1754. {
  1755. gsb_transactions_list_update_tree_view (account_number, TRUE);
  1756. gsb_data_account_colorize_current_balance ( account_number );
  1757. }
  1758. }
  1759. /**
  1760. *
  1761. *
  1762. *
  1763. * \param
  1764. *
  1765. * return
  1766. */
  1767. gboolean gsb_import_define_action ( struct struct_compte_importation *imported_account,
  1768. gint account_number,
  1769. GDate *first_date_import )
  1770. {
  1771. GSList *list_tmp;
  1772. gint demande_confirmation = FALSE;
  1773. GSList *list_tmp_transactions;
  1774. list_tmp = imported_account -> operations_importees;
  1775. while ( list_tmp )
  1776. {
  1777. struct struct_ope_importation *imported_transaction;
  1778. gint transaction_no;
  1779. imported_transaction = list_tmp -> data;
  1780. /* on corrige le bug de la libofx */
  1781. if ( imported_account -> origine
  1782. && g_ascii_strcasecmp (imported_account -> origine, "OFX") == 0
  1783. && imported_transaction -> cheque )
  1784. imported_transaction -> tiers = my_strdelimit (
  1785. imported_transaction -> tiers, "&", "°" );
  1786. /* first check the id */
  1787. if ( imported_transaction -> id_operation
  1788. &&
  1789. ( transaction_no = gsb_data_transaction_find_by_id (
  1790. imported_transaction -> id_operation, account_number ) ) )
  1791. {
  1792. /* the id exists with the same account_nb, so the transaction is already
  1793. * in grisbi we will forget that transaction */
  1794. if ( g_date_compare ( imported_transaction -> date,
  1795. gsb_data_transaction_get_date ( transaction_no ) ) == 0 )
  1796. {
  1797. imported_transaction -> action = IMPORT_TRANSACTION_LEAVE_TRANSACTION;
  1798. }
  1799. }
  1800. /* if no id, check the cheque */
  1801. if ( imported_transaction -> action != IMPORT_TRANSACTION_LEAVE_TRANSACTION
  1802. &&
  1803. imported_transaction -> cheque
  1804. &&
  1805. gsb_data_transaction_find_by_payment_content ( imported_transaction -> cheque,
  1806. account_number ) )
  1807. {
  1808. /* found the cheque, forget that transaction */
  1809. imported_transaction -> action = IMPORT_TRANSACTION_LEAVE_TRANSACTION;
  1810. }
  1811. /* no id, no cheque, try to find the transaction */
  1812. if ( imported_transaction -> action != IMPORT_TRANSACTION_LEAVE_TRANSACTION )
  1813. {
  1814. list_tmp_transactions = gsb_data_transaction_get_transactions_list ();
  1815. while ( list_tmp_transactions )
  1816. {
  1817. gint transaction_number;
  1818. transaction_number = gsb_data_transaction_get_transaction_number (
  1819. list_tmp_transactions -> data);
  1820. if ( gsb_data_transaction_get_account_number (
  1821. transaction_number ) == account_number
  1822. &&
  1823. g_date_compare ( gsb_data_transaction_get_date ( transaction_number ),
  1824. first_date_import ) > 0 )
  1825. {
  1826. GDate *date_debut_comparaison;
  1827. GDate *date_fin_comparaison;
  1828. date_debut_comparaison = g_date_new_dmy ( g_date_get_day ( imported_transaction -> date ),
  1829. g_date_get_month ( imported_transaction -> date ),
  1830. g_date_get_year ( imported_transaction -> date ));
  1831. g_date_subtract_days ( date_debut_comparaison,
  1832. valeur_echelle_recherche_date_import );
  1833. date_fin_comparaison = g_date_new_dmy ( g_date_get_day ( imported_transaction -> date ),
  1834. g_date_get_month ( imported_transaction -> date ),
  1835. g_date_get_year ( imported_transaction -> date ));
  1836. g_date_add_days ( date_fin_comparaison,
  1837. valeur_echelle_recherche_date_import );
  1838. if ( !gsb_real_cmp ( gsb_data_transaction_get_amount (
  1839. transaction_number), imported_transaction -> montant )
  1840. &&
  1841. ( g_date_compare ( gsb_data_transaction_get_date (
  1842. transaction_number), date_debut_comparaison ) >= 0 )
  1843. &&
  1844. ( g_date_compare ( gsb_data_transaction_get_date (
  1845. transaction_number ), date_fin_comparaison ) <= 0 )
  1846. &&
  1847. !imported_transaction -> ope_de_ventilation
  1848. &&
  1849. ( !etat.get_fusion_import_transactions
  1850. ||
  1851. !gsb_data_transaction_get_id ( transaction_number ) ) )
  1852. {
  1853. /* the imported transaction has the same date and same amount,
  1854. * will ask the user */
  1855. imported_transaction -> action = IMPORT_TRANSACTION_ASK_FOR_TRANSACTION;
  1856. imported_transaction -> ope_correspondante = transaction_number;
  1857. demande_confirmation = TRUE;
  1858. }
  1859. g_date_free ( date_debut_comparaison );
  1860. g_date_free ( date_fin_comparaison );
  1861. }
  1862. list_tmp_transactions = list_tmp_transactions -> next;
  1863. }
  1864. }
  1865. list_tmp = list_tmp -> next;
  1866. }
  1867. return demande_confirmation;
  1868. }
  1869. /**
  1870. * called if we are not sure about some transactions to import
  1871. * ask here to the user
  1872. *
  1873. * \param imported_account
  1874. *
  1875. * \return
  1876. * */
  1877. void confirmation_enregistrement_ope_import ( struct struct_compte_importation *imported_account,
  1878. gint account_number )
  1879. {
  1880. GSList *list_tmp;
  1881. GtkWidget *dialog;
  1882. GtkWidget *vbox;
  1883. GtkWidget *hbox;
  1884. GtkWidget *scrolled_window;
  1885. GtkWidget *label;
  1886. GtkWidget *frame;
  1887. gchar* tmpstr;
  1888. gchar* tmpstr2;
  1889. gint action_derniere_ventilation;
  1890. gint result;
  1891. /* pbiava the 03/17/2009 modifications pour la fusion des opérations */
  1892. if ( etat.get_fusion_import_transactions )
  1893. tmpstr = g_strdup_printf (
  1894. _("Confirmation of transactions to be merged in: %s"),
  1895. gsb_data_account_get_name ( account_number ) );
  1896. else
  1897. tmpstr = g_strdup_printf (
  1898. _("Confirmation of importation of transactions in: %s"),
  1899. gsb_data_account_get_name ( account_number ) );
  1900. dialog = gtk_dialog_new_with_buttons ( tmpstr,
  1901. GTK_WINDOW ( window ),
  1902. GTK_DIALOG_MODAL,
  1903. GTK_STOCK_SELECT_ALL, -12,
  1904. _("Unselect all"), -13,
  1905. GTK_STOCK_OK,
  1906. GTK_RESPONSE_OK,
  1907. NULL );
  1908. g_free ( tmpstr );
  1909. gtk_window_set_default_size ( GTK_WINDOW ( dialog ), 770, 412 );
  1910. gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
  1911. gtk_window_set_resizable ( GTK_WINDOW ( dialog ), TRUE );
  1912. gtk_container_set_border_width ( GTK_CONTAINER(dialog), 12 );
  1913. if ( etat.get_fusion_import_transactions )
  1914. {
  1915. gtk_dialog_set_response_sensitive ( GTK_DIALOG ( dialog ), -12, FALSE );
  1916. tmpstr = g_strdup (
  1917. _("Please select the transactions to be merged") );
  1918. }
  1919. else
  1920. {
  1921. gtk_dialog_set_response_sensitive ( GTK_DIALOG ( dialog ), -13, FALSE );
  1922. tmpstr = g_strdup (
  1923. _("Some imported transactions seem to be already saved."
  1924. "Please select the transactions to import.") );
  1925. }
  1926. label = gtk_label_new ( tmpstr );
  1927. gtk_misc_set_alignment ( GTK_MISC ( label ), 0.0, 0.0 );
  1928. gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog )-> vbox ),
  1929. label,
  1930. FALSE,
  1931. FALSE,
  1932. 10 );
  1933. gtk_widget_show ( label );
  1934. g_free ( tmpstr );
  1935. /* set the decoration */
  1936. frame = gtk_frame_new (NULL);
  1937. gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog )-> vbox ), frame, TRUE, TRUE, 0 );
  1938. gtk_widget_show ( frame );
  1939. vbox = gtk_vbox_new ( FALSE, 0 );
  1940. gtk_container_add ( GTK_CONTAINER ( frame ), vbox);
  1941. gtk_widget_show ( vbox );
  1942. scrolled_window = gtk_scrolled_window_new ( FALSE, FALSE );
  1943. gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolled_window ),
  1944. GTK_POLICY_AUTOMATIC,
  1945. GTK_POLICY_AUTOMATIC );
  1946. gtk_box_pack_start ( GTK_BOX ( vbox), scrolled_window, TRUE, TRUE, 0 );
  1947. gtk_widget_show ( scrolled_window );
  1948. vbox = gtk_vbox_new ( FALSE, 5 );
  1949. gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW ( scrolled_window ), vbox );
  1950. gtk_container_set_border_width ( GTK_CONTAINER ( vbox ), 10 );
  1951. gtk_widget_show ( vbox );
  1952. /* on fait maintenant le tour des opés importées et affichent celles ŕ problčme */
  1953. list_tmp = imported_account -> operations_importees;
  1954. while ( list_tmp )
  1955. {
  1956. struct struct_ope_importation *ope_import;
  1957. ope_import = list_tmp -> data;
  1958. /* on n'affiche pas si c'est des opés de ventil, si la mčre est cochée, les filles
  1959. * seront alors cochées on ne teste pas ici car ça a été testé avant */
  1960. if ( ope_import -> action == IMPORT_TRANSACTION_ASK_FOR_TRANSACTION
  1961. &&
  1962. !ope_import -> ope_de_ventilation )
  1963. {
  1964. const gchar *tiers;
  1965. hbox = gtk_hbox_new ( FALSE, 5 );
  1966. gtk_box_pack_start ( GTK_BOX ( vbox ), hbox, FALSE, FALSE, 0 );
  1967. gtk_widget_show ( hbox );
  1968. ope_import -> bouton = gtk_check_button_new ();
  1969. if ( etat.get_fusion_import_transactions )
  1970. gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( ope_import -> bouton ), TRUE );
  1971. g_object_set_data ( G_OBJECT ( ope_import -> bouton ), "dialog", dialog );
  1972. g_signal_connect ( ope_import -> bouton,
  1973. "toggled",
  1974. G_CALLBACK (gsb_import_ope_import_toggled),
  1975. vbox );
  1976. gtk_box_pack_start ( GTK_BOX ( hbox ), ope_import -> bouton, FALSE, FALSE, 0 );
  1977. gtk_widget_show ( ope_import -> bouton );
  1978. tmpstr2 = gsb_real_get_string (ope_import -> montant);
  1979. if ( etat.get_fusion_import_transactions )
  1980. tmpstr = g_strdup_printf ( _("Transactions to be merged : %s ; %s ; %s"),
  1981. gsb_format_gdate ( ope_import -> date ),
  1982. ope_import -> tiers,
  1983. tmpstr2);
  1984. else
  1985. tmpstr = g_strdup_printf ( _("Transactions to import : %s ; %s ; %s"),
  1986. gsb_format_gdate ( ope_import -> date ),
  1987. ope_import -> tiers,
  1988. tmpstr2);
  1989. g_free ( tmpstr2 );
  1990. label = gtk_label_new ( tmpstr );
  1991. g_free ( tmpstr );
  1992. gtk_box_pack_start ( GTK_BOX ( hbox ), label, FALSE, FALSE, 0 );
  1993. gtk_widget_show ( label );
  1994. hbox = gtk_hbox_new ( FALSE, 5 );
  1995. gtk_box_pack_start ( GTK_BOX ( vbox ), hbox, FALSE, FALSE, 0 );
  1996. gtk_widget_show ( hbox );
  1997. label = gtk_label_new ( " " );
  1998. gtk_box_pack_start ( GTK_BOX ( hbox ), label, FALSE, FALSE, 0 );
  1999. gtk_widget_show ( label );
  2000. tiers = gsb_data_payee_get_name ( gsb_data_transaction_get_party_number (
  2001. ope_import -> ope_correspondante), FALSE );
  2002. if ( gsb_data_transaction_get_notes (ope_import -> ope_correspondante))
  2003. {
  2004. tmpstr2 = gsb_real_get_string (gsb_data_transaction_get_amount (
  2005. ope_import -> ope_correspondante));
  2006. tmpstr = g_strdup_printf ( _("Transaction found : %s ; %s ; %s ; %s"),
  2007. gsb_format_gdate ( gsb_data_transaction_get_date (
  2008. ope_import -> ope_correspondante ) ),
  2009. tiers,
  2010. tmpstr2,
  2011. gsb_data_transaction_get_notes (ope_import -> ope_correspondante));
  2012. g_free ( tmpstr2 );
  2013. label = gtk_label_new ( tmpstr);
  2014. g_free ( tmpstr );
  2015. }
  2016. else
  2017. {
  2018. tmpstr2 = gsb_real_get_string (gsb_data_transaction_get_amount (
  2019. ope_import -> ope_correspondante));
  2020. tmpstr = g_strdup_printf ( _("Transaction found : %s ; %s ; %s"),
  2021. gsb_format_gdate ( gsb_data_transaction_get_date (
  2022. ope_import -> ope_correspondante ) ),
  2023. tiers,
  2024. tmpstr2);
  2025. g_free ( tmpstr2 );
  2026. label = gtk_label_new ( tmpstr );
  2027. g_free ( tmpstr );
  2028. }
  2029. gtk_box_pack_start ( GTK_BOX ( hbox ), label, FALSE, FALSE, 0 );
  2030. gtk_widget_show ( label );
  2031. }
  2032. list_tmp = list_tmp -> next;
  2033. }
  2034. dialog_return:
  2035. result = gtk_dialog_run ( GTK_DIALOG ( dialog ));
  2036. if ( result <= -12 )
  2037. {
  2038. gtk_container_foreach ( GTK_CONTAINER ( vbox ),
  2039. (GtkCallback) gsb_import_check_ope_import,
  2040. GINT_TO_POINTER ( result ) );
  2041. goto dialog_return;
  2042. }
  2043. /* on fait maintenant le tour des check buttons pour voir ce qu'on importe */
  2044. list_tmp = imported_account -> operations_importees;
  2045. action_derniere_ventilation = 1;
  2046. while ( list_tmp )
  2047. {
  2048. struct struct_ope_importation *ope_import;
  2049. ope_import = list_tmp -> data;
  2050. /* si c'est une opé de ventil, elle n'était pas affichée, dans ce cas si l'action de la
  2051. derničre ventil était 0, on fait de męme pour les filles */
  2052. if ( ope_import -> ope_de_ventilation )
  2053. {
  2054. if ( ope_import -> action )
  2055. ope_import -> action = action_derniere_ventilation;
  2056. }
  2057. else
  2058. action_derniere_ventilation = 1;
  2059. if ( ope_import -> bouton
  2060. &&
  2061. gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( ope_import -> bouton )))
  2062. {
  2063. ope_import -> action = 0;
  2064. /* si c'était une ventil on met l'action de la derničre ventil ŕ 0 */
  2065. if ( ope_import -> operation_ventilee )
  2066. action_derniere_ventilation = 0;
  2067. }
  2068. else if ( etat.get_fusion_import_transactions &&
  2069. ope_import -> ope_correspondante > 0 )
  2070. {
  2071. ope_import -> action = 0;
  2072. if ( ope_import -> operation_ventilee )
  2073. action_derniere_ventilation = 0;
  2074. ope_import -> ope_correspondante = 0;
  2075. }
  2076. list_tmp = list_tmp -> next;
  2077. }
  2078. gtk_widget_destroy ( dialog );
  2079. }
  2080. /**
  2081. * get an imported transaction structure in arg and create the corresponding transaction
  2082. *
  2083. * \param imported_transaction the transaction to import
  2084. * \param account_number the account where to put the new transaction
  2085. *
  2086. * \return the number of the new transaction
  2087. * */
  2088. gint gsb_import_create_transaction ( struct struct_ope_importation *imported_transaction,
  2089. gint account_number,
  2090. gchar *origine )
  2091. {
  2092. gchar **tab_str;
  2093. gint transaction_number;
  2094. gint payee_number = 0;
  2095. gint fyear = 0;
  2096. gint last_transaction_number;
  2097. gint div_number;
  2098. gint payment_number = 0;
  2099. gchar* tmpstr = NULL;
  2100. if ( etat.get_fusion_import_transactions
  2101. &&
  2102. imported_transaction -> ope_correspondante > 0 )
  2103. transaction_number = imported_transaction -> ope_correspondante;
  2104. else
  2105. /* we create the new transaction */
  2106. transaction_number = gsb_data_transaction_new_transaction ( account_number );
  2107. /* get the id if exists */
  2108. if ( imported_transaction -> id_operation )
  2109. gsb_data_transaction_set_transaction_id ( transaction_number,
  2110. imported_transaction -> id_operation );
  2111. /* get the date */
  2112. gsb_data_transaction_set_date ( transaction_number,
  2113. imported_transaction -> date );
  2114. /* récupération de la date de valeur */
  2115. if ( imported_transaction -> date_de_valeur )
  2116. {
  2117. gsb_data_transaction_set_value_date ( transaction_number,
  2118. imported_transaction -> date_de_valeur );
  2119. /* set the financial year according to the date or value date */
  2120. if ( etat.get_fyear_by_value_date )
  2121. fyear = gsb_data_fyear_get_from_date (
  2122. imported_transaction -> date_de_valeur );
  2123. }
  2124. /* if no fyear found, get from the date */
  2125. if (fyear <= 0)
  2126. fyear = gsb_data_fyear_get_from_date (imported_transaction -> date );
  2127. if (fyear > 0)
  2128. gsb_data_transaction_set_financial_year_number ( transaction_number, fyear );
  2129. /* on sort de la fonction si on a fusionné des opérations */
  2130. if ( etat.get_fusion_import_transactions
  2131. &&
  2132. imported_transaction -> ope_correspondante > 0 )
  2133. {
  2134. if ( imported_transaction -> tiers
  2135. &&
  2136. strlen (imported_transaction -> tiers) )
  2137. {
  2138. /* Before leaving, we retrieve the data from payee */
  2139. gsb_data_transaction_set_notes ( transaction_number,
  2140. imported_transaction -> tiers );
  2141. if ( etat.get_extract_number_for_check )
  2142. {
  2143. tmpstr = gsb_string_extract_int ( imported_transaction -> tiers );
  2144. if ( tmpstr && strlen ( tmpstr ) > 0 )
  2145. {
  2146. payment_number = gsb_data_payment_get_number_by_name ( _("Check"),
  2147. account_number );
  2148. gsb_data_transaction_set_method_of_payment_number (transaction_number,
  2149. payment_number);
  2150. gsb_data_transaction_set_method_of_payment_content (
  2151. transaction_number, tmpstr );
  2152. g_free ( tmpstr );
  2153. }
  2154. }
  2155. }
  2156. return transaction_number;
  2157. }
  2158. /* récupération du montant */
  2159. gsb_data_transaction_set_amount ( transaction_number,
  2160. imported_transaction -> montant );
  2161. /* récupération de la devise */
  2162. gsb_data_transaction_set_currency_number ( transaction_number,
  2163. imported_transaction -> devise );
  2164. /* Recovery of payee.
  2165. * we routinely backup imported payee. May be replaced later if
  2166. * notes exist to transactions imported */
  2167. if ( imported_transaction -> tiers
  2168. &&
  2169. strlen (imported_transaction -> tiers))
  2170. {
  2171. payee_number = gsb_import_associations_find_payee (
  2172. imported_transaction -> tiers );
  2173. if ( payee_number == 0 )
  2174. payee_number = gsb_data_payee_get_number_by_name (
  2175. imported_transaction -> tiers, TRUE );
  2176. else
  2177. {
  2178. if ( g_utf8_collate ( gsb_data_payee_get_name (
  2179. payee_number, FALSE ),
  2180. imported_transaction -> tiers ) != 0 )
  2181. gsb_data_transaction_set_notes ( transaction_number,
  2182. imported_transaction -> tiers );
  2183. }
  2184. if ( etat.get_extract_number_for_check )
  2185. {
  2186. tmpstr = gsb_string_extract_int ( imported_transaction -> tiers );
  2187. if ( tmpstr && strlen ( tmpstr ) > 0 )
  2188. {
  2189. payment_number = gsb_data_payment_get_number_by_name ( _("Check"),
  2190. account_number );
  2191. gsb_data_transaction_set_method_of_payment_number (transaction_number,
  2192. payment_number);
  2193. gsb_data_transaction_set_method_of_payment_content (
  2194. transaction_number, tmpstr );
  2195. g_free ( tmpstr );
  2196. }
  2197. }
  2198. gsb_data_transaction_set_party_number ( transaction_number, payee_number );
  2199. }
  2200. /* checking if split, otherwise recovery categories */
  2201. if ( imported_transaction -> operation_ventilee )
  2202. {
  2203. /* transaction is splitted */
  2204. gsb_data_transaction_set_split_of_transaction ( transaction_number, 1 );
  2205. }
  2206. else
  2207. {
  2208. if ( imported_transaction -> categ
  2209. &&
  2210. strlen (imported_transaction -> categ))
  2211. {
  2212. /* Fill budget if existing */
  2213. if ( imported_transaction -> budget
  2214. &&
  2215. strlen (imported_transaction -> budget))
  2216. {
  2217. gsb_import_lookup_budget(imported_transaction, transaction_number);
  2218. }
  2219. if ( imported_transaction -> categ[0] == '[' )
  2220. {
  2221. /* it's a transfer,
  2222. * we will try to make the link later, for now, we keep the name of the contra account into
  2223. * the bank references (never used for import)
  2224. * and set contra_transaction_number to -1 to search the link later */
  2225. gsb_data_transaction_set_bank_references ( transaction_number,
  2226. imported_transaction -> categ);
  2227. gsb_data_transaction_set_contra_transaction_number ( transaction_number, -1);
  2228. virements_a_chercher = 1;
  2229. }
  2230. else
  2231. {
  2232. /* it's a normal category */
  2233. gint category_number;
  2234. tab_str = g_strsplit ( imported_transaction -> categ,
  2235. ":",
  2236. 2 );
  2237. /* get the category and create it if doesn't exist */
  2238. if (tab_str[0])
  2239. tab_str[0] = g_strstrip (tab_str[0]);
  2240. category_number = gsb_data_category_get_number_by_name ( tab_str[0],
  2241. TRUE,
  2242. imported_transaction -> montant.mantissa < 0 );
  2243. gsb_data_transaction_set_category_number ( transaction_number,
  2244. category_number );
  2245. if (tab_str[1])
  2246. tab_str[1] = g_strstrip (tab_str[1]);
  2247. gsb_data_transaction_set_sub_category_number ( transaction_number,
  2248. gsb_data_category_get_sub_category_number_by_name ( category_number,
  2249. tab_str[1],
  2250. TRUE ));
  2251. g_strfreev(tab_str);
  2252. }
  2253. }
  2254. else if ( etat.get_categorie_for_payee && !imported_transaction -> cheque )
  2255. {
  2256. /* associate the class and the budgetary line to the payee except checks */
  2257. last_transaction_number = gsb_form_transactions_look_for_last_party (
  2258. payee_number, transaction_number,
  2259. account_number );
  2260. div_number = gsb_data_transaction_get_category_number (
  2261. last_transaction_number );
  2262. if ( div_number != -1 )
  2263. gsb_data_transaction_set_category_number ( transaction_number, div_number );
  2264. div_number = gsb_data_transaction_get_sub_category_number (
  2265. last_transaction_number );
  2266. if ( div_number != -1 )
  2267. gsb_data_transaction_set_sub_category_number ( transaction_number, div_number );
  2268. div_number = gsb_data_transaction_get_budgetary_number ( last_transaction_number );
  2269. if ( div_number != -1 )
  2270. gsb_data_transaction_set_budgetary_number ( transaction_number, div_number );
  2271. div_number = gsb_data_transaction_get_sub_budgetary_number (
  2272. last_transaction_number );
  2273. if ( div_number != -1 )
  2274. gsb_data_transaction_set_sub_budgetary_number ( transaction_number, div_number );
  2275. }
  2276. else
  2277. {
  2278. gsb_data_transaction_set_category_number ( transaction_number, 0 );
  2279. gsb_data_transaction_set_sub_category_number ( transaction_number, 0 );
  2280. /* Fill budget if existing */
  2281. if ( imported_transaction -> budget
  2282. &&
  2283. strlen (imported_transaction -> budget))
  2284. {
  2285. gsb_import_lookup_budget(imported_transaction, transaction_number);
  2286. }
  2287. }
  2288. }
  2289. /* récupération des notes */
  2290. if ( imported_transaction -> notes &&
  2291. strlen (imported_transaction -> notes) )
  2292. gsb_data_transaction_set_notes ( transaction_number,
  2293. imported_transaction -> notes );
  2294. if (origine && g_ascii_strcasecmp (origine, "OFX") == 0 )
  2295. {
  2296. switch ( imported_transaction -> type_de_transaction )
  2297. {
  2298. case OFX_CHECK:
  2299. /* Check = Chčque */
  2300. payment_number = gsb_data_payment_get_number_by_name ( _("Check"),
  2301. account_number );
  2302. gsb_data_transaction_set_method_of_payment_number (transaction_number,
  2303. payment_number);
  2304. /* we get the check number */
  2305. gsb_data_transaction_set_method_of_payment_content (
  2306. transaction_number, imported_transaction -> cheque );
  2307. break;
  2308. /* case OFX_INT:
  2309. break;
  2310. case OFX_DIV:
  2311. break;
  2312. case OFX_SRVCHG:
  2313. break;
  2314. case OFX_FEE:
  2315. break; */
  2316. case OFX_DEP:
  2317. /* Deposit = Dépôt */
  2318. payment_number = gsb_data_payment_get_number_by_name ( _("Deposit"),
  2319. account_number );
  2320. gsb_data_transaction_set_method_of_payment_number (transaction_number, payment_number);
  2321. break;
  2322. case OFX_ATM:
  2323. /* pas trouvé de définition remplacé par carte de crédit */
  2324. payment_number = gsb_data_payment_get_number_by_name ( _("Credit card"),
  2325. account_number );
  2326. gsb_data_transaction_set_method_of_payment_number (transaction_number, payment_number);
  2327. break;
  2328. case OFX_POS:
  2329. /* Point of sale = Point de vente remplacé par carte de crédit */
  2330. payment_number = gsb_data_payment_get_number_by_name ( _("Credit card"),
  2331. account_number );
  2332. gsb_data_transaction_set_method_of_payment_number (transaction_number, payment_number);
  2333. break;
  2334. case OFX_XFER:
  2335. /* Transfer = Virement */
  2336. payment_number = gsb_data_payment_get_number_by_name ( _("Transfer"),
  2337. account_number );
  2338. gsb_data_transaction_set_method_of_payment_number (transaction_number, payment_number);
  2339. break;
  2340. case OFX_PAYMENT:
  2341. /* Electronic payment remplacé par Direct debit = Prélčvement */
  2342. payment_number = gsb_data_payment_get_number_by_name ( _("Direct debit"),
  2343. account_number );
  2344. gsb_data_transaction_set_method_of_payment_number (transaction_number, payment_number);
  2345. break;
  2346. case OFX_CASH:
  2347. /* Cash withdrawal = retrait en liquide */
  2348. payment_number = gsb_data_payment_get_number_by_name ( _("Cash withdrawal"),
  2349. account_number );
  2350. gsb_data_transaction_set_method_of_payment_number (transaction_number, payment_number);
  2351. break;
  2352. case OFX_DIRECTDEP:
  2353. /* Direct deposit remplacé par Transfert = Virement */
  2354. payment_number = gsb_data_payment_get_number_by_name ( _("Transfer"),
  2355. account_number );
  2356. gsb_data_transaction_set_method_of_payment_number (transaction_number, payment_number);
  2357. break;
  2358. case OFX_DIRECTDEBIT:
  2359. /* Merchant initiated debit remplacé par Direct debit = Prélčvement */
  2360. payment_number = gsb_data_payment_get_number_by_name ( _("Direct debit"),
  2361. account_number );
  2362. gsb_data_transaction_set_method_of_payment_number (transaction_number, payment_number);
  2363. break;
  2364. /* case OFX_REPEATPMT:
  2365. break; */
  2366. case OFX_DEBIT:
  2367. case OFX_CREDIT:
  2368. case OFX_OTHER:
  2369. break;
  2370. }
  2371. }
  2372. else
  2373. {
  2374. /* récupération du chčque et mise en forme du type d'opération */
  2375. if ( imported_transaction -> cheque )
  2376. {
  2377. /* it's a cheque, try to find a method of payment with automatic increment, if don't find
  2378. * set in default method of payment */
  2379. gint payment_number;
  2380. gint sign;
  2381. if ( gsb_data_transaction_get_amount (transaction_number).mantissa < 0 )
  2382. {
  2383. sign = GSB_PAYMENT_DEBIT;
  2384. payment_number = gsb_data_account_get_default_debit (account_number);
  2385. }
  2386. else
  2387. {
  2388. sign = GSB_PAYMENT_CREDIT;
  2389. payment_number = gsb_data_account_get_default_credit (account_number);
  2390. }
  2391. if ( !gsb_data_payment_get_automatic_numbering (payment_number))
  2392. {
  2393. /* the default method is not an automatic numbering, try to find one in the method of payment of this account */
  2394. GSList *list_tmp;
  2395. list_tmp = gsb_data_payment_get_payments_list ();
  2396. while (list_tmp)
  2397. {
  2398. gint payment_number_tmp;
  2399. payment_number_tmp = gsb_data_payment_get_number (list_tmp -> data);
  2400. if ( gsb_data_payment_get_account_number (payment_number_tmp) == account_number
  2401. &&
  2402. gsb_data_payment_get_automatic_numbering (payment_number_tmp)
  2403. &&
  2404. ( gsb_data_payment_get_sign (payment_number_tmp) == sign
  2405. ||
  2406. gsb_data_payment_get_sign (payment_number_tmp) == GSB_PAYMENT_NEUTRAL ))
  2407. {
  2408. payment_number = payment_number_tmp;
  2409. break;
  2410. }
  2411. list_tmp = list_tmp -> next;
  2412. }
  2413. }
  2414. /* now, either payment_number is an automatic numbering method of payment,
  2415. * either it's the default method of payment,
  2416. * first save it */
  2417. gsb_data_transaction_set_method_of_payment_number ( transaction_number,
  2418. payment_number );
  2419. if ( gsb_data_payment_get_automatic_numbering (payment_number))
  2420. /* we are on the default payment_number, save just the cheque number */
  2421. gsb_data_transaction_set_method_of_payment_content ( transaction_number,
  2422. imported_transaction -> cheque );
  2423. else
  2424. {
  2425. /* we are on a automatic numbering payment, we will save the cheque only
  2426. * if it's not used before, else we show an warning message */
  2427. if ( gsb_data_transaction_check_content_payment ( payment_number, imported_transaction -> cheque ) )
  2428. {
  2429. tmpstr = g_strdup_printf ( _("Warning : the cheque number %s is already used.\nWe skip it"),
  2430. imported_transaction -> cheque );
  2431. dialogue_warning ( tmpstr );
  2432. g_free ( tmpstr );
  2433. }
  2434. else
  2435. gsb_data_transaction_set_method_of_payment_content ( transaction_number,
  2436. imported_transaction -> cheque );
  2437. }
  2438. }
  2439. else
  2440. {
  2441. /* comme ce n'est pas un chčque, on met sur le type par défaut */
  2442. if ( gsb_data_transaction_get_amount (transaction_number).mantissa < 0 )
  2443. gsb_data_transaction_set_method_of_payment_number ( transaction_number,
  2444. gsb_data_account_get_default_debit (account_number));
  2445. else
  2446. gsb_data_transaction_set_method_of_payment_number ( transaction_number,
  2447. gsb_data_account_get_default_credit (account_number));
  2448. }
  2449. }
  2450. /* récupération du pointé */
  2451. gsb_data_transaction_set_marked_transaction ( transaction_number,
  2452. imported_transaction -> p_r );
  2453. if (imported_transaction -> p_r == OPERATION_RAPPROCHEE)
  2454. marked_r_transactions_imported = TRUE;
  2455. /* si c'est une ope de ventilation, lui ajoute le no de l'opération précédente */
  2456. if ( imported_transaction -> ope_de_ventilation )
  2457. gsb_data_transaction_set_mother_transaction_number ( transaction_number,
  2458. mother_transaction_number );
  2459. else
  2460. mother_transaction_number = transaction_number;
  2461. return (transaction_number);
  2462. }
  2463. /**
  2464. *
  2465. *
  2466. * */
  2467. void pointe_opes_importees ( struct struct_compte_importation *imported_account,
  2468. gint account_number )
  2469. {
  2470. GSList *list_tmp;
  2471. GSList *liste_opes_import_celibataires;
  2472. /* si le compte importé a une id, on la vérifie ici */
  2473. /* si elle est absente, on met celle importée */
  2474. /* si elle est différente, on demande si on la remplace */
  2475. if ( imported_account -> id_compte )
  2476. {
  2477. if ( ! gsb_import_set_id_compte ( account_number, imported_account -> id_compte ) )
  2478. return;
  2479. }
  2480. /* on fait le tour des opés importées et recherche dans la liste d'opé s'il y a la
  2481. * correspondance */
  2482. list_tmp = imported_account -> operations_importees;
  2483. liste_opes_import_celibataires = NULL;
  2484. while ( list_tmp )
  2485. {
  2486. GSList *liste_ope_importees_tmp;
  2487. GSList *ope_trouvees;
  2488. struct struct_ope_importation *ope_import;
  2489. gint transaction_number;
  2490. gint i;
  2491. ope_import = list_tmp -> data;
  2492. ope_trouvees = NULL;
  2493. /* set now the account number of the transaction */
  2494. ope_import -> no_compte = account_number;
  2495. /* si l'opé d'import a une id, on recherche dans la liste d'opé pour trouver
  2496. une id comparable */
  2497. if ( ope_import -> id_operation
  2498. &&
  2499. (transaction_number = gsb_data_transaction_find_by_id (
  2500. ope_import -> id_operation, account_number ) ) )
  2501. ope_trouvees = g_slist_append ( ope_trouvees,
  2502. GINT_TO_POINTER (transaction_number));
  2503. /* si on n'a rien trouvé par id, */
  2504. /* on fait le tour de la liste d'opés pour trouver des opés comparable */
  2505. /* cad męme date avec + ou - une échelle et męme montant et pas une opé de ventil */
  2506. if ( !ope_trouvees )
  2507. {
  2508. GDate *date_debut_comparaison;
  2509. GDate *date_fin_comparaison;
  2510. GSList *list_tmp_transactions;
  2511. date_debut_comparaison = g_date_new_dmy ( g_date_get_day ( ope_import -> date ),
  2512. g_date_get_month ( ope_import -> date ),
  2513. g_date_get_year ( ope_import -> date ));
  2514. g_date_subtract_days ( date_debut_comparaison,
  2515. valeur_echelle_recherche_date_import );
  2516. date_fin_comparaison = g_date_new_dmy ( g_date_get_day ( ope_import -> date ),
  2517. g_date_get_month ( ope_import -> date ),
  2518. g_date_get_year ( ope_import -> date ));
  2519. g_date_add_days ( date_fin_comparaison,
  2520. valeur_echelle_recherche_date_import );
  2521. if ( imported_account -> invert_transaction_amount )
  2522. ope_import -> montant = gsb_real_opposite ( ope_import -> montant );
  2523. list_tmp_transactions = gsb_data_transaction_get_transactions_list ();
  2524. while ( list_tmp_transactions )
  2525. {
  2526. transaction_number = gsb_data_transaction_get_transaction_number (
  2527. list_tmp_transactions -> data);
  2528. if ( gsb_data_transaction_get_account_number (transaction_number) == account_number )
  2529. {
  2530. if ( !gsb_real_cmp ( gsb_data_transaction_get_amount (transaction_number),
  2531. ope_import -> montant )
  2532. &&
  2533. ( g_date_compare ( gsb_data_transaction_get_date (transaction_number),
  2534. date_debut_comparaison ) >= 0 )
  2535. &&
  2536. ( g_date_compare ( gsb_data_transaction_get_date (transaction_number),
  2537. date_fin_comparaison ) <= 0 )
  2538. &&
  2539. !gsb_data_transaction_get_mother_transaction_number (transaction_number)
  2540. &&
  2541. gsb_data_transaction_get_marked_transaction ( transaction_number ) < 2 )
  2542. /* on a retouvé une opé de męme date et męme montant, on l'ajoute ŕ la liste
  2543. * des opés trouvées */
  2544. ope_trouvees = g_slist_append ( ope_trouvees,
  2545. GINT_TO_POINTER (transaction_number));
  2546. }
  2547. list_tmp_transactions = list_tmp_transactions -> next;
  2548. }
  2549. }
  2550. /* ŕ ce stade, ope_trouvees contient la ou les opés qui sont comparables ŕ l'opé importée */
  2551. /* soit il n'y en n'a qu'une, et on la pointe, soit il y en a plusieurs, et on recherche */
  2552. /* les opés importées s'il y en a d'autre comparables, et on pointe les opés en fonction */
  2553. /* du nb de celles importées */
  2554. switch ( g_slist_length ( ope_trouvees ))
  2555. {
  2556. case 0:
  2557. /* aucune opé comparable n'a été retrouvée */
  2558. /* on marque donc cette opé comme seule */
  2559. /* sauf si c'est une opé de ventil */
  2560. if ( !ope_import -> ope_de_ventilation )
  2561. {
  2562. /* on met le no de compte et la devise de l'opération si plus tard on l'enregistre */
  2563. if (imported_account -> bouton_devise)
  2564. ope_import -> devise = gsb_currency_get_currency_from_combobox (
  2565. imported_account -> bouton_devise);
  2566. else
  2567. ope_import -> devise = gsb_data_currency_get_number_by_code_iso4217 (
  2568. imported_account -> devise);
  2569. liste_opes_import_celibataires = g_slist_append ( liste_opes_import_celibataires,
  2570. ope_import );
  2571. }
  2572. break;
  2573. case 1:
  2574. /* il n'y a qu'une opé retrouvée, on la pointe */
  2575. /* si elle est déjŕ pointée ou relevée, on ne fait rien */
  2576. /* si l'opé d'import a une id et pas l'opé, on marque l'id dans l'opé */
  2577. transaction_number = GPOINTER_TO_INT ( ope_trouvees -> data );
  2578. if ( strlen ( gsb_data_transaction_get_transaction_id ( transaction_number ) ) == 0
  2579. &&
  2580. ope_import -> id_operation )
  2581. gsb_data_transaction_set_transaction_id ( transaction_number,
  2582. ope_import -> id_operation );
  2583. if ( !gsb_data_transaction_get_marked_transaction (transaction_number))
  2584. {
  2585. gsb_data_transaction_set_marked_transaction ( transaction_number,
  2586. 2 );
  2587. /* si c'est une opé ventilée, on recherche les opé filles pour leur mettre
  2588. * le męme pointage que la mčre */
  2589. if ( gsb_data_transaction_get_split_of_transaction (transaction_number))
  2590. {
  2591. GSList *list_tmp_transactions;
  2592. list_tmp_transactions = gsb_data_transaction_get_transactions_list ();
  2593. while ( list_tmp_transactions )
  2594. {
  2595. gint transaction_number_tmp;
  2596. transaction_number_tmp = gsb_data_transaction_get_transaction_number (
  2597. list_tmp_transactions -> data);
  2598. if ( gsb_data_transaction_get_account_number (transaction_number_tmp) == account_number
  2599. &&
  2600. gsb_data_transaction_get_mother_transaction_number (transaction_number_tmp) == transaction_number)
  2601. gsb_data_transaction_set_marked_transaction ( transaction_number_tmp, 2 );
  2602. list_tmp_transactions = list_tmp_transactions -> next;
  2603. }
  2604. }
  2605. }
  2606. /* récupération de la date de valeur */
  2607. if ( ope_import -> date_de_valeur )
  2608. {
  2609. gint fyear = 0;
  2610. gsb_data_transaction_set_value_date ( transaction_number,
  2611. ope_import -> date_de_valeur );
  2612. /* set the financial year according to the date or value date */
  2613. if ( etat.get_fyear_by_value_date )
  2614. fyear = gsb_data_fyear_get_from_date ( ope_import -> date_de_valeur );
  2615. if (fyear > 0)
  2616. gsb_data_transaction_set_financial_year_number ( transaction_number, fyear );
  2617. }
  2618. break;
  2619. default:
  2620. /* il y a plusieurs opé trouvées correspondant ŕ l'opé importée */
  2621. /* on va voir s'il y a d'autres opées importées ayant la męme date et le męme montant
  2622. si on retrouve autant d'opé importées que d'opé trouvées, on peut marquer cette
  2623. opé sans s'en préoccuper */
  2624. i=0;
  2625. liste_ope_importees_tmp = imported_account -> operations_importees;
  2626. while ( liste_ope_importees_tmp )
  2627. {
  2628. struct struct_ope_importation *ope_import_tmp;
  2629. GDate *date_debut_comparaison;
  2630. GDate *date_fin_comparaison;
  2631. ope_import_tmp = liste_ope_importees_tmp -> data;
  2632. /* we look for a date around ope_import_tmp with +- valeur_echelle_recherche_date_import */
  2633. date_debut_comparaison = g_date_new_dmy ( g_date_get_day ( ope_import_tmp -> date ),
  2634. g_date_get_month ( ope_import_tmp -> date ),
  2635. g_date_get_year ( ope_import_tmp -> date ));
  2636. g_date_subtract_days ( date_debut_comparaison,
  2637. valeur_echelle_recherche_date_import );
  2638. date_fin_comparaison = g_date_new_dmy ( g_date_get_day ( ope_import_tmp -> date ),
  2639. g_date_get_month ( ope_import_tmp -> date ),
  2640. g_date_get_year ( ope_import_tmp -> date ));
  2641. g_date_add_days ( date_fin_comparaison,
  2642. valeur_echelle_recherche_date_import );
  2643. if ( !gsb_real_cmp ( ope_import_tmp -> montant,
  2644. ope_import -> montant )
  2645. &&
  2646. ( g_date_compare ( ope_import -> date,
  2647. date_debut_comparaison ) >= 0 )
  2648. &&
  2649. ( g_date_compare ( ope_import -> date,
  2650. date_fin_comparaison ) <= 0 )
  2651. &&
  2652. !ope_import_tmp -> ope_de_ventilation )
  2653. /* on a retouvé une opé d'import de męme date et męme montant, on incrémente
  2654. * le nb d'opé d'import semblables trouvees */
  2655. i++;
  2656. liste_ope_importees_tmp = liste_ope_importees_tmp -> next;
  2657. }
  2658. if ( i == g_slist_length ( ope_trouvees ))
  2659. {
  2660. /* on a trouvé autant d'opé d'import semblables que d'opés semblables dans la
  2661. * liste d'opé donc on peut marquer les opés trouvées */
  2662. /* pour celles qui sont déjŕ pointées, on ne fait rien */
  2663. /* si l'opé importée ŕ une id, on met cette id dans l'opération si elle n'en a pas */
  2664. GSList *list_tmp_2;
  2665. list_tmp_2 = ope_trouvees;
  2666. while ( list_tmp_2 )
  2667. {
  2668. gint transaction_number;
  2669. transaction_number = GPOINTER_TO_INT (list_tmp_2 -> data);
  2670. if ( strlen ( gsb_data_transaction_get_transaction_id ( transaction_number ) ) == 0
  2671. &&
  2672. ope_import -> id_operation )
  2673. gsb_data_transaction_set_transaction_id ( transaction_number,
  2674. ope_import -> id_operation );
  2675. if ( !gsb_data_transaction_get_marked_transaction (transaction_number))
  2676. {
  2677. gsb_data_transaction_set_marked_transaction ( transaction_number, 2 );
  2678. /* si c'est une opé ventilée, on recherche les opé filles pour leur mettre
  2679. * le męme pointage que la mčre */
  2680. if ( gsb_data_transaction_get_split_of_transaction (transaction_number))
  2681. {
  2682. GSList *list_tmp_transactions;
  2683. list_tmp_transactions = gsb_data_transaction_get_transactions_list ();
  2684. while ( list_tmp_transactions )
  2685. {
  2686. gint transaction_number_tmp;
  2687. transaction_number_tmp = gsb_data_transaction_get_transaction_number (list_tmp_transactions -> data);
  2688. if ( gsb_data_transaction_get_account_number (transaction_number_tmp) == account_number )
  2689. {
  2690. if ( gsb_data_transaction_get_mother_transaction_number (transaction_number_tmp) == transaction_number)
  2691. gsb_data_transaction_set_marked_transaction ( transaction_number_tmp,
  2692. 2 );
  2693. }
  2694. list_tmp_transactions = list_tmp_transactions -> next;
  2695. }
  2696. }
  2697. }
  2698. list_tmp_2 = list_tmp_2 -> next;
  2699. }
  2700. }
  2701. else
  2702. {
  2703. /* on a trouvé un nombre différent d'opés d'import et d'opés semblables dans
  2704. * la liste d'opés on marque donc cette opé d'import comme seule */
  2705. ope_import -> devise = gsb_currency_get_currency_from_combobox (
  2706. imported_account -> bouton_devise);
  2707. liste_opes_import_celibataires = g_slist_append (
  2708. liste_opes_import_celibataires, ope_import );
  2709. }
  2710. }
  2711. g_slist_free ( ope_trouvees );
  2712. list_tmp = list_tmp -> next;
  2713. }
  2714. /* a ce niveau, liste_opes_import_celibataires contient les opés d'import dont on
  2715. * n'a pas retrouvé l'opé correspondante
  2716. * on les affiche dans une liste en proposant de les ajouter ŕ la liste */
  2717. if ( liste_opes_import_celibataires )
  2718. gsb_import_show_orphan_transactions ( liste_opes_import_celibataires, account_number );
  2719. }
  2720. /**
  2721. *
  2722. *
  2723. *
  2724. * \param
  2725. *
  2726. * return
  2727. */
  2728. void gsb_import_show_orphan_transactions ( GSList *orphan_list,
  2729. gint account_number )
  2730. {
  2731. GtkWidget *liste_ope_celibataires, *dialog, *label, *scrolled_window;
  2732. GtkListStore *store;
  2733. GtkCellRenderer *renderer;
  2734. GtkTreeViewColumn *column;
  2735. GSList *list_tmp;
  2736. gchar* tmp_str;
  2737. tmp_str = g_strdup_printf (
  2738. _("Orphaned transactions for: %s"),
  2739. gsb_data_account_get_name ( account_number ) );
  2740. dialog = gtk_dialog_new_with_buttons ( tmp_str,
  2741. GTK_WINDOW ( window ),
  2742. GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
  2743. GTK_STOCK_SELECT_ALL, GTK_RESPONSE_ACCEPT,
  2744. GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
  2745. GTK_STOCK_OK, GTK_RESPONSE_OK,
  2746. NULL );
  2747. g_free ( tmp_str );
  2748. gtk_window_set_default_size ( GTK_WINDOW ( dialog ), 770, 412 );
  2749. gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
  2750. gtk_window_set_resizable ( GTK_WINDOW ( dialog ), TRUE );
  2751. gtk_container_set_border_width ( GTK_CONTAINER(dialog), 12 );
  2752. label = gtk_label_new ( _("Mark transactions you want to add to the list and click the "
  2753. "OK button"));
  2754. gtk_misc_set_alignment ( GTK_MISC ( label ), 0.0, 0.0 );
  2755. gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog ) -> vbox ),
  2756. label,
  2757. FALSE,
  2758. FALSE,
  2759. 10 );
  2760. gtk_widget_show ( label );
  2761. /* on crée le model et on y associe le dialogue */
  2762. store = gtk_list_store_new ( 4,
  2763. G_TYPE_BOOLEAN,
  2764. G_TYPE_STRING,
  2765. G_TYPE_STRING,
  2766. G_TYPE_STRING );
  2767. g_object_set_data ( G_OBJECT ( store ), "dialog", dialog );
  2768. /* on remplit la liste */
  2769. list_tmp = orphan_list;
  2770. while ( list_tmp )
  2771. {
  2772. struct struct_ope_importation *ope_import;
  2773. GtkTreeIter iter;
  2774. ope_import = list_tmp -> data;
  2775. gtk_list_store_append ( store, &iter );
  2776. gtk_list_store_set ( store,
  2777. &iter,
  2778. 0, FALSE,
  2779. 1, gsb_format_gdate ( ope_import -> date ),
  2780. 2, ope_import -> tiers,
  2781. 3, gsb_real_get_string_with_currency ( ope_import -> montant,
  2782. ope_import -> devise, TRUE ),
  2783. -1 );
  2784. list_tmp = list_tmp -> next;
  2785. }
  2786. /* on crée la liste des opés célibataires et on y associe la gslist */
  2787. liste_ope_celibataires = gtk_tree_view_new_with_model ( GTK_TREE_MODEL (store));
  2788. g_object_set_data ( G_OBJECT ( liste_ope_celibataires ), "liste_ope", orphan_list );
  2789. scrolled_window = gtk_scrolled_window_new ( FALSE, FALSE );
  2790. gtk_widget_set_size_request ( scrolled_window, -1, 300 );
  2791. gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog ) -> vbox ),
  2792. scrolled_window,
  2793. TRUE,
  2794. TRUE,
  2795. 0 );
  2796. gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolled_window ),
  2797. GTK_POLICY_AUTOMATIC,
  2798. GTK_POLICY_AUTOMATIC );
  2799. gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW ( scrolled_window ),
  2800. liste_ope_celibataires );
  2801. gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (liste_ope_celibataires), TRUE);
  2802. gtk_widget_show_all ( scrolled_window );
  2803. /* on affiche les colonnes */
  2804. renderer = gtk_cell_renderer_toggle_new ();
  2805. g_signal_connect ( renderer,
  2806. "toggled",
  2807. G_CALLBACK (click_sur_liste_opes_orphelines ),
  2808. store );
  2809. column = gtk_tree_view_column_new_with_attributes ( _("Mark"),
  2810. renderer,
  2811. "active", 0,
  2812. NULL);
  2813. gtk_tree_view_append_column (GTK_TREE_VIEW (liste_ope_celibataires), column);
  2814. renderer = gtk_cell_renderer_text_new ();
  2815. column = gtk_tree_view_column_new_with_attributes ( _("Date"),
  2816. renderer,
  2817. "text", 1,
  2818. NULL);
  2819. gtk_tree_view_append_column (GTK_TREE_VIEW (liste_ope_celibataires), column);
  2820. renderer = gtk_cell_renderer_text_new ();
  2821. column = gtk_tree_view_column_new_with_attributes ( _("Payee"),
  2822. renderer,
  2823. "text", 2,
  2824. NULL);
  2825. gtk_tree_view_append_column (GTK_TREE_VIEW (liste_ope_celibataires), column);
  2826. renderer = gtk_cell_renderer_text_new ();
  2827. column = gtk_tree_view_column_new_with_attributes ( _("Amount"),
  2828. renderer,
  2829. "text", 3,
  2830. NULL);
  2831. gtk_tree_view_append_column (GTK_TREE_VIEW (liste_ope_celibataires), column);
  2832. g_signal_connect ( G_OBJECT ( dialog ),
  2833. "response",
  2834. G_CALLBACK ( click_dialog_ope_orphelines ),
  2835. liste_ope_celibataires );
  2836. gtk_widget_show ( dialog );
  2837. }
  2838. /**
  2839. *
  2840. *
  2841. *
  2842. * \param
  2843. *
  2844. * return
  2845. */
  2846. gboolean gsb_import_set_id_compte ( gint account_nb, gchar *imported_id )
  2847. {
  2848. gchar *account_id;
  2849. account_id = gsb_data_account_get_id ( account_nb );
  2850. if ( account_id )
  2851. {
  2852. if ( g_ascii_strcasecmp ( account_id, imported_id ) )
  2853. {
  2854. /* l'id du compte choisi et l'id du compte importé sont différents */
  2855. /* on propose encore d'arręter... */
  2856. if ( question_yes_no_hint (
  2857. _("The id of the imported and chosen accounts are different"),
  2858. _("Perhaps you choose a wrong account ? If you choose to continue, "
  2859. "the id of the account will be changed. Do you want to continue ?"),
  2860. GTK_RESPONSE_NO ) )
  2861. gsb_data_account_set_id ( account_nb, my_strdup ( imported_id ) );
  2862. else
  2863. return FALSE;
  2864. }
  2865. }
  2866. else
  2867. gsb_data_account_set_id ( account_nb, my_strdup ( imported_id ) );
  2868. return TRUE;
  2869. }
  2870. /**
  2871. * get first date of the imported file
  2872. *
  2873. *
  2874. * \param
  2875. *
  2876. * return
  2877. */
  2878. GDate *gsb_import_get_first_date ( GSList *import_list )
  2879. {
  2880. GSList *list_tmp;
  2881. GDate *first_date = NULL;
  2882. list_tmp = import_list;
  2883. while ( list_tmp )
  2884. {
  2885. struct struct_ope_importation *imported_transaction;
  2886. imported_transaction = list_tmp -> data;
  2887. if ( !first_date
  2888. ||
  2889. g_date_compare ( imported_transaction -> date, first_date ) < 0 )
  2890. first_date = imported_transaction -> date;
  2891. list_tmp = list_tmp -> next;
  2892. }
  2893. first_date = gsb_date_copy ( first_date );
  2894. g_date_subtract_days ( first_date, valeur_echelle_recherche_date_import );
  2895. return first_date;
  2896. }
  2897. /* *******************************************************************************/
  2898. /* *******************************************************************************/
  2899. gboolean click_dialog_ope_orphelines ( GtkWidget *dialog,
  2900. gint result,
  2901. GtkWidget *liste_ope_celibataires )
  2902. {
  2903. GSList *liste_opes_import_celibataires;
  2904. GSList *list_tmp;
  2905. GtkTreeIter iter;
  2906. GtkTreeModel *model;
  2907. switch ( result )
  2908. {
  2909. case GTK_RESPONSE_ACCEPT:
  2910. /* on coche toutes les cases des opérations */
  2911. liste_opes_import_celibataires = g_object_get_data (
  2912. G_OBJECT ( liste_ope_celibataires ),
  2913. "liste_ope" );
  2914. model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( liste_ope_celibataires ));
  2915. if ( gtk_tree_model_get_iter_first ( GTK_TREE_MODEL ( model ), &iter ) )
  2916. {
  2917. do
  2918. {
  2919. gtk_list_store_set ( GTK_LIST_STORE ( model ), &iter, 0, TRUE, -1 );
  2920. }
  2921. while ( gtk_tree_model_iter_next ( GTK_TREE_MODEL ( model ), &iter ) );
  2922. }
  2923. gtk_dialog_set_response_sensitive ( GTK_DIALOG ( dialog ),GTK_RESPONSE_ACCEPT, FALSE );
  2924. break;
  2925. case GTK_RESPONSE_OK:
  2926. /* on ajoute la ou les opés marquées ŕ la liste d'opés en les pointant d'un T
  2927. puis on les retire de la liste des orphelines
  2928. s'il ne reste plus d'opés orphelines, on ferme la boite de dialogue */
  2929. liste_opes_import_celibataires = g_object_get_data ( G_OBJECT ( liste_ope_celibataires ),
  2930. "liste_ope" );
  2931. model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( liste_ope_celibataires ));
  2932. gtk_tree_model_get_iter_first ( GTK_TREE_MODEL ( model ),
  2933. &iter );
  2934. list_tmp = liste_opes_import_celibataires;
  2935. /* normalement, pas besoin de mettre ça ŕ 0 car normalement pas de ventilations ŕ ce stade... */
  2936. mother_transaction_number = 0;
  2937. while ( list_tmp )
  2938. {
  2939. gboolean enregistre;
  2940. GSList *last_item;
  2941. gtk_tree_model_get ( GTK_TREE_MODEL ( model ),
  2942. &iter,
  2943. 0, &enregistre,
  2944. -1 );
  2945. if ( enregistre )
  2946. {
  2947. /* ŕ ce niveau, l'opé a été cochée donc on l'enregistre en la marquant T */
  2948. struct struct_ope_importation *ope_import;
  2949. gint transaction_number;
  2950. ope_import = list_tmp -> data;
  2951. transaction_number = gsb_import_create_transaction ( ope_import,
  2952. ope_import -> no_compte , NULL);
  2953. gsb_data_transaction_set_marked_transaction ( transaction_number, 2 );
  2954. /* we need to add the transaction now to the tree model and update the tree_view */
  2955. gsb_transactions_list_append_new_transaction (transaction_number, FALSE);
  2956. gsb_transactions_list_update_tree_view (ope_import -> no_compte, FALSE);
  2957. gsb_data_account_colorize_current_balance ( ope_import -> no_compte );
  2958. /* on a enregistré l'opé, on la retire maintenant de la liste et de la sliste */
  2959. last_item = list_tmp;
  2960. list_tmp = list_tmp -> next;
  2961. liste_opes_import_celibataires = g_slist_remove_link ( liste_opes_import_celibataires,
  2962. last_item );
  2963. /* on retire la ligne qu'on vient d'enregistrer, celŕ met l'iter directement sur
  2964. * la suite */
  2965. gtk_list_store_remove ( GTK_LIST_STORE ( model),
  2966. &iter );
  2967. }
  2968. else
  2969. {
  2970. gtk_tree_model_iter_next ( GTK_TREE_MODEL ( model ),
  2971. &iter );
  2972. list_tmp = list_tmp -> next;
  2973. }
  2974. }
  2975. /* on enregistre la nouvelle liste d'opé pour la retrouver plus tard */
  2976. g_object_set_data ( G_OBJECT ( liste_ope_celibataires ),
  2977. "liste_ope",
  2978. liste_opes_import_celibataires );
  2979. /* il est possible que les opés importées soient des virements, il faut faire les
  2980. relations ici */
  2981. if ( virements_a_chercher )
  2982. cree_liens_virements_ope_import ();
  2983. /* mise ŕ jour de l'accueil */
  2984. mise_a_jour_liste_comptes_accueil = 1;
  2985. mise_a_jour_soldes_minimaux = 1;
  2986. if ( etat.modification_fichier == 0 )
  2987. modification_fichier ( TRUE );
  2988. if ( result != GTK_RESPONSE_OK
  2989. &&
  2990. g_slist_length ( liste_opes_import_celibataires ))
  2991. break;
  2992. default:
  2993. gtk_widget_destroy ( dialog );
  2994. break;
  2995. }
  2996. return ( FALSE );
  2997. }
  2998. /* *******************************************************************************/
  2999. /* *******************************************************************************/
  3000. gboolean click_sur_liste_opes_orphelines ( GtkCellRendererToggle *renderer,
  3001. gchar *ligne,
  3002. GtkTreeModel *store )
  3003. {
  3004. GtkTreeIter iter;
  3005. gboolean valeur;
  3006. if ( gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL ( store ), &iter, ligne ) )
  3007. {
  3008. gtk_tree_model_get ( GTK_TREE_MODEL ( store ), &iter, 0, &valeur, -1 );
  3009. gtk_list_store_set ( GTK_LIST_STORE ( store ), &iter, 0, 1 - valeur, -1 );
  3010. }
  3011. if ( gtk_tree_model_get_iter_first ( GTK_TREE_MODEL ( store ), &iter ) )
  3012. {
  3013. gboolean all_true = TRUE;
  3014. GtkDialog *dialog;
  3015. dialog = g_object_get_data ( G_OBJECT ( store ), "dialog" );
  3016. do
  3017. {
  3018. gtk_tree_model_get ( GTK_TREE_MODEL ( store ), &iter, 0, &valeur, -1 );
  3019. if ( valeur == FALSE )
  3020. all_true = FALSE;
  3021. }
  3022. while ( gtk_tree_model_iter_next ( GTK_TREE_MODEL ( store ), &iter ) );
  3023. if ( all_true == TRUE )
  3024. gtk_dialog_set_response_sensitive ( dialog,GTK_RESPONSE_ACCEPT, FALSE );
  3025. else
  3026. gtk_dialog_set_response_sensitive ( dialog,GTK_RESPONSE_ACCEPT, TRUE );
  3027. }
  3028. return ( FALSE );
  3029. }
  3030. /**
  3031. * check if the name of the imported account in param is not already
  3032. * used, if yes, modify it
  3033. *
  3034. * \param account_name name to check
  3035. *
  3036. * return a newly allocated string or NULL
  3037. */
  3038. G_MODULE_EXPORT gchar * unique_imported_name ( gchar * account_name )
  3039. {
  3040. GSList *tmp_list;
  3041. gchar *basename;
  3042. gint iter = 1;
  3043. tmp_list = liste_comptes_importes;
  3044. basename = my_strdup ( account_name );
  3045. if ( !liste_comptes_importes )
  3046. return basename;
  3047. do
  3048. {
  3049. struct struct_compte_importation *tmp_account;
  3050. tmp_account = (struct struct_compte_importation *) tmp_list -> data;
  3051. if ( tmp_account -> nom_de_compte == NULL )
  3052. tmp_account -> nom_de_compte = g_strdup ( basename );
  3053. if ( !strcmp ( basename, tmp_account -> nom_de_compte ) )
  3054. {
  3055. tmp_list = liste_comptes_importes;
  3056. g_free (basename);
  3057. basename = g_strdup_printf ( _("%s #%d"), account_name, ++iter );
  3058. }
  3059. else
  3060. tmp_list = tmp_list -> next;
  3061. }
  3062. while ( tmp_list );
  3063. return basename;
  3064. }
  3065. /* *******************************************************************************/
  3066. /* page de configuration pour l'importation */
  3067. /* *******************************************************************************/
  3068. GtkWidget *onglet_importation (void)
  3069. {
  3070. GtkWidget *vbox_pref, *paddingbox;
  3071. GtkWidget *hbox;
  3072. GtkWidget *label;
  3073. GtkWidget *button;
  3074. vbox_pref = new_vbox_with_title_and_icon ( _("Import"),
  3075. "importlg.png" );
  3076. /* Data import settings */
  3077. paddingbox = new_paddingbox_with_title (vbox_pref, FALSE,
  3078. _("Import settings"));
  3079. /* hbox for label and range-selection */
  3080. hbox = gtk_hbox_new ( FALSE, 0 );
  3081. gtk_box_pack_start ( GTK_BOX ( paddingbox ), hbox, FALSE, FALSE, 0 );
  3082. label = gtk_label_new (
  3083. _("Threshold while matching transaction date during import (in days): "));
  3084. gtk_box_pack_start ( GTK_BOX ( hbox ), label, FALSE, FALSE, 0 );
  3085. button = gtk_spin_button_new_with_range ( 0.0,
  3086. 100.0,
  3087. 1.0);
  3088. gtk_spin_button_set_value ( GTK_SPIN_BUTTON ( button ),
  3089. (gdouble) valeur_echelle_recherche_date_import );
  3090. g_signal_connect ( G_OBJECT ( button ),
  3091. "value-changed",
  3092. G_CALLBACK ( changement_valeur_echelle_recherche_date_import ),
  3093. NULL );
  3094. gtk_box_pack_start ( GTK_BOX ( hbox ), button, FALSE, FALSE, 0 );
  3095. /* merge transactions imported with planned transactions */
  3096. hbox = gtk_hbox_new ( FALSE, 0 );
  3097. gtk_box_pack_start ( GTK_BOX ( paddingbox ), hbox, FALSE, FALSE, 0 );
  3098. button = gsb_automem_checkbutton_new (
  3099. _("Merge the imported transactions with the transactions found"),
  3100. &etat.get_fusion_import_transactions, NULL, NULL );
  3101. gtk_box_pack_start ( GTK_BOX ( hbox ), button, FALSE, FALSE, 0 );
  3102. /* automatically associate the category of the payee if it is possible */
  3103. hbox = gtk_hbox_new ( FALSE, 0 );
  3104. gtk_box_pack_start ( GTK_BOX ( paddingbox ), hbox, FALSE, FALSE, 0 );
  3105. button = gsb_automem_checkbutton_new (
  3106. _("Automatically associate the category of the payee if it is possible"),
  3107. &etat.get_categorie_for_payee,
  3108. NULL, NULL );
  3109. gtk_box_pack_start ( GTK_BOX ( hbox ), button, FALSE, FALSE, 0 );
  3110. /* extraire le numéro de chčque du tiers pour le mettre dans No Cheque/Virement */
  3111. hbox = gtk_hbox_new ( FALSE, 0 );
  3112. gtk_box_pack_start ( GTK_BOX ( paddingbox ), hbox, FALSE, FALSE, 0 );
  3113. button = gsb_automem_checkbutton_new (
  3114. _("Extracting a number and save it in the field No Cheque/Virement"),
  3115. &etat.get_extract_number_for_check,
  3116. NULL, NULL );
  3117. gtk_box_pack_start ( GTK_BOX ( hbox ), button, FALSE, FALSE, 0 );
  3118. /* propose to choose between getting the fyear by value date or by date */
  3119. gsb_automem_radiobutton_new_with_title ( vbox_pref,
  3120. _("Set the financial year"),
  3121. _("According to the date"),
  3122. _("According to the value date (if fail, try with the date)"),
  3123. &etat.get_fyear_by_value_date,
  3124. NULL, NULL );
  3125. gtk_widget_show_all ( vbox_pref );
  3126. return ( vbox_pref );
  3127. }
  3128. /* *******************************************************************************/
  3129. /* page de configuration pour la gestion des associations des tiers */
  3130. /* *******************************************************************************/
  3131. GtkWidget * gsb_import_associations_gere_tiers ( void )
  3132. {
  3133. GtkWidget *vbox_main, *vbox, *paddingbox, *button;
  3134. GtkWidget *hbox, *vbox2, *sw, *treeview ;
  3135. GtkWidget *table, *label, *entry;
  3136. GtkListStore *list_store;
  3137. GtkTreeViewColumn *column;
  3138. GtkCellRenderer *cell;
  3139. GtkTreeSelection *selection;
  3140. gchar *texte;
  3141. vbox_main = new_vbox_with_title_and_icon (
  3142. _("Manage import associations"),
  3143. "payees.png" );
  3144. vbox = gtk_vbox_new ( FALSE, 12 );
  3145. gtk_box_pack_start ( GTK_BOX ( vbox_main ), vbox, TRUE, TRUE, 0 );
  3146. gtk_container_set_border_width ( GTK_CONTAINER ( vbox ), 12 );
  3147. paddingbox = new_paddingbox_with_title ( vbox, FALSE, _("Import associations") );
  3148. texte = g_strdup ( _("This will associate a search string to a payee every time you "
  3149. "import a file. For instance, all QIF labels containing 'Rent' "
  3150. "could be associated with a specific payee representing your "
  3151. "landlord.") );
  3152. label = gtk_label_new ( texte );
  3153. gtk_label_set_line_wrap ( GTK_LABEL ( label ), TRUE );
  3154. gtk_misc_set_alignment ( GTK_MISC ( label ), 0, 0);
  3155. gtk_label_set_justify ( GTK_LABEL ( label ), GTK_JUSTIFY_LEFT );
  3156. g_free ( texte );
  3157. gtk_box_pack_start ( GTK_BOX(paddingbox), label, FALSE, FALSE, 6 );
  3158. hbox = gtk_hbox_new ( FALSE, 5 );
  3159. gtk_box_pack_start ( GTK_BOX ( paddingbox ), hbox, TRUE, TRUE, 0);
  3160. sw = gtk_scrolled_window_new (NULL, NULL);
  3161. gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
  3162. GTK_SHADOW_ETCHED_IN);
  3163. gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
  3164. GTK_POLICY_AUTOMATIC,
  3165. GTK_POLICY_ALWAYS);
  3166. gtk_box_pack_start ( GTK_BOX (hbox), sw, TRUE,TRUE, 0 );
  3167. /* Create Add/Remove buttons */
  3168. vbox2 = gtk_vbox_new ( FALSE, 5 );
  3169. gtk_box_pack_start ( GTK_BOX ( hbox ), vbox2, FALSE, FALSE, 0 );
  3170. /* Button "Add" */
  3171. button = gtk_button_new_from_stock (GTK_STOCK_ADD);
  3172. g_signal_connect ( G_OBJECT ( button ),
  3173. "clicked",
  3174. G_CALLBACK ( gsb_import_associations_add_assoc ),
  3175. vbox_main );
  3176. gtk_box_pack_start ( GTK_BOX ( vbox2 ), button, FALSE, FALSE, 5 );
  3177. g_object_set_data ( G_OBJECT (vbox_main), "add_button", button );
  3178. /* Button "Remove" */
  3179. button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
  3180. g_signal_connect ( G_OBJECT ( button ),
  3181. "clicked",
  3182. G_CALLBACK ( gsb_import_associations_del_assoc ),
  3183. vbox_main );
  3184. gtk_box_pack_start ( GTK_BOX ( vbox2 ), button, FALSE, FALSE, 5 );
  3185. gtk_widget_set_sensitive ( button, FALSE );
  3186. g_object_set_data ( G_OBJECT (vbox_main), "remove_button", button );
  3187. /* create the model */
  3188. list_store = gtk_list_store_new (
  3189. 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT );
  3190. /* remplit le modčle si nécessaire */
  3191. gsb_import_associations_fill_model ( list_store );
  3192. /* create the treeview */
  3193. treeview = gtk_tree_view_new_with_model (
  3194. GTK_TREE_MODEL (list_store) );
  3195. g_object_unref (list_store);
  3196. gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
  3197. gtk_widget_set_size_request ( treeview, -1, 230 );
  3198. selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (treeview) );
  3199. gtk_tree_selection_set_select_function ( selection,
  3200. (GtkTreeSelectionFunc) gsb_import_associations_select_func,
  3201. vbox_main, NULL );
  3202. gtk_container_add (GTK_CONTAINER (sw), treeview);
  3203. gtk_container_set_resize_mode (GTK_CONTAINER (sw), GTK_RESIZE_PARENT);
  3204. g_object_set_data ( G_OBJECT (vbox_main), "treeview", treeview );
  3205. /* payee name */
  3206. cell = gtk_cell_renderer_text_new ( );
  3207. column = gtk_tree_view_column_new_with_attributes ( _("Payee name"),
  3208. cell, "text", 0, NULL);
  3209. gtk_tree_view_column_set_expand ( column, TRUE );
  3210. gtk_tree_view_column_set_alignment ( column, 0.5 );
  3211. gtk_tree_view_column_set_sort_column_id (column, 0);
  3212. gtk_tree_view_append_column ( GTK_TREE_VIEW (treeview), column);
  3213. /* Search string */
  3214. cell = gtk_cell_renderer_text_new ( );
  3215. g_object_set (cell, "editable", TRUE, NULL);
  3216. g_signal_connect ( cell,
  3217. "edited",
  3218. G_CALLBACK (gsb_import_associations_cell_edited),
  3219. vbox_main );
  3220. column = gtk_tree_view_column_new_with_attributes ( _("Search string"),
  3221. cell, "text", 1, NULL);
  3222. gtk_tree_view_column_set_expand ( column, TRUE );
  3223. gtk_tree_view_column_set_alignment ( column, 0.5 );
  3224. gtk_tree_view_column_set_sort_column_id (column, 1);
  3225. gtk_tree_view_append_column ( GTK_TREE_VIEW (treeview), column);
  3226. paddingbox = new_paddingbox_with_title ( vbox,
  3227. FALSE, _("Details of associations"));
  3228. /* Create table */
  3229. table = gtk_table_new ( 2, 2, FALSE );
  3230. gtk_table_set_col_spacings ( GTK_TABLE ( table ), 5 );
  3231. gtk_table_set_row_spacings ( GTK_TABLE ( table ), 5 );
  3232. gtk_box_pack_start ( GTK_BOX ( paddingbox ), table, TRUE, TRUE, 0 );
  3233. /* Create entry liste des tiers */
  3234. label = gtk_label_new ( _("Payee name: ") );
  3235. gtk_misc_set_alignment (GTK_MISC (label), 0, 1);
  3236. gtk_label_set_justify ( GTK_LABEL(label), GTK_JUSTIFY_RIGHT );
  3237. gtk_table_attach ( GTK_TABLE ( table ), label, 0, 1, 0, 1,
  3238. GTK_SHRINK | GTK_FILL, 0, 0, 0 );
  3239. entry = gtk_combofix_new (
  3240. gsb_data_payee_get_name_and_report_list());
  3241. gtk_combofix_set_text ( GTK_COMBOFIX (entry), "" );
  3242. gtk_combofix_set_force_text ( GTK_COMBOFIX (entry),FALSE );
  3243. gtk_combofix_set_max_items ( GTK_COMBOFIX (entry),
  3244. etat.combofix_max_item );
  3245. gtk_combofix_set_case_sensitive ( GTK_COMBOFIX (entry),
  3246. etat.combofix_case_sensitive );
  3247. gtk_table_attach ( GTK_TABLE ( table ), entry, 1, 2, 0, 1,
  3248. GTK_EXPAND|GTK_FILL, 0, 0, 0 );
  3249. g_object_set_data ( G_OBJECT (vbox_main), "payee", entry );
  3250. g_signal_connect ( G_OBJECT (GTK_COMBOFIX (entry) -> entry),
  3251. "changed",
  3252. G_CALLBACK (gsb_import_associations_combo_changed),
  3253. vbox_main );
  3254. /* Create entry search string */
  3255. label = gtk_label_new ( _("Search string: ") );
  3256. gtk_misc_set_alignment (GTK_MISC (label), 0, 1);
  3257. gtk_label_set_justify ( GTK_LABEL(label), GTK_JUSTIFY_RIGHT );
  3258. gtk_table_attach ( GTK_TABLE ( table ), label, 0, 1, 1, 2,
  3259. GTK_SHRINK | GTK_FILL, 0, 0, 0 );
  3260. entry = gtk_entry_new ();
  3261. gtk_entry_set_text ( GTK_ENTRY (entry), "" );
  3262. gtk_table_attach ( GTK_TABLE ( table ), entry, 1, 2, 1, 2,
  3263. GTK_EXPAND|GTK_FILL, 0, 0, 0 );
  3264. g_signal_connect_swapped ( entry,
  3265. "changed",
  3266. G_CALLBACK (gsb_import_associations_check_add_button),
  3267. vbox_main );
  3268. g_object_set_data ( G_OBJECT (vbox_main), "Search_string", entry );
  3269. gsb_import_associations_check_add_button ( G_OBJECT (vbox_main) );
  3270. return vbox_main;
  3271. }
  3272. /**
  3273. *
  3274. *
  3275. */
  3276. void gsb_import_associations_init_variables ( void )
  3277. {
  3278. if ( liste_associations_tiers )
  3279. {
  3280. g_slist_free ( liste_associations_tiers );
  3281. liste_associations_tiers = NULL;
  3282. }
  3283. }
  3284. void gsb_import_associations_add_assoc ( GtkWidget *button, GtkWidget *main_widget )
  3285. {
  3286. GtkWidget *combo, *entry;
  3287. GtkTreeView *treeview;
  3288. GtkTreeModel *list_store;
  3289. gchar *payee, *search_str;
  3290. gint payee_number;
  3291. combo = g_object_get_data ( G_OBJECT (main_widget), "payee" );
  3292. payee = g_strstrip ( g_strdup ( gtk_combofix_get_text ( GTK_COMBOFIX (combo) ) ) );
  3293. if ( strlen ( payee ) == 0 )
  3294. return;
  3295. entry = g_object_get_data ( G_OBJECT (main_widget), "Search_string" );
  3296. search_str = g_strstrip ( g_strdup ( gtk_entry_get_text ( GTK_ENTRY (entry) ) ) );
  3297. if ( strlen ( search_str ) == 0 )
  3298. return;
  3299. devel_debug (payee);
  3300. devel_debug (search_str);
  3301. payee_number = gsb_data_payee_get_number_by_name ( payee, TRUE );
  3302. g_free(payee);
  3303. treeview = g_object_get_data ( G_OBJECT (main_widget), "treeview" );
  3304. list_store = gtk_tree_view_get_model ( GTK_TREE_VIEW (treeview) );
  3305. /* add association in liste_associations_tiers */
  3306. if (g_slist_length ( liste_associations_tiers ) == 0 )
  3307. {
  3308. struct struct_payee_asso *assoc;
  3309. assoc = g_malloc ( sizeof (struct struct_payee_asso) );
  3310. assoc -> payee_number = payee_number;
  3311. assoc -> search_str = search_str;
  3312. liste_associations_tiers = g_slist_append ( liste_associations_tiers,
  3313. assoc );
  3314. gsb_data_payee_set_search_string ( payee_number, search_str );
  3315. }
  3316. else
  3317. {
  3318. struct struct_payee_asso *assoc;
  3319. assoc = g_malloc ( sizeof (struct struct_payee_asso) );
  3320. assoc -> payee_number = payee_number;
  3321. assoc -> search_str = search_str;
  3322. if ( g_slist_find_custom (liste_associations_tiers,
  3323. assoc,
  3324. (GCompareFunc) gsb_import_associations_cmp_assoc) )
  3325. {
  3326. /* clear the entry */
  3327. gtk_combofix_set_text ( GTK_COMBOFIX (combo), "" );
  3328. gtk_entry_set_text ( GTK_ENTRY (entry), "" );
  3329. }
  3330. else
  3331. {
  3332. liste_associations_tiers = g_slist_insert_sorted (
  3333. liste_associations_tiers,
  3334. assoc,
  3335. (GCompareFunc) gsb_import_associations_cmp_assoc);
  3336. gsb_data_payee_set_search_string ( payee_number, search_str );
  3337. }
  3338. }
  3339. if (g_slist_length ( liste_associations_tiers ) > 0 )
  3340. gsb_import_associations_fill_model ( GTK_LIST_STORE (list_store) );
  3341. /* clear the entry */
  3342. gtk_combofix_set_text ( GTK_COMBOFIX (combo), "" );
  3343. gtk_entry_set_text ( GTK_ENTRY (entry), "" );
  3344. }
  3345. gint gsb_import_associations_cmp_assoc (struct struct_payee_asso *assoc_1,
  3346. struct struct_payee_asso *assoc_2)
  3347. {
  3348. gint num_1, num_2;
  3349. num_1 = assoc_1 -> payee_number;
  3350. num_2 = assoc_2 -> payee_number;
  3351. if ( num_1 == num_2 )
  3352. return 0;
  3353. else
  3354. return g_utf8_collate ( gsb_data_payee_get_name (num_1, FALSE),
  3355. gsb_data_payee_get_name (num_2, FALSE) );
  3356. }
  3357. void gsb_import_associations_del_assoc ( GtkWidget *button, GtkWidget *main_widget )
  3358. {
  3359. GtkWidget *combo, *entry;
  3360. GtkTreeView *treeview;
  3361. GtkTreeModel *model;
  3362. GtkTreeIter iter;
  3363. GSList *list_tmp;
  3364. gint payee_number;
  3365. treeview = g_object_get_data ( G_OBJECT (main_widget), "treeview" );
  3366. if ( !gtk_tree_selection_get_selected (
  3367. gtk_tree_view_get_selection (treeview),
  3368. &model,
  3369. &iter ))
  3370. return;
  3371. gtk_tree_model_get ( model, &iter, 2, &payee_number, -1 );
  3372. if ( payee_number > 0 )
  3373. {
  3374. gsb_data_payee_set_search_string ( payee_number, "" );
  3375. list_tmp = liste_associations_tiers;
  3376. while ( list_tmp )
  3377. {
  3378. struct struct_payee_asso *assoc;
  3379. assoc = list_tmp -> data;
  3380. if ( assoc -> payee_number == payee_number )
  3381. {
  3382. liste_associations_tiers = g_slist_remove (
  3383. liste_associations_tiers, assoc );
  3384. gsb_import_associations_fill_model (
  3385. GTK_LIST_STORE (model) );
  3386. break;
  3387. }
  3388. list_tmp = list_tmp -> next;
  3389. }
  3390. combo = g_object_get_data ( G_OBJECT (main_widget), "payee" );
  3391. gtk_combofix_set_text ( GTK_COMBOFIX (combo), "" );
  3392. entry = g_object_get_data ( G_OBJECT (main_widget), "Search_string" );
  3393. gtk_entry_set_text ( GTK_ENTRY (entry), "" );
  3394. }
  3395. }
  3396. void gsb_import_associations_fill_model ( GtkListStore *list_store )
  3397. {
  3398. GSList *list_tmp;
  3399. GtkTreeIter iter;
  3400. list_tmp = liste_associations_tiers;
  3401. gtk_list_store_clear ( GTK_LIST_STORE (list_store) );
  3402. while ( list_tmp )
  3403. {
  3404. gchar *tmpstr;
  3405. struct struct_payee_asso *assoc;
  3406. assoc = list_tmp -> data;
  3407. tmpstr = g_strdup ( gsb_data_payee_get_name (
  3408. assoc -> payee_number, TRUE) );
  3409. gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
  3410. gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
  3411. 0, tmpstr,
  3412. 1, assoc -> search_str,
  3413. 2, assoc -> payee_number,
  3414. -1);
  3415. g_free (tmpstr);
  3416. list_tmp = list_tmp -> next;
  3417. }
  3418. }
  3419. gboolean gsb_import_associations_select_func ( GtkTreeSelection *selection,
  3420. GtkTreeModel *model,
  3421. GtkTreePath *path,
  3422. gboolean path_currently_selected,
  3423. GObject *main_widget )
  3424. {
  3425. GtkWidget *combo, *entry, *button;
  3426. GtkTreeIter iter;
  3427. gchar *payee_str;
  3428. gchar *search_str;
  3429. combo = g_object_get_data ( G_OBJECT (main_widget), "payee" );
  3430. entry = g_object_get_data ( G_OBJECT (main_widget), "Search_string" );
  3431. button = g_object_get_data ( G_OBJECT (main_widget), "remove_button" );
  3432. gtk_tree_model_get_iter ( model, &iter, path );
  3433. gtk_tree_model_get ( model, &iter, 0, &payee_str, 1, &search_str, -1 );
  3434. g_signal_handlers_block_by_func ( G_OBJECT (GTK_COMBOFIX (combo) -> entry),
  3435. G_CALLBACK (gsb_import_associations_combo_changed),
  3436. main_widget );
  3437. gtk_combofix_set_text ( GTK_COMBOFIX (combo), payee_str );
  3438. g_signal_handlers_unblock_by_func ( G_OBJECT (GTK_COMBOFIX (combo) -> entry),
  3439. G_CALLBACK (gsb_import_associations_combo_changed),
  3440. main_widget );
  3441. gtk_entry_set_text ( GTK_ENTRY (entry), search_str );
  3442. gtk_widget_set_sensitive ( entry, FALSE );
  3443. gtk_widget_set_sensitive ( button, TRUE );
  3444. return TRUE;
  3445. }
  3446. static void gsb_import_associations_cell_edited (GtkCellRendererText *cell,
  3447. const gchar *path_string,
  3448. const gchar *new_text,
  3449. GObject * main_widget )
  3450. {
  3451. GtkWidget *entry;
  3452. GtkTreeView *treeview;
  3453. GtkTreeModel *model;
  3454. GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
  3455. GtkTreeIter iter;
  3456. GSList *list_tmp;
  3457. gchar *search_str;
  3458. gint payee_number;
  3459. treeview = g_object_get_data ( G_OBJECT (main_widget), "treeview" );
  3460. model = gtk_tree_view_get_model ( treeview );
  3461. gtk_tree_model_get_iter (model, &iter, path);
  3462. gtk_tree_model_get ( model, &iter, 1, &search_str, 2, &payee_number, -1 );
  3463. if ( g_utf8_collate ( search_str, new_text ) != 0 )
  3464. {
  3465. devel_debug (new_text);
  3466. gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, new_text, -1);
  3467. list_tmp = liste_associations_tiers;
  3468. while ( list_tmp )
  3469. {
  3470. struct struct_payee_asso *assoc;
  3471. assoc = list_tmp -> data;
  3472. if ( assoc -> payee_number == payee_number )
  3473. {
  3474. if ( assoc -> search_str && strlen (assoc -> search_str) )
  3475. g_free ( assoc -> search_str );
  3476. assoc -> search_str = g_strdup ( new_text );
  3477. entry = g_object_get_data ( main_widget, "Search_string" );
  3478. gtk_entry_set_text ( GTK_ENTRY (entry), new_text );
  3479. break;
  3480. }
  3481. list_tmp = list_tmp -> next;
  3482. }
  3483. gsb_data_payee_set_search_string ( payee_number, new_text );
  3484. }
  3485. }
  3486. void gsb_import_associations_combo_changed ( GtkEditable *editable,
  3487. GObject * main_widget )
  3488. {
  3489. GtkWidget *button, *entry;
  3490. const gchar *tmpstr;
  3491. gint payee_number;
  3492. payee_number = gsb_data_payee_get_number_by_name (
  3493. gtk_editable_get_chars (editable, 0, -1), FALSE );
  3494. tmpstr = gsb_data_payee_get_search_string ( payee_number );
  3495. entry = g_object_get_data ( main_widget, "Search_string" );
  3496. if ( strlen ( tmpstr) == 0 )
  3497. {
  3498. gtk_entry_set_text ( GTK_ENTRY (entry), tmpstr );
  3499. gtk_widget_set_sensitive ( entry, TRUE );
  3500. }
  3501. else
  3502. {
  3503. gchar * str;
  3504. str = g_strdup_printf ( _("You cannot choose this payee because it "
  3505. "already has an association") );
  3506. dialogue_warning ( str );
  3507. gtk_editable_delete_text ( editable, 0, -1 );
  3508. if ( strlen (gtk_entry_get_text (GTK_ENTRY (entry))) )
  3509. {
  3510. gtk_entry_set_text ( GTK_ENTRY (entry), "" );
  3511. }
  3512. g_free ( str );
  3513. }
  3514. /* on empeche la suppression par inadvertance d'une association */
  3515. button = g_object_get_data ( main_widget, "remove_button" );
  3516. gtk_widget_set_sensitive ( button, FALSE );
  3517. gsb_import_associations_check_add_button ( main_widget );
  3518. }
  3519. gint gsb_import_associations_find_payee ( gchar *imported_tiers)
  3520. {
  3521. GSList *list_tmp;
  3522. list_tmp = liste_associations_tiers;
  3523. while ( list_tmp )
  3524. {
  3525. struct struct_payee_asso *assoc;
  3526. assoc = list_tmp -> data;
  3527. if ( gsb_string_is_trouve ( imported_tiers, assoc -> search_str ) )
  3528. {
  3529. return assoc -> payee_number;
  3530. }
  3531. list_tmp = list_tmp -> next;
  3532. }
  3533. return 0;
  3534. }
  3535. gint gsb_import_associations_list_append_assoc ( gint payee_number,
  3536. const gchar *search_str )
  3537. {
  3538. struct struct_payee_asso *assoc;
  3539. assoc = g_malloc ( sizeof (struct struct_payee_asso) );
  3540. assoc -> payee_number = payee_number;
  3541. assoc -> search_str = g_strdup ( search_str );
  3542. if ( ! g_slist_find_custom (liste_associations_tiers,
  3543. assoc,
  3544. (GCompareFunc) gsb_import_associations_cmp_assoc) )
  3545. liste_associations_tiers = g_slist_insert_sorted (
  3546. liste_associations_tiers,
  3547. assoc,
  3548. (GCompareFunc) gsb_import_associations_cmp_assoc);
  3549. return g_slist_length ( liste_associations_tiers );
  3550. }
  3551. /**
  3552. *
  3553. *
  3554. */
  3555. gboolean gsb_import_associations_check_add_button ( GObject * main_widget )
  3556. {
  3557. GtkWidget * payee_widget, * search_string_widget;
  3558. gboolean sensitive = TRUE;
  3559. payee_widget = g_object_get_data ( main_widget, "payee" );
  3560. if ( payee_widget )
  3561. {
  3562. const gchar *content;
  3563. content = gtk_combofix_get_text ( GTK_COMBOFIX ( payee_widget ) );
  3564. if ( !content || ! strlen ( content ) )
  3565. sensitive = FALSE;
  3566. }
  3567. search_string_widget = g_object_get_data ( main_widget, "Search_string" );
  3568. if ( search_string_widget )
  3569. {
  3570. const gchar * content = gtk_entry_get_text ( GTK_ENTRY ( search_string_widget ) );
  3571. if ( ! content || ! strlen(content) )
  3572. sensitive = FALSE;
  3573. }
  3574. gtk_widget_set_sensitive ( GTK_WIDGET ( g_object_get_data ( main_widget, "add_button" ) ),
  3575. sensitive );
  3576. return FALSE;
  3577. }
  3578. /* *******************************************************************************/
  3579. /* *******************************************************************************/
  3580. gboolean changement_valeur_echelle_recherche_date_import ( GtkWidget *spin_button )
  3581. {
  3582. valeur_echelle_recherche_date_import = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON ( spin_button ));
  3583. if ( etat.modification_fichier == 0 )
  3584. modification_fichier ( TRUE );
  3585. return ( FALSE );
  3586. }
  3587. /**
  3588. * try to autodetect the type of imported file
  3589. *
  3590. * \param filename
  3591. * \param pointeur_char pointer returned by g_file_get_contents
  3592. * can be NULL, in that case only the extension will be used
  3593. *
  3594. * \return a string : OFX, QIF, Gnucash
  3595. *
  3596. *
  3597. */
  3598. const gchar * autodetect_file_type ( gchar * filename,
  3599. gchar * pointeur_char )
  3600. {
  3601. gchar * extension;
  3602. gchar * type;
  3603. extension = strrchr ( filename, '.' );
  3604. if ( extension )
  3605. {
  3606. GSList * tmp = import_formats;
  3607. while ( tmp )
  3608. {
  3609. struct import_format * format = (struct import_format *) tmp -> data;
  3610. if ( !g_ascii_strcasecmp ( extension + 1, format -> extension ) )
  3611. {
  3612. return format -> name;
  3613. }
  3614. tmp = tmp -> next;
  3615. }
  3616. }
  3617. if ( ! pointeur_char )
  3618. {
  3619. return _("Unknown");
  3620. }
  3621. /** FIXME: add auto-detection to plugin. */
  3622. if ( g_strrstr ( pointeur_char, "ofx" ) || g_strrstr ( pointeur_char, "OFX" ))
  3623. {
  3624. type = "OFX";
  3625. }
  3626. else if ( !my_strncasecmp ( pointeur_char, "!Type", 5 ) ||
  3627. !my_strncasecmp ( pointeur_char, "!Account", 8 ) ||
  3628. !my_strncasecmp ( pointeur_char, "!Option", 7 ))
  3629. {
  3630. type = "QIF";
  3631. }
  3632. else
  3633. {
  3634. if ( strstr ( pointeur_char, "<gnc-v2" ) )
  3635. {
  3636. type = "Gnucash";
  3637. }
  3638. else
  3639. {
  3640. type = _("Unknown");
  3641. }
  3642. }
  3643. return type;
  3644. }
  3645. /**
  3646. * Add an imported account to the list of imported accounts.
  3647. *
  3648. * \param account Account to register.
  3649. */
  3650. G_MODULE_EXPORT void gsb_import_register_account ( struct struct_compte_importation * account )
  3651. {
  3652. liste_comptes_importes = g_slist_append ( liste_comptes_importes, account );
  3653. }
  3654. /**
  3655. * Add an imported account to the list of imported accounts in error.
  3656. *
  3657. * \param account Account to register.
  3658. */
  3659. G_MODULE_EXPORT void gsb_import_register_account_error ( struct struct_compte_importation * account )
  3660. {
  3661. liste_comptes_importes_error = g_slist_append ( liste_comptes_importes, account );
  3662. }
  3663. /**
  3664. * import a file with a rule
  3665. *
  3666. * \param rule the number of rule to use
  3667. *
  3668. * \return TRUE : ok, FALSE : nothing done
  3669. * */
  3670. gboolean gsb_import_by_rule ( gint rule )
  3671. {
  3672. gint account_number;
  3673. gchar **array;
  3674. gint i=0;
  3675. charmap_imported = my_strdup ( gsb_data_import_rule_get_charmap ( rule ));
  3676. array = gsb_import_by_rule_ask_filename (rule);
  3677. if (!array)
  3678. return FALSE;
  3679. account_number = gsb_data_import_rule_get_account (rule);
  3680. while (array[i])
  3681. {
  3682. gchar *filename = array[i];
  3683. const gchar *type;
  3684. gchar * nom_fichier;
  3685. struct imported_file imported;
  3686. GSList *tmp = import_formats;
  3687. /* check if we are on ofx or qif file */
  3688. type = autodetect_file_type (filename, NULL);
  3689. if (strcmp (type, "OFX") && strcmp (type, "QIF"))
  3690. {
  3691. gchar *tmpstr = g_path_get_basename (filename);
  3692. gchar *tmpstr2 = g_strdup_printf (_("%s is neither an OFX file, neither a QIF file. "
  3693. "Nothing will be done for that file."),
  3694. tmpstr );
  3695. dialogue_error (tmpstr2);
  3696. g_free (tmpstr);
  3697. g_free (tmpstr2);
  3698. i++;
  3699. continue;
  3700. }
  3701. else if ( ! strcmp ( type, "OFX" ) )
  3702. {
  3703. gchar * pointeur_char;
  3704. GError * error = NULL;
  3705. if ( ! g_file_get_contents ( filename, &pointeur_char, NULL, &error ) )
  3706. {
  3707. g_print ( _("Unable to read file: %s\n"), error -> message);
  3708. g_error_free ( error );
  3709. i++;
  3710. continue;
  3711. }
  3712. nom_fichier = g_strconcat (g_get_tmp_dir (),G_DIR_SEPARATOR_S,
  3713. g_path_get_basename ( filename ), NULL);
  3714. if (! gsb_import_set_tmp_file (nom_fichier, pointeur_char ) )
  3715. {
  3716. g_free (pointeur_char);
  3717. g_free (nom_fichier);
  3718. i++;
  3719. continue;
  3720. }
  3721. g_free (pointeur_char);
  3722. }
  3723. else
  3724. nom_fichier = my_strdup (filename);
  3725. /* get the transactions */
  3726. imported.name = nom_fichier;
  3727. imported.coding_system = charmap_imported;
  3728. imported.type = type;
  3729. liste_comptes_importes_error = NULL;
  3730. liste_comptes_importes = NULL;
  3731. while ( tmp )
  3732. {
  3733. struct import_format * format = (struct import_format *) tmp -> data;
  3734. if ( !strcmp ( imported.type, format -> name ) )
  3735. {
  3736. format -> import ( NULL, &imported );
  3737. tmp = tmp -> next;
  3738. continue;
  3739. }
  3740. tmp = tmp -> next;
  3741. }
  3742. /* now liste_comptes_importes contains the account structure of imported transactions */
  3743. if (liste_comptes_importes_error)
  3744. {
  3745. gchar *tmpstr = g_path_get_basename (filename);
  3746. gchar *tmpstr2 = g_strdup_printf (_("%s was not imported successfully. An error occured while getting the transactions."),
  3747. tmpstr );
  3748. dialogue_error (tmpstr2);
  3749. g_free (tmpstr);
  3750. g_free (tmpstr2);
  3751. i++;
  3752. continue;
  3753. }
  3754. while ( liste_comptes_importes )
  3755. {
  3756. struct struct_compte_importation *account;
  3757. account = liste_comptes_importes -> data;
  3758. account -> invert_transaction_amount = gsb_data_import_rule_get_invert ( rule );
  3759. switch (gsb_data_import_rule_get_action (rule))
  3760. {
  3761. case IMPORT_ADD_TRANSACTIONS:
  3762. gsb_import_add_imported_transactions ( account, account_number);
  3763. break;
  3764. case IMPORT_MARK_TRANSACTIONS:
  3765. pointe_opes_importees ( account, account_number );
  3766. transaction_list_update_element (ELEMENT_MARK);
  3767. break;
  3768. }
  3769. g_slist_free (account -> operations_importees);
  3770. g_free (account);
  3771. liste_comptes_importes = liste_comptes_importes -> next;
  3772. }
  3773. /* save the charmap for the last file used */
  3774. gsb_data_import_rule_set_charmap (rule, charmap_imported);
  3775. /* save the last file used */
  3776. gsb_data_import_rule_set_last_file_name (rule, filename);
  3777. if ( ! strcmp ( type, "OFX" ) )
  3778. {
  3779. g_remove ( nom_fichier );
  3780. }
  3781. g_slist_free (liste_comptes_importes);
  3782. g_free (nom_fichier);
  3783. i++;
  3784. }
  3785. g_strfreev (array);
  3786. /* update main page */
  3787. mise_a_jour_liste_comptes_accueil = 1;
  3788. mise_a_jour_soldes_minimaux = 1;
  3789. mise_a_jour_accueil (FALSE);
  3790. /* MAJ du solde du compte nécessaire suivant date des opérations existantes */
  3791. if ( conf.balances_with_scheduled == FALSE )
  3792. gsb_data_account_set_balances_are_dirty ( account_number );
  3793. /* force the update module budget */
  3794. gsb_data_account_set_bet_maj ( account_number, BET_MAJ_ALL );
  3795. if ( etat.modification_fichier == 0 )
  3796. modification_fichier ( TRUE );
  3797. return FALSE;
  3798. }
  3799. /**
  3800. * show a popup asking the name of the file to import with a rule
  3801. *
  3802. * \param rule
  3803. *
  3804. * \return a newly-allocated NULL-terminated array of strings of filenames, or NULL
  3805. * use g_strfreev to free it
  3806. * */
  3807. gchar **gsb_import_by_rule_ask_filename ( gint rule )
  3808. {
  3809. gchar *tmpstr;
  3810. GtkWidget *dialog, *paddingbox, *table;
  3811. GtkWidget *label;
  3812. GtkWidget *button;
  3813. GtkWidget *entry;
  3814. GtkWidget *hbox;
  3815. gchar **array = NULL;
  3816. if (!rule)
  3817. return NULL;
  3818. dialog = gtk_dialog_new_with_buttons (_("Import a file with a rule"),
  3819. GTK_WINDOW ( window ),
  3820. GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
  3821. GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
  3822. GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
  3823. NULL );
  3824. gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
  3825. gtk_window_set_resizable ( GTK_WINDOW ( dialog ), FALSE );
  3826. /* text for paddingbox */
  3827. tmpstr = g_strdup_printf (_("Properties of the rule: %s\n"),
  3828. gsb_data_import_rule_get_name (rule));
  3829. /* Ugly dance to avoid side effects on dialog's vbox. */
  3830. hbox = gtk_hbox_new ( FALSE, 0 );
  3831. gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0 );
  3832. paddingbox = new_paddingbox_with_title ( hbox, TRUE, tmpstr );
  3833. gtk_container_set_border_width ( GTK_CONTAINER(hbox), 6 );
  3834. gtk_container_set_border_width ( GTK_CONTAINER(paddingbox), 6 );
  3835. g_free ( tmpstr );
  3836. /* table for layout */
  3837. table = gtk_table_new ( 2, 3, FALSE );
  3838. gtk_box_pack_start ( GTK_BOX ( paddingbox ), table, FALSE, FALSE, 6 );
  3839. gtk_table_set_col_spacings ( GTK_TABLE(table), 6 );
  3840. gtk_table_set_row_spacings ( GTK_TABLE(table), 6 );
  3841. /* textstring 1 */
  3842. if (gsb_data_import_rule_get_action (rule) == IMPORT_ADD_TRANSACTIONS)
  3843. tmpstr = g_strdup_printf (_("Imported transactions will be added to the account %s.\n"),
  3844. gsb_data_account_get_name (gsb_data_import_rule_get_account (rule)));
  3845. else
  3846. tmpstr = g_strdup_printf (_("Imported transactions will mark transactions in the account "
  3847. "%s.\n"),
  3848. gsb_data_account_get_name (gsb_data_import_rule_get_account (rule)));
  3849. /* textstring 2 */
  3850. tmpstr = g_strconcat(tmpstr, g_strdup_printf (_("Currency to import is %s.\n"),
  3851. gsb_data_currency_get_name (
  3852. gsb_data_import_rule_get_currency (rule))), NULL);
  3853. /* textstring 3 */
  3854. if (gsb_data_import_rule_get_invert (rule))
  3855. {
  3856. tmpstr = g_strconcat(tmpstr, g_strdup_printf (_("Amounts of the transactions will be "
  3857. "inverted.\n")), NULL);
  3858. }
  3859. label = gtk_label_new ( tmpstr );
  3860. gtk_misc_set_alignment ( GTK_MISC ( label ), 0.0, 0.0 );
  3861. gtk_table_attach ( GTK_TABLE(table), label, 0, 3, 0, 1,
  3862. GTK_SHRINK | GTK_FILL, 0, 0, 0 );
  3863. g_free ( tmpstr );
  3864. /* label filename */
  3865. label = gtk_label_new ( _("Name of the file to import: ") );
  3866. gtk_misc_set_alignment ( GTK_MISC ( label ), 0.0, 0.0 );
  3867. gtk_table_attach ( GTK_TABLE(table), label, 0, 1, 1, 2,
  3868. GTK_SHRINK | GTK_FILL, 0, 0, 0 );
  3869. /* i tried to use gtk_file_chooser_button, but the name of the file is showed only sometimes
  3870. * so go back to the old method with a gtkentry */
  3871. entry = gtk_entry_new ();
  3872. gtk_widget_set_size_request ( entry, 200, -1 );
  3873. gtk_table_attach ( GTK_TABLE(table), entry, 1, 2, 1, 2,
  3874. GTK_SHRINK | GTK_FILL, 0, 0, 0 );
  3875. if (gsb_data_import_rule_get_last_file_name (rule))
  3876. {
  3877. gtk_entry_set_text ( GTK_ENTRY (entry),
  3878. gsb_data_import_rule_get_last_file_name (rule));
  3879. }
  3880. button = gtk_button_new_with_label ("...");
  3881. g_signal_connect (G_OBJECT (button), "clicked",
  3882. G_CALLBACK (gsb_import_by_rule_get_file), entry );
  3883. gtk_table_attach ( GTK_TABLE(table), button, 2, 3, 1, 2,
  3884. GTK_SHRINK | GTK_FILL, 0, 0, 0 );
  3885. g_object_set_data ( G_OBJECT(entry), "rule", GINT_TO_POINTER ( rule ) );
  3886. gtk_widget_show_all (dialog);
  3887. if ( gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
  3888. array = g_strsplit ( gtk_entry_get_text (GTK_ENTRY (entry)), ";", 0);
  3889. gtk_widget_destroy (dialog);
  3890. return array;
  3891. }
  3892. /**
  3893. * callback when user click on the button to open a file by file chooser
  3894. *
  3895. * \param button the button to open the file chooser
  3896. * \param entry the entry to fill with the new filename
  3897. *
  3898. * \return FALSE
  3899. * */
  3900. gboolean gsb_import_by_rule_get_file ( GtkWidget *button,
  3901. GtkWidget *entry )
  3902. {
  3903. GSList *filenames;
  3904. GSList *tmp_list;
  3905. gchar *string = NULL;
  3906. const gchar *enc;
  3907. gint rule;
  3908. rule = GPOINTER_TO_INT ( g_object_get_data (G_OBJECT (entry), "rule"));
  3909. enc = gsb_data_import_rule_get_charmap ( rule );
  3910. filenames = gsb_import_create_file_chooser ( enc, window );
  3911. if (!filenames)
  3912. return FALSE;
  3913. /* separate all the files by ; */
  3914. tmp_list = filenames;
  3915. while (tmp_list)
  3916. {
  3917. if (string)
  3918. {
  3919. gchar *last_string = string;
  3920. string = g_strconcat (string, ";", tmp_list -> data, NULL);
  3921. g_free (last_string);
  3922. }
  3923. else
  3924. string = my_strdup (tmp_list -> data);
  3925. tmp_list = tmp_list -> next;
  3926. }
  3927. g_slist_free (filenames);
  3928. gtk_entry_set_text (GTK_ENTRY (entry), string);
  3929. gtk_editable_select_region ( GTK_EDITABLE (entry), 0, -1);
  3930. g_free (string);
  3931. return FALSE;
  3932. }
  3933. /**
  3934. * fonction de contournement du bug des fichiers OFX des PTT
  3935. *
  3936. * \param filename nom du fichier provisoire
  3937. * \param pointeur_char contenu du fichier ŕ traiter
  3938. *
  3939. * \return TRUE si OK FALSE autrement
  3940. * */
  3941. gboolean gsb_import_set_tmp_file ( gchar *filename,
  3942. gchar * pointeur_char )
  3943. {
  3944. gchar * contenu_fichier;
  3945. GError * error = NULL;
  3946. contenu_fichier = my_strdelimit (pointeur_char, "°", "&");
  3947. /* create tmp file */
  3948. if ( ! g_file_set_contents ( filename, contenu_fichier, -1, &error ) )
  3949. {
  3950. g_free (contenu_fichier);
  3951. g_print ( _("Unable to create tmp file: %s\n"), error -> message);
  3952. g_error_free ( error );
  3953. return FALSE;
  3954. }
  3955. g_free (contenu_fichier);
  3956. return TRUE;
  3957. }
  3958. /**
  3959. * décompresse le fichier et le sauvegarde ŕ la place du fichier original
  3960. *
  3961. * \param filename nom du fichier provisoire
  3962. *
  3963. * \return TRUE si OK FALSE autrement
  3964. * */
  3965. gboolean gsb_import_gunzip_file ( gchar *filename )
  3966. {
  3967. gchar *file_content;
  3968. gulong length;
  3969. if ( gsb_file_util_get_contents ( filename, &file_content, &length ) )
  3970. {
  3971. GError *error = NULL;
  3972. g_unlink ( filename );
  3973. if ( !g_file_set_contents ( filename, file_content, length, &error ) )
  3974. {
  3975. gchar* tmpstr = g_strdup_printf ( _("cannot unzip file '%s': %s"),
  3976. filename,
  3977. error -> message);
  3978. dialogue_error ( tmpstr );
  3979. g_free ( file_content);
  3980. g_error_free (error);
  3981. return FALSE;
  3982. }
  3983. else
  3984. return TRUE;
  3985. }
  3986. return FALSE;
  3987. }
  3988. /**
  3989. * Lookup the budget and create it if necessary
  3990. *
  3991. * \param budget_str nom du budget ŕ rechercher
  3992. *
  3993. * \return void
  3994. * */
  3995. void gsb_import_lookup_budget ( struct struct_ope_importation *imported_transaction,
  3996. gint transaction_number)
  3997. {
  3998. gint budget_number;
  3999. gchar ** tab_str;
  4000. tab_str = g_strsplit ( imported_transaction -> budget,
  4001. ":",
  4002. 2 );
  4003. /* get the budget and create it if doesn't exist */
  4004. if (tab_str[0])
  4005. tab_str[0] = g_strstrip (tab_str[0]);
  4006. budget_number = gsb_data_budget_get_number_by_name ( tab_str[0],
  4007. TRUE,
  4008. imported_transaction -> montant.mantissa < 0 );
  4009. gsb_data_transaction_set_budgetary_number ( transaction_number,
  4010. budget_number );
  4011. if (tab_str[1])
  4012. tab_str[1] = g_strstrip (tab_str[1]);
  4013. gsb_data_transaction_set_sub_budgetary_number ( transaction_number,
  4014. gsb_data_budget_get_sub_budget_number_by_name ( budget_number,
  4015. tab_str[1],
  4016. TRUE ));
  4017. g_strfreev(tab_str);
  4018. }
  4019. /**
  4020. * check or uncheck the operation found
  4021. *
  4022. * \param widget to test
  4023. * \param data for check or uncheck
  4024. *
  4025. * \return void
  4026. * */
  4027. void gsb_import_check_ope_import ( GtkWidget *widget, gpointer data )
  4028. {
  4029. gint result = GPOINTER_TO_INT ( data );
  4030. if ( GTK_IS_HBOX ( widget ) )
  4031. {
  4032. gtk_container_foreach ( GTK_CONTAINER (widget ),
  4033. (GtkCallback) gsb_import_check_ope_import,
  4034. data );
  4035. }
  4036. if ( GTK_IS_TOGGLE_BUTTON ( widget ) )
  4037. {
  4038. GtkDialog *dialog;
  4039. dialog = g_object_get_data ( G_OBJECT ( widget ), "dialog" );
  4040. if ( result == -12 )
  4041. {
  4042. gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( widget ), TRUE );
  4043. gtk_dialog_set_response_sensitive (dialog, -12, FALSE );
  4044. gtk_dialog_set_response_sensitive (dialog, -13, TRUE );
  4045. }
  4046. else
  4047. {
  4048. gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( widget ), FALSE );
  4049. gtk_dialog_set_response_sensitive (dialog, -12, TRUE );
  4050. gtk_dialog_set_response_sensitive (dialog, -13, FALSE );
  4051. }
  4052. }
  4053. }
  4054. /**
  4055. * select or unselect buttons of the dialog
  4056. *
  4057. * \param toggle_button
  4058. * \param dialog
  4059. *
  4060. * \return void
  4061. * */
  4062. void gsb_import_ope_import_toggled ( GtkWidget *button, GtkWidget *vbox )
  4063. {
  4064. gboolean toggle;
  4065. toggle = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( button ) );
  4066. if ( gsb_import_ope_import_test_toggled ( vbox, toggle ) )
  4067. {
  4068. GtkDialog *dialog;
  4069. dialog = g_object_get_data ( G_OBJECT ( button ), "dialog" );
  4070. if ( toggle == 1 )
  4071. {
  4072. gtk_dialog_set_response_sensitive (dialog, -12, FALSE );
  4073. gtk_dialog_set_response_sensitive (dialog, -13, TRUE );
  4074. }
  4075. else
  4076. {
  4077. gtk_dialog_set_response_sensitive (dialog, -12, TRUE );
  4078. gtk_dialog_set_response_sensitive (dialog, -13, FALSE );
  4079. }
  4080. }
  4081. }
  4082. /**
  4083. * returns false if at least 1 check_button is different of test
  4084. *
  4085. * \param
  4086. * \param
  4087. *
  4088. * \return
  4089. * */
  4090. gboolean gsb_import_ope_import_test_toggled ( GtkWidget *vbox , gboolean test )
  4091. {
  4092. GList *children;
  4093. children = gtk_container_get_children ( GTK_CONTAINER ( vbox ) );
  4094. while ( children )
  4095. {
  4096. GtkWidget *widget;
  4097. widget = children -> data;
  4098. if ( GTK_IS_HBOX ( widget ) )
  4099. {
  4100. GList *list;
  4101. list = gtk_container_get_children ( GTK_CONTAINER ( widget ) );
  4102. while ( list )
  4103. {
  4104. widget = list -> data;
  4105. if ( GTK_IS_TOGGLE_BUTTON ( widget ) )
  4106. {
  4107. g_list_free ( list );
  4108. break;
  4109. }
  4110. list = list -> next;
  4111. }
  4112. }
  4113. if ( GTK_IS_TOGGLE_BUTTON ( widget ) )
  4114. {
  4115. if ( test != gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( widget ) ) )
  4116. return FALSE;
  4117. }
  4118. children = children -> next;
  4119. }
  4120. g_list_free ( children );
  4121. return TRUE;
  4122. }
  4123. GtkWidget *gsb_import_progress_bar_affiche ( struct struct_compte_importation *imported_account )
  4124. {
  4125. GtkWidget *assistant;
  4126. GtkWidget *progress;
  4127. GtkWidget *hbox;
  4128. GtkWidget *image;
  4129. GtkWidget *align;
  4130. GtkWidget *bar;
  4131. progress = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
  4132. gtk_window_set_decorated ( GTK_WINDOW ( progress ), FALSE );
  4133. assistant = g_object_get_data ( G_OBJECT ( window ), "assistant" );
  4134. gtk_window_set_modal ( GTK_WINDOW ( assistant ), FALSE );
  4135. gtk_window_set_transient_for ( GTK_WINDOW ( progress ), GTK_WINDOW ( assistant ) );
  4136. gtk_window_set_modal ( GTK_WINDOW ( progress ), TRUE );
  4137. gtk_window_set_position ( GTK_WINDOW ( progress ), GTK_WIN_POS_CENTER_ALWAYS );
  4138. hbox = gtk_hbox_new ( FALSE, 0 );
  4139. gtk_container_add ( GTK_CONTAINER ( progress ), hbox );
  4140. image = gtk_image_new_from_icon_name ( GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG );
  4141. gtk_box_pack_start ( GTK_BOX ( hbox ), image, FALSE, FALSE, 0 );
  4142. align = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
  4143. bar = gtk_progress_bar_new ( );
  4144. gtk_progress_bar_set_pulse_step ( GTK_PROGRESS_BAR ( bar ), 0.1 );
  4145. g_object_set_data ( G_OBJECT ( progress ), "bar", bar );
  4146. gtk_container_add ( GTK_CONTAINER ( align ), bar );
  4147. gtk_box_pack_start ( GTK_BOX ( hbox ), align, FALSE, FALSE, 6 );
  4148. gtk_widget_show_all ( progress );
  4149. return progress;
  4150. }
  4151. void gsb_import_progress_bar_pulse ( GtkWidget *progress, gint nbre_transaction )
  4152. {
  4153. GtkWidget *bar;
  4154. gchar *tmp_text;
  4155. gchar *text;
  4156. bar = g_object_get_data ( G_OBJECT ( progress ), "bar" );
  4157. gtk_progress_bar_pulse ( GTK_PROGRESS_BAR ( bar ) );
  4158. tmp_text = utils_str_itoa ( nbre_transaction );
  4159. text = g_strdup_printf ( " reste %s transactions ŕ traiter ", tmp_text );
  4160. gtk_progress_bar_set_text ( GTK_PROGRESS_BAR ( bar ), text );
  4161. g_free ( tmp_text );
  4162. g_free ( text );
  4163. }
  4164. /* Local Variables: */
  4165. /* c-basic-offset: 4 */
  4166. /* End: */