|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * import-main-matcher.c - Transaction matcher main window * 00003 * * 00004 * Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> * 00005 * Copyright (C) 2002 Christian Stimming * 00006 * Copyright (c) 2006 David Hampton <hampton@employees.org> * 00007 * Copyright (C) 2012 Robert Fewell * 00008 * * 00009 * This program is free software; you can redistribute it and/or * 00010 * modify it under the terms of the GNU General Public License as * 00011 * published by the Free Software Foundation; either version 2 of * 00012 * the License, or (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License* 00020 * along with this program; if not, contact: * 00021 * * 00022 * Free Software Foundation Voice: +1-617-542-5942 * 00023 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00024 * Boston, MA 02110-1301, USA gnu@gnu.org * 00025 \********************************************************************/ 00035 #include "config.h" 00036 00037 #include <gtk/gtk.h> 00038 #include <glib/gi18n.h> 00039 00040 #include "import-main-matcher.h" 00041 00042 #include "dialog-utils.h" 00043 #include "gnc-ui.h" 00044 #include "gnc-ui-util.h" 00045 #include "gnc-engine.h" 00046 #include "import-settings.h" 00047 #include "import-match-map.h" 00048 #include "import-match-picker.h" 00049 #include "import-backend.h" 00050 #include "import-account-matcher.h" 00051 00052 #define GCONF_SECTION "dialogs/import/generic_matcher/transaction_list" 00053 00054 struct _main_matcher_info 00055 { 00056 GtkWidget *dialog; 00057 GtkWidget *assistant; 00058 GtkTreeView *view; 00059 GNCImportSettings *user_settings; 00060 GdkColor color_back_red; 00061 GdkColor color_back_green; 00062 GdkColor color_back_yellow; 00063 int selected_row; 00064 GNCTransactionProcessedCB transaction_processed_cb; 00065 gpointer user_data; 00066 }; 00067 00068 enum downloaded_cols 00069 { 00070 DOWNLOADED_COL_DATE = 0, 00071 DOWNLOADED_COL_ACCOUNT, 00072 DOWNLOADED_COL_AMOUNT, 00073 DOWNLOADED_COL_DESCRIPTION, 00074 DOWNLOADED_COL_MEMO, 00075 DOWNLOADED_COL_ACTION_ADD, 00076 DOWNLOADED_COL_ACTION_CLEAR, 00077 DOWNLOADED_COL_ACTION_UPDATE, 00078 DOWNLOADED_COL_ACTION_INFO, 00079 DOWNLOADED_COL_ACTION_PIXBUF, 00080 DOWNLOADED_COL_DATA, 00081 DOWNLOADED_COL_COLOR, 00082 NUM_DOWNLOADED_COLS 00083 }; 00084 00085 #define COLOR_RED "brown1" 00086 #define COLOR_YELLOW "gold" 00087 #define COLOR_GREEN "DarkSeaGreen1" 00088 00089 static QofLogModule log_module = GNC_MOD_IMPORT; 00090 00091 void on_matcher_ok_clicked (GtkButton *button, GNCImportMainMatcher *info); 00092 void on_matcher_cancel_clicked (GtkButton *button, gpointer user_data); 00093 void on_matcher_help_clicked (GtkButton *button, gpointer user_data); 00094 void on_matcher_help_close_clicked (GtkButton *button, gpointer user_data); 00095 00096 /* Local prototypes */ 00097 static void 00098 automatch_store_transactions(GNCImportMainMatcher *info, 00099 GtkTreeModel *model, 00100 GtkTreeIter *iter, 00101 GNCImportTransInfo *trans_info); 00102 static void 00103 refresh_model_row(GNCImportMainMatcher *gui, GtkTreeModel *model, 00104 GtkTreeIter *iter, GNCImportTransInfo *info); 00105 00106 void gnc_gen_trans_list_delete (GNCImportMainMatcher *info) 00107 { 00108 GtkTreeModel *model; 00109 GtkTreeIter iter; 00110 GNCImportTransInfo *trans_info; 00111 00112 if (info == NULL) 00113 return; 00114 00115 model = gtk_tree_view_get_model(info->view); 00116 if (gtk_tree_model_get_iter_first(model, &iter)) 00117 { 00118 do 00119 { 00120 gtk_tree_model_get(model, &iter, 00121 DOWNLOADED_COL_DATA, &trans_info, 00122 -1); 00123 00124 if (info->transaction_processed_cb) 00125 { 00126 info->transaction_processed_cb(trans_info, 00127 FALSE, 00128 info->user_data); 00129 } 00130 00131 gnc_import_TransInfo_delete(trans_info); 00132 } 00133 while (gtk_tree_model_iter_next (model, &iter)); 00134 } 00135 00136 00137 if (!(info->dialog == NULL)) 00138 { 00139 gnc_save_window_size(GCONF_SECTION, GTK_WINDOW(info->dialog)); 00140 gnc_import_Settings_delete (info->user_settings); 00141 gtk_widget_destroy (GTK_WIDGET (info->dialog)); 00142 } 00143 else 00144 gnc_import_Settings_delete (info->user_settings); 00145 g_free (info); 00146 } 00147 00148 void 00149 on_matcher_ok_clicked (GtkButton *button, 00150 GNCImportMainMatcher *info) 00151 { 00152 GtkTreeModel *model; 00153 GtkTreePath *path; 00154 GtkTreeRowReference *ref; 00155 GtkTreeIter iter; 00156 GNCImportTransInfo *trans_info; 00157 GSList *refs_list = NULL, *item; 00158 00159 g_assert (info); 00160 00161 /* DEBUG ("Begin") */ 00162 00163 model = gtk_tree_view_get_model(info->view); 00164 if (!gtk_tree_model_get_iter_first(model, &iter)) 00165 return; 00166 00167 do 00168 { 00169 gtk_tree_model_get(model, &iter, 00170 DOWNLOADED_COL_DATA, &trans_info, 00171 -1); 00172 00173 if (gnc_import_process_trans_item(NULL, trans_info)) 00174 { 00175 path = gtk_tree_model_get_path(model, &iter); 00176 ref = gtk_tree_row_reference_new(model, path); 00177 refs_list = g_slist_append(refs_list, ref); 00178 gtk_tree_path_free(path); 00179 00180 if (info->transaction_processed_cb) 00181 { 00182 info->transaction_processed_cb(trans_info, 00183 TRUE, 00184 info->user_data); 00185 } 00186 } 00187 else 00188 { 00189 /* transaction skipped -> destroy 00190 * Otherwise temporary transactions remains visible if account is open 00191 * (see gnc_import_process_trans_item() case GNCImport_CLEAR) */ 00192 /*FIXME xaccTransDestroy(gnc_import_TransInfo_get_trans(trans_info)); 00193 xaccTransCommitEdit(gnc_import_TransInfo_get_trans(trans_info)); */ 00194 } 00195 00196 } 00197 while (gtk_tree_model_iter_next (model, &iter)); 00198 00199 /* DEBUG ("Deleting") */ 00200 /* DRH: Is this necessary. Isn't the call to trans_list_delete at 00201 the end of this routine going to destroy the entire list store 00202 anyway? */ 00203 /*FIXME for (item = refs_list; item; item = g_slist_next(item)) 00204 { 00205 ref = item->data; 00206 path = gtk_tree_row_reference_get_path(ref); 00207 if (gtk_tree_model_get_iter(model, &iter, path)) 00208 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); 00209 gtk_tree_path_free(path); 00210 gtk_tree_row_reference_free(ref); 00211 } 00212 g_slist_free(refs_list); */ 00213 00214 gnc_gen_trans_list_delete (info); 00215 /* DEBUG ("End") */ 00216 } 00217 00218 void 00219 on_matcher_cancel_clicked (GtkButton *button, gpointer user_data) 00220 { 00221 GNCImportMainMatcher *info = user_data; 00222 gnc_gen_trans_list_delete (info); 00223 } 00224 00225 void 00226 on_matcher_help_close_clicked (GtkButton *button, gpointer user_data) 00227 { 00228 GtkWidget *help_dialog = user_data; 00229 00230 gtk_widget_destroy(help_dialog); 00231 } 00232 00233 void 00234 on_matcher_help_clicked (GtkButton *button, gpointer user_data) 00235 { 00236 GNCImportMainMatcher *info = user_data; 00237 GtkBuilder *builder; 00238 GtkWidget *help_dialog, *box, *closebutton; 00239 00240 builder = gtk_builder_new(); 00241 gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer2"); 00242 gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer3"); 00243 gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer4"); 00244 gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer5"); 00245 gnc_builder_add_from_file (builder, "dialog-import.glade", "matcher_help"); 00246 00247 box = GTK_WIDGET(gtk_builder_get_object (builder, "red")); 00248 gtk_widget_modify_bg(box, GTK_STATE_NORMAL, &info->color_back_red); 00249 box = GTK_WIDGET(gtk_builder_get_object (builder, "yellow")); 00250 gtk_widget_modify_bg(box, GTK_STATE_NORMAL, &info->color_back_yellow); 00251 box = GTK_WIDGET(gtk_builder_get_object (builder, "green")); 00252 gtk_widget_modify_bg(box, GTK_STATE_NORMAL, &info->color_back_green); 00253 00254 help_dialog = GTK_WIDGET(gtk_builder_get_object (builder, "matcher_help")); 00255 gtk_window_set_transient_for(GTK_WINDOW(help_dialog), 00256 GTK_WINDOW(info->dialog)); 00257 00258 /* Connect the signals */ 00259 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, help_dialog); 00260 00261 g_object_unref(G_OBJECT(builder)); 00262 00263 gtk_widget_show(help_dialog); 00264 } 00265 00266 static void 00267 run_account_picker_dialog (GNCImportMainMatcher *info, 00268 GtkTreeModel *model, 00269 GtkTreeIter *iter, 00270 GNCImportTransInfo *trans_info) 00271 { 00272 Account *old_acc, *new_acc; 00273 gboolean ok_pressed; 00274 g_assert (trans_info); 00275 old_acc = gnc_import_TransInfo_get_destacc (trans_info); 00276 new_acc = gnc_import_select_account(info->dialog, 00277 NULL, 00278 TRUE, 00279 _("Destination account for the auto-balance split."), 00280 xaccTransGetCurrency(gnc_import_TransInfo_get_trans(trans_info)), 00281 ACCT_TYPE_NONE, 00282 old_acc, 00283 &ok_pressed); 00284 if (ok_pressed) 00285 { 00286 gnc_import_TransInfo_set_destacc (trans_info, 00287 new_acc, 00288 TRUE); 00289 00290 /* Iterate through the transactions in a given clist to auto match them */ 00291 automatch_store_transactions(info, model, iter, trans_info); 00292 } 00293 } 00294 00295 static void 00296 run_match_dialog (GNCImportMainMatcher *info, 00297 GNCImportTransInfo *trans_info) 00298 { 00299 gnc_import_match_picker_run_and_close (trans_info); 00300 } 00301 00302 static void 00303 gnc_gen_trans_add_toggled_cb (GtkCellRendererToggle *cell_renderer, 00304 gchar *path, 00305 GNCImportMainMatcher *gui) 00306 { 00307 GtkTreeModel *model; 00308 GtkTreeIter iter; 00309 GNCImportTransInfo *trans_info; 00310 00311 model = gtk_tree_view_get_model(gui->view); 00312 if (!gtk_tree_model_get_iter_from_string(model, &iter, path)) 00313 return; 00314 gtk_tree_model_get(model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1); 00315 00316 if ( gnc_import_TransInfo_get_action(trans_info) == GNCImport_ADD 00317 && gnc_import_Settings_get_action_skip_enabled (gui->user_settings) == TRUE) 00318 { 00319 gnc_import_TransInfo_set_action(trans_info, GNCImport_SKIP); 00320 } 00321 else 00322 { 00323 gnc_import_TransInfo_set_action(trans_info, GNCImport_ADD); 00324 } 00325 refresh_model_row(gui, model, &iter, trans_info); 00326 } 00327 00328 static void 00329 gnc_gen_trans_clear_toggled_cb (GtkCellRendererToggle *cell_renderer, 00330 gchar *path, 00331 GNCImportMainMatcher *gui) 00332 { 00333 GtkTreeModel *model; 00334 GtkTreeIter iter; 00335 GNCImportTransInfo *trans_info; 00336 00337 model = gtk_tree_view_get_model(gui->view); 00338 if (!gtk_tree_model_get_iter_from_string(model, &iter, path)) 00339 return; 00340 gtk_tree_model_get(model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1); 00341 00342 if ( gnc_import_TransInfo_get_action(trans_info) == GNCImport_CLEAR 00343 && gnc_import_Settings_get_action_skip_enabled (gui->user_settings) == TRUE) 00344 { 00345 gnc_import_TransInfo_set_action(trans_info, GNCImport_SKIP); 00346 } 00347 else 00348 { 00349 gnc_import_TransInfo_set_action(trans_info, GNCImport_CLEAR); 00350 } 00351 refresh_model_row(gui, model, &iter, trans_info); 00352 } 00353 00354 static void 00355 gnc_gen_trans_update_toggled_cb (GtkCellRendererToggle *cell_renderer, 00356 gchar *path, 00357 GNCImportMainMatcher *gui) 00358 { 00359 GtkTreeModel *model; 00360 GtkTreeIter iter; 00361 GNCImportTransInfo *trans_info; 00362 00363 model = gtk_tree_view_get_model(gui->view); 00364 if (!gtk_tree_model_get_iter_from_string(model, &iter, path)) 00365 return; 00366 gtk_tree_model_get(model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1); 00367 00368 if ( gnc_import_TransInfo_get_action(trans_info) == GNCImport_UPDATE 00369 && gnc_import_Settings_get_action_skip_enabled (gui->user_settings) == TRUE) 00370 { 00371 gnc_import_TransInfo_set_action(trans_info, GNCImport_SKIP); 00372 } 00373 else 00374 { 00375 gnc_import_TransInfo_set_action(trans_info, GNCImport_UPDATE); 00376 } 00377 refresh_model_row(gui, model, &iter, trans_info); 00378 } 00379 00380 static void 00381 gnc_gen_trans_row_activated_cb (GtkTreeView *view, 00382 GtkTreePath *path, 00383 GtkTreeViewColumn *column, 00384 GNCImportMainMatcher *gui) 00385 { 00386 GtkTreeModel *model; 00387 GtkTreeIter iter; 00388 GNCImportTransInfo *trans_info; 00389 00390 model = gtk_tree_view_get_model(gui->view); 00391 if (!gtk_tree_model_get_iter(model, &iter, path)) 00392 return; 00393 gtk_tree_model_get(model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1); 00394 00395 switch (gnc_import_TransInfo_get_action (trans_info)) 00396 { 00397 case GNCImport_ADD: 00398 if (gnc_import_TransInfo_is_balanced(trans_info) == FALSE) 00399 { 00400 run_account_picker_dialog (gui, model, &iter, trans_info); 00401 } 00402 break; 00403 case GNCImport_CLEAR: 00404 case GNCImport_UPDATE: 00405 run_match_dialog (gui, trans_info); 00406 break; 00407 case GNCImport_SKIP: 00408 /*The information displayed is only informative, until you select an action*/ 00409 break; 00410 default: 00411 PERR("I don't know what to do! (Yet...)"); 00412 } 00413 refresh_model_row(gui, model, &iter, trans_info); 00414 } 00415 00416 static void 00417 gnc_gen_trans_row_changed_cb (GtkTreeSelection *selection, 00418 GNCImportMainMatcher *gui) 00419 { 00420 GtkTreeModel *model; 00421 GtkTreeIter iter; 00422 00423 if (!gtk_tree_selection_get_selected(selection, &model, &iter)) 00424 return; 00425 gtk_tree_selection_unselect_iter(selection, &iter); 00426 } 00427 00428 static GtkTreeViewColumn * 00429 add_text_column(GtkTreeView *view, const gchar *title, int col_num) 00430 { 00431 GtkCellRenderer *renderer; 00432 GtkTreeViewColumn *column; 00433 00434 renderer = gtk_cell_renderer_text_new(); 00435 g_object_set(G_OBJECT(renderer), 00436 "foreground", "black", 00437 "foreground-set", TRUE, 00438 NULL); 00439 column = gtk_tree_view_column_new_with_attributes 00440 (title, renderer, 00441 "text", col_num, 00442 "background", DOWNLOADED_COL_COLOR, 00443 NULL); 00444 gtk_tree_view_column_set_sort_column_id(column, col_num); 00445 g_object_set(G_OBJECT(column), 00446 "reorderable", TRUE, 00447 "resizable", TRUE, 00448 NULL); 00449 gtk_tree_view_append_column(view, column); 00450 return column; 00451 } 00452 00453 static GtkTreeViewColumn * 00454 add_toggle_column(GtkTreeView *view, const gchar *title, int col_num, 00455 GCallback cb_fn, gpointer cb_arg) 00456 { 00457 GtkCellRenderer *renderer; 00458 GtkTreeViewColumn *column; 00459 00460 renderer = gtk_cell_renderer_toggle_new(); 00461 column = gtk_tree_view_column_new_with_attributes 00462 (title, renderer, 00463 "active", col_num, 00464 "cell-background", DOWNLOADED_COL_COLOR, 00465 NULL); 00466 gtk_tree_view_column_set_sort_column_id(column, col_num); 00467 g_object_set(G_OBJECT(column), 00468 "reorderable", TRUE, 00469 NULL); 00470 g_signal_connect(renderer, "toggled", cb_fn, cb_arg); 00471 gtk_tree_view_append_column(view, column); 00472 return column; 00473 } 00474 00475 static void 00476 gnc_gen_trans_init_view (GNCImportMainMatcher *info, 00477 gboolean show_account, 00478 gboolean show_update) 00479 { 00480 GtkTreeView *view; 00481 GtkListStore *store; 00482 GtkCellRenderer *renderer; 00483 GtkTreeViewColumn *column; 00484 GtkTreeSelection *selection; 00485 00486 view = info->view; 00487 store = gtk_list_store_new(NUM_DOWNLOADED_COLS, 00488 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, 00489 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, 00490 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING, 00491 GDK_TYPE_PIXBUF, G_TYPE_POINTER, G_TYPE_STRING); 00492 gtk_tree_view_set_model(view, GTK_TREE_MODEL(store)); 00493 g_object_unref(store); 00494 00495 /* Add the columns */ 00496 add_text_column(view, _("Date"), DOWNLOADED_COL_DATE); 00497 column = add_text_column(view, _("Account"), DOWNLOADED_COL_ACCOUNT); 00498 gtk_tree_view_column_set_visible(column, show_account); 00499 add_text_column(view, _("Amount"), DOWNLOADED_COL_AMOUNT); 00500 add_text_column(view, _("Description"), DOWNLOADED_COL_DESCRIPTION); 00501 add_text_column(view, _("Memo"), DOWNLOADED_COL_MEMO); 00502 add_toggle_column(view, _("A"), DOWNLOADED_COL_ACTION_ADD, 00503 G_CALLBACK(gnc_gen_trans_add_toggled_cb), info); 00504 column = add_toggle_column(view, _("U+R"), DOWNLOADED_COL_ACTION_UPDATE, 00505 G_CALLBACK(gnc_gen_trans_update_toggled_cb), info); 00506 gtk_tree_view_column_set_visible(column, show_update); 00507 add_toggle_column(view, _("R"), DOWNLOADED_COL_ACTION_CLEAR, 00508 G_CALLBACK(gnc_gen_trans_clear_toggled_cb), info); 00509 00510 /* The last column has multiple renderers */ 00511 renderer = gtk_cell_renderer_pixbuf_new(); 00512 g_object_set(renderer, "xalign", 0.0, NULL); 00513 column = gtk_tree_view_column_new_with_attributes(_("Info"), renderer, 00514 "pixbuf", DOWNLOADED_COL_ACTION_PIXBUF, 00515 "cell-background", DOWNLOADED_COL_COLOR, 00516 NULL); 00517 renderer = gtk_cell_renderer_text_new(); 00518 g_object_set(G_OBJECT(renderer), 00519 "foreground", "black", 00520 "foreground-set", TRUE, 00521 NULL); 00522 gtk_tree_view_column_pack_start(column, renderer, TRUE); 00523 gtk_tree_view_column_set_attributes(column, renderer, 00524 "text", DOWNLOADED_COL_ACTION_INFO, 00525 "background", DOWNLOADED_COL_COLOR, 00526 NULL); 00527 gtk_tree_view_column_set_sort_column_id(column, DOWNLOADED_COL_ACTION_INFO); 00528 g_object_set(G_OBJECT(column), 00529 "reorderable", TRUE, 00530 "resizable", TRUE, 00531 NULL); 00532 gtk_tree_view_append_column(info->view, column); 00533 00534 00535 selection = gtk_tree_view_get_selection(info->view); 00536 g_signal_connect(info->view, "row-activated", 00537 G_CALLBACK(gnc_gen_trans_row_activated_cb), info); 00538 g_signal_connect(selection, "changed", 00539 G_CALLBACK(gnc_gen_trans_row_changed_cb), info); 00540 } 00541 00542 GNCImportMainMatcher *gnc_gen_trans_list_new (GtkWidget *parent, 00543 const gchar* heading, 00544 gboolean all_from_same_account, 00545 gint match_date_hardlimit) 00546 { 00547 GNCImportMainMatcher *info; 00548 GtkBuilder *builder; 00549 GtkWidget *heading_label; 00550 GtkWidget *button, *box, *pbox; 00551 gboolean show_update; 00552 00553 info = g_new0 (GNCImportMainMatcher, 1); 00554 00555 /* Initialize user Settings. */ 00556 info->user_settings = gnc_import_Settings_new (); 00557 gnc_import_Settings_set_match_date_hardlimit (info->user_settings, match_date_hardlimit); 00558 00559 /* Initialize the GtkDialog. */ 00560 builder = gtk_builder_new(); 00561 gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher"); 00562 gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_content"); 00563 info->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher")); 00564 g_assert (info->dialog != NULL); 00565 00566 /* Pack the content into the dialog vbox */ 00567 pbox = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_vbox")); 00568 box = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_content")); 00569 gtk_box_pack_start( GTK_BOX(pbox), box, TRUE, TRUE, 0); 00570 00571 /* Get the view */ 00572 info->view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "downloaded_view")); 00573 g_assert (info->view != NULL); 00574 00575 show_update = gnc_import_Settings_get_action_update_enabled(info->user_settings); 00576 gnc_gen_trans_init_view(info, all_from_same_account, show_update); 00577 heading_label = GTK_WIDGET(gtk_builder_get_object (builder, "heading_label")); 00578 g_assert (heading_label != NULL); 00579 00580 /* if (parent) 00581 gtk_window_set_transient_for (GTK_WINDOW (info->dialog), 00582 GTK_WINDOW (parent));*/ 00583 00584 /*Initialise the colors */ 00585 gdk_color_parse(COLOR_RED, &info->color_back_red); 00586 gdk_color_parse(COLOR_YELLOW, &info->color_back_yellow); 00587 gdk_color_parse(COLOR_GREEN, &info->color_back_green); 00588 00589 if (heading) 00590 gtk_label_set_text (GTK_LABEL (heading_label), heading); 00591 00592 gnc_restore_window_size(GCONF_SECTION, GTK_WINDOW(info->dialog)); 00593 gtk_widget_show_all (GTK_WIDGET (info->dialog)); 00594 00595 info->transaction_processed_cb = NULL; 00596 00597 /* Connect the signals */ 00598 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, info); 00599 00600 g_object_unref(G_OBJECT(builder)); 00601 00602 return info; 00603 } 00604 00605 /***************************************************************** 00606 * Assistant routines Start * 00607 *****************************************************************/ 00608 00609 GNCImportMainMatcher * gnc_gen_trans_assist_new (GtkWidget *parent, 00610 const gchar* heading, 00611 gboolean all_from_same_account, 00612 gint match_date_hardlimit) 00613 { 00614 GNCImportMainMatcher *info; 00615 GtkBuilder *builder; 00616 GtkWidget *heading_label; 00617 GtkWidget *button, *box, *pbox; 00618 gboolean show_update; 00619 00620 info = g_new0 (GNCImportMainMatcher, 1); 00621 00622 /* Initialize user Settings. */ 00623 info->user_settings = gnc_import_Settings_new (); 00624 gnc_import_Settings_set_match_date_hardlimit (info->user_settings, match_date_hardlimit); 00625 00626 /* load the interface */ 00627 builder = gtk_builder_new(); 00628 gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_content"); 00629 if (builder == NULL) 00630 { 00631 PERR("Error opening the glade builder interface"); 00632 } 00633 /* Pack content into Assistant page widget */ 00634 box = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_content")); 00635 gtk_box_pack_start( GTK_BOX(parent), box, TRUE, TRUE, 6); 00636 00637 /* Get the view */ 00638 info->view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "downloaded_view")); 00639 g_assert (info->view != NULL); 00640 00641 show_update = gnc_import_Settings_get_action_update_enabled(info->user_settings); 00642 gnc_gen_trans_init_view(info, all_from_same_account, show_update); 00643 heading_label = GTK_WIDGET(gtk_builder_get_object (builder, "heading_label")); 00644 g_assert (heading_label != NULL); 00645 00646 /*Initialise the colors */ 00647 gdk_color_parse(COLOR_RED, &info->color_back_red); 00648 gdk_color_parse(COLOR_YELLOW, &info->color_back_yellow); 00649 gdk_color_parse(COLOR_GREEN, &info->color_back_green); 00650 00651 if (heading) 00652 gtk_label_set_text (GTK_LABEL (heading_label), heading); 00653 00654 info->transaction_processed_cb = NULL; 00655 00656 /* Connect the signals */ 00657 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, info); 00658 00659 g_object_unref(G_OBJECT(builder)); 00660 00661 return info; 00662 } 00663 00664 void gnc_gen_trans_assist_start (GNCImportMainMatcher *info) 00665 { 00666 on_matcher_ok_clicked (NULL, info); 00667 } 00668 00669 /***************************************************************** 00670 * Assistant routines End * 00671 *****************************************************************/ 00672 00673 void gnc_gen_trans_list_add_tp_cb(GNCImportMainMatcher *info, 00674 GNCTransactionProcessedCB trans_processed_cb, 00675 gpointer user_data) 00676 { 00677 info->user_data = user_data; 00678 info->transaction_processed_cb = trans_processed_cb; 00679 } 00680 00681 gboolean gnc_gen_trans_list_run (GNCImportMainMatcher *info) 00682 { 00683 gboolean result; 00684 00685 /* DEBUG("Begin"); */ 00686 result = gtk_dialog_run (GTK_DIALOG (info->dialog)); 00687 /* DEBUG("Result was %d", result); */ 00688 00689 /* No destroying here since the dialog was already destroyed through 00690 the ok_clicked handlers. */ 00691 00692 return result; 00693 } 00694 00695 static void 00696 refresh_model_row (GNCImportMainMatcher *gui, 00697 GtkTreeModel *model, 00698 GtkTreeIter *iter, 00699 GNCImportTransInfo *info) 00700 { 00701 GtkListStore *store; 00702 GtkTreeSelection *selection; 00703 gchar *tmp, *imbalance, *text, *color; 00704 const gchar *ro_text; 00705 Split *split; 00706 g_assert (gui); 00707 g_assert (model); 00708 g_assert (info); 00709 /*DEBUG("Begin");*/ 00710 00711 store = GTK_LIST_STORE(model); 00712 gtk_list_store_set(store, iter, DOWNLOADED_COL_DATA, info, -1); 00713 00714 /*Account:*/ 00715 split = gnc_import_TransInfo_get_fsplit (info); 00716 g_assert(split); // Must not be NULL 00717 ro_text = xaccAccountGetName(xaccSplitGetAccount(split)); 00718 gtk_list_store_set(store, iter, DOWNLOADED_COL_ACCOUNT, ro_text, -1); 00719 00720 /*Date*/ 00721 text = qof_print_date ( xaccTransGetDate( gnc_import_TransInfo_get_trans(info) ) ); 00722 gtk_list_store_set(store, iter, DOWNLOADED_COL_DATE, text, -1); 00723 g_free(text); 00724 00725 /*Amount*/ 00726 ro_text = xaccPrintAmount 00727 (xaccSplitGetAmount (split), 00728 gnc_split_amount_print_info(split, TRUE) 00729 ); 00730 gtk_list_store_set(store, iter, DOWNLOADED_COL_AMOUNT, ro_text, -1); 00731 00732 /*Description*/ 00733 ro_text = xaccTransGetDescription(gnc_import_TransInfo_get_trans(info) ); 00734 gtk_list_store_set(store, iter, DOWNLOADED_COL_DESCRIPTION, ro_text, -1); 00735 00736 /*Memo*/ 00737 ro_text = xaccSplitGetMemo(split); 00738 gtk_list_store_set(store, iter, DOWNLOADED_COL_MEMO, ro_text, -1); 00739 00740 /*Actions*/ 00741 00742 /* Action informations */ 00743 ro_text = text = color = NULL; 00744 switch (gnc_import_TransInfo_get_action(info)) 00745 { 00746 case GNCImport_ADD: 00747 if (gnc_import_TransInfo_is_balanced(info) == TRUE) 00748 { 00749 ro_text = _("New, already balanced"); 00750 color = COLOR_GREEN; 00751 } 00752 else 00753 { 00754 /* Assume that importers won't create transactions in two or more 00755 currencies so we can use xaccTransGetImbalanceValue */ 00756 imbalance = 00757 g_strdup 00758 (xaccPrintAmount 00759 (gnc_numeric_neg(xaccTransGetImbalanceValue 00760 (gnc_import_TransInfo_get_trans(info) )), 00761 gnc_commodity_print_info 00762 (xaccTransGetCurrency(gnc_import_TransInfo_get_trans (info)), 00763 TRUE) )); 00764 if (gnc_import_TransInfo_get_destacc (info) != NULL) 00765 { 00766 color = COLOR_GREEN; 00767 tmp = gnc_account_get_full_name 00768 (gnc_import_TransInfo_get_destacc (info)); 00769 if (gnc_import_TransInfo_get_destacc_selected_manually(info) 00770 == TRUE) 00771 { 00772 text = 00773 /* Translators: %1$s is the amount to be 00774 transferred. %2$s is the destination account. */ 00775 g_strdup_printf(_("New, transfer %s to (manual) \"%s\""), 00776 imbalance, tmp); 00777 } 00778 else 00779 { 00780 text = 00781 /* Translators: %1$s is the amount to be 00782 transferred. %2$s is the destination account. */ 00783 g_strdup_printf(_("New, transfer %s to (auto) \"%s\""), 00784 imbalance, tmp); 00785 } 00786 g_free (tmp); 00787 00788 } 00789 else 00790 { 00791 color = COLOR_YELLOW; 00792 text = 00793 /* Translators: %s is the amount to be transferred. */ 00794 g_strdup_printf(_("New, UNBALANCED (need acct to transfer %s)!"), 00795 imbalance); 00796 } 00797 g_free (imbalance); 00798 } 00799 break; 00800 case GNCImport_CLEAR: 00801 if (gnc_import_TransInfo_get_selected_match(info)) 00802 { 00803 color = COLOR_GREEN; 00804 if (gnc_import_TransInfo_get_match_selected_manually(info) == TRUE) 00805 { 00806 ro_text = _("Reconcile (manual) match"); 00807 } 00808 else 00809 { 00810 ro_text = _("Reconcile (auto) match"); 00811 } 00812 } 00813 else 00814 { 00815 color = COLOR_RED; 00816 ro_text = _("Match missing!"); 00817 } 00818 break; 00819 case GNCImport_UPDATE: 00820 if (gnc_import_TransInfo_get_selected_match(info)) 00821 { 00822 color = COLOR_GREEN; 00823 if (gnc_import_TransInfo_get_match_selected_manually(info) == TRUE) 00824 { 00825 ro_text = _("Update and reconcile (manual) match"); 00826 } 00827 else 00828 { 00829 ro_text = _("Update and reconcile (auto) match"); 00830 } 00831 } 00832 else 00833 { 00834 color = COLOR_RED; 00835 ro_text = _("Match missing!"); 00836 } 00837 break; 00838 case GNCImport_SKIP: 00839 color = COLOR_RED; 00840 ro_text = _("Do not import (no action selected)"); 00841 break; 00842 default: 00843 color = "white"; 00844 ro_text = "WRITEME, this is an unknown action"; 00845 } 00846 00847 gtk_list_store_set(store, iter, 00848 DOWNLOADED_COL_COLOR, color, 00849 DOWNLOADED_COL_ACTION_INFO, ro_text ? ro_text : text, 00850 -1); 00851 if (text) 00852 g_free(text); 00853 00854 /* Set the pixmaps */ 00855 gtk_list_store_set(store, iter, 00856 DOWNLOADED_COL_ACTION_ADD, 00857 gnc_import_TransInfo_get_action(info) == GNCImport_ADD, 00858 -1); 00859 if (gnc_import_TransInfo_get_action(info) == GNCImport_SKIP) 00860 { 00861 /*Show the best match's confidence pixmap in the info column*/ 00862 gtk_list_store_set(store, iter, 00863 DOWNLOADED_COL_ACTION_PIXBUF, 00864 gen_probability_pixbuf( gnc_import_MatchInfo_get_probability 00865 ( gnc_import_TransInfo_get_selected_match (info)), 00866 gui->user_settings, 00867 GTK_WIDGET(gui->view)), 00868 -1); 00869 } 00870 00871 gtk_list_store_set(store, iter, 00872 DOWNLOADED_COL_ACTION_CLEAR, 00873 gnc_import_TransInfo_get_action(info) == GNCImport_CLEAR, 00874 -1); 00875 if (gnc_import_TransInfo_get_action(info) == GNCImport_CLEAR) 00876 { 00877 /*Show the best match's confidence pixmap in the info column*/ 00878 gtk_list_store_set(store, iter, 00879 DOWNLOADED_COL_ACTION_PIXBUF, 00880 gen_probability_pixbuf( gnc_import_MatchInfo_get_probability 00881 ( gnc_import_TransInfo_get_selected_match (info)), 00882 gui->user_settings, 00883 GTK_WIDGET(gui->view)), 00884 -1); 00885 } 00886 00887 gtk_list_store_set(store, iter, 00888 DOWNLOADED_COL_ACTION_UPDATE, 00889 gnc_import_TransInfo_get_action(info) == GNCImport_UPDATE, 00890 -1); 00891 if (gnc_import_TransInfo_get_action(info) == GNCImport_UPDATE) 00892 { 00893 /*Show the best match's confidence pixmap in the info column*/ 00894 gtk_list_store_set(store, iter, 00895 DOWNLOADED_COL_ACTION_PIXBUF, 00896 gen_probability_pixbuf( gnc_import_MatchInfo_get_probability 00897 ( gnc_import_TransInfo_get_selected_match (info)), 00898 gui->user_settings, 00899 GTK_WIDGET(gui->view)), 00900 -1); 00901 } 00902 00903 selection = gtk_tree_view_get_selection(gui->view); 00904 gtk_tree_selection_unselect_all(selection); 00905 } 00906 00907 void gnc_gen_trans_list_add_trans(GNCImportMainMatcher *gui, Transaction *trans) 00908 { 00909 gnc_gen_trans_list_add_trans_with_ref_id(gui, trans, 0); 00910 return; 00911 }/* end gnc_import_add_trans() */ 00912 00913 void gnc_gen_trans_list_add_trans_with_ref_id(GNCImportMainMatcher *gui, Transaction *trans, guint32 ref_id) 00914 { 00915 GNCImportTransInfo * transaction_info = NULL; 00916 GtkTreeModel *model; 00917 GtkTreeIter iter; 00918 g_assert (gui); 00919 g_assert (trans); 00920 00921 00922 if (gnc_import_exists_online_id (trans)) 00923 return; 00924 else 00925 { 00926 transaction_info = gnc_import_TransInfo_new(trans, NULL); 00927 gnc_import_TransInfo_set_ref_id(transaction_info, ref_id); 00928 00929 gnc_import_TransInfo_init_matches(transaction_info, 00930 gui->user_settings); 00931 00932 model = gtk_tree_view_get_model(gui->view); 00933 gtk_list_store_append(GTK_LIST_STORE(model), &iter); 00934 refresh_model_row (gui, model, &iter, transaction_info); 00935 } 00936 return; 00937 }/* end gnc_import_add_trans_with_ref_id() */ 00938 00939 /* Iterate through the rows of the clist and try to automatch each of them */ 00940 static void 00941 automatch_store_transactions (GNCImportMainMatcher *info, 00942 GtkTreeModel *model, 00943 GtkTreeIter *iter, 00944 GNCImportTransInfo *trans_info) 00945 { 00946 /* returns TRUE if we changed this row, so update it */ 00947 if (gnc_import_TransInfo_refresh_destacc(trans_info, NULL)) 00948 { 00949 refresh_model_row(info, model, iter, trans_info); 00950 } 00951 } 00952 00953 GtkWidget *gnc_gen_trans_list_widget (GNCImportMainMatcher *info) 00954 { 00955 g_assert(info); 00956 return info->dialog; 00957 } 00958
1.7.4