00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026
00027 #include <gtk/gtk.h>
00028 #include <glib/gi18n.h>
00029 #include <stdio.h>
00030 #include <libguile.h>
00031
00032 #include "dialog-account-picker.h"
00033 #include "dialog-utils.h"
00034 #include "druid-qif-import.h"
00035 #include "gnc-gui-query.h"
00036 #include "gnc-ui-util.h"
00037 #include "guile-mappings.h"
00038 #include "gnc-ui.h"
00039
00040 enum account_cols
00041 {
00042 ACCOUNT_COL_NAME = 0,
00043 ACCOUNT_COL_FULLNAME,
00044 ACCOUNT_COL_CHECK,
00045 NUM_ACCOUNT_COLS
00046 };
00047
00048 struct _accountpickerdialog
00049 {
00050 GtkWidget * dialog;
00051 GtkTreeView * treeview;
00052 QIFImportWindow * qif_wind;
00053 SCM map_entry;
00054 gchar * selected_name;
00055 };
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 static void
00069 acct_tree_add_accts(SCM accts,
00070 GtkTreeStore *store,
00071 GtkTreeIter *parent,
00072 const char *base_name,
00073 const char *search_name,
00074 GtkTreeRowReference **reference)
00075 {
00076 GtkTreeIter iter;
00077 const char * compname;
00078 char * acctname;
00079 gboolean leafnode;
00080 SCM current;
00081 gboolean checked;
00082
00083 while (!scm_is_null(accts))
00084 {
00085 current = SCM_CAR(accts);
00086
00087 if (scm_is_null(current))
00088 {
00089 g_critical("QIF import: BUG DETECTED in acct_tree_add_accts!");
00090 accts = SCM_CDR(accts);
00091 continue;
00092 }
00093
00094 if (scm_is_string(SCM_CAR(current)))
00095 compname = scm_to_locale_string(SCM_CAR(current));
00096 else
00097 compname = "";
00098
00099 if (!scm_is_null(SCM_CADDR(current)))
00100 {
00101 leafnode = FALSE;
00102 }
00103 else
00104 {
00105 leafnode = TRUE;
00106 }
00107
00108
00109 if (base_name && *base_name)
00110 {
00111 acctname = g_strjoin(gnc_get_account_separator_string(),
00112 base_name, compname, (char *)NULL);
00113 }
00114 else
00115 {
00116 acctname = g_strdup(compname);
00117 }
00118
00119 checked = (SCM_CADR(current) == SCM_BOOL_T);
00120
00121 gtk_tree_store_append(store, &iter, parent);
00122 gtk_tree_store_set(store, &iter,
00123 ACCOUNT_COL_NAME, compname,
00124 ACCOUNT_COL_FULLNAME, acctname,
00125 ACCOUNT_COL_CHECK, checked,
00126 -1);
00127
00128 if (reference && !*reference &&
00129 search_name && (g_utf8_collate(search_name, acctname) == 0))
00130 {
00131 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
00132 *reference = gtk_tree_row_reference_new(GTK_TREE_MODEL(store), path);
00133 gtk_tree_path_free(path);
00134 }
00135
00136 if (!leafnode)
00137 {
00138 acct_tree_add_accts(SCM_CADDR(current), store, &iter, acctname,
00139 search_name, reference);
00140 }
00141
00142 g_free(acctname);
00143
00144 accts = SCM_CDR(accts);
00145 }
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155 static void
00156 build_acct_tree(QIFAccountPickerDialog * picker, QIFImportWindow * import)
00157 {
00158 SCM get_accts = scm_c_eval_string("qif-import:get-all-accts");
00159 SCM acct_tree;
00160 GtkTreeStore *store;
00161 GtkTreePath *path;
00162 GtkTreeSelection* selection;
00163 GtkTreeRowReference *reference = NULL;
00164 gchar *name_to_select;
00165
00166 g_return_if_fail(picker && import);
00167
00168
00169 acct_tree = scm_call_1(get_accts,
00170 gnc_ui_qif_import_druid_get_mappings(import));
00171
00172
00173
00174
00175 name_to_select = g_strdup(picker->selected_name);
00176 store = GTK_TREE_STORE(gtk_tree_view_get_model(picker->treeview));
00177 gtk_tree_store_clear(store);
00178 acct_tree_add_accts(acct_tree, store, NULL, NULL, name_to_select, &reference);
00179 g_free(name_to_select);
00180
00181
00182 if (reference)
00183 {
00184 selection = gtk_tree_view_get_selection(picker->treeview);
00185 path = gtk_tree_row_reference_get_path(reference);
00186 if (path)
00187 {
00188 gtk_tree_view_expand_to_path(picker->treeview, path);
00189 gtk_tree_selection_select_path(selection, path);
00190 gtk_tree_path_free(path);
00191 }
00192 gtk_tree_row_reference_free(reference);
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 static void
00205 gnc_ui_qif_account_picker_new_cb(GtkButton * w, gpointer user_data)
00206 {
00207 QIFAccountPickerDialog * wind = user_data;
00208 SCM name_setter = scm_c_eval_string("qif-map-entry:set-gnc-name!");
00209 const gchar *name;
00210 int response;
00211 gchar *fullname;
00212 GtkWidget *dlg, *entry;
00213
00214
00215 dlg = gtk_message_dialog_new(GTK_WINDOW(wind->dialog),
00216 GTK_DIALOG_DESTROY_WITH_PARENT,
00217 GTK_MESSAGE_QUESTION,
00218 GTK_BUTTONS_OK_CANCEL,
00219 "%s", _("Enter a name for the account"));
00220 gtk_dialog_set_default_response(GTK_DIALOG(dlg), GTK_RESPONSE_OK);
00221 entry = gtk_entry_new();
00222 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
00223 gtk_entry_set_max_length(GTK_ENTRY(entry), 250);
00224 gtk_widget_show(entry);
00225 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dlg)->vbox), entry);
00226
00227
00228 response = gtk_dialog_run(GTK_DIALOG(dlg));
00229 name = gtk_entry_get_text(GTK_ENTRY(entry));
00230
00231
00232 if (response == GTK_RESPONSE_OK && name && *name)
00233 {
00234
00235 if (wind->selected_name && *(wind->selected_name))
00236
00237 fullname = g_strjoin(gnc_get_account_separator_string(),
00238 wind->selected_name, name, (char *)NULL);
00239 else
00240 fullname = g_strdup(name);
00241
00242
00243 g_free(wind->selected_name);
00244 wind->selected_name = fullname;
00245 scm_call_2(name_setter, wind->map_entry, scm_makfrom0str(fullname));
00246 }
00247 gtk_widget_destroy(dlg);
00248
00249
00250 build_acct_tree(wind, wind->qif_wind);
00251 gtk_widget_grab_focus(GTK_WIDGET(wind->treeview));
00252 }
00253
00254 static void
00255 gnc_ui_qif_account_picker_changed_cb(GtkTreeSelection *selection,
00256 gpointer user_data)
00257 {
00258 QIFAccountPickerDialog * wind = user_data;
00259 SCM name_setter = scm_c_eval_string("qif-map-entry:set-gnc-name!");
00260 GtkTreeModel *model;
00261 GtkTreeIter iter;
00262
00263 g_free(wind->selected_name);
00264 if (gtk_tree_selection_get_selected(selection, &model, &iter))
00265 {
00266 gtk_tree_model_get(model, &iter,
00267 ACCOUNT_COL_FULLNAME, &wind->selected_name,
00268 -1);
00269 scm_call_2(name_setter, wind->map_entry,
00270 scm_makfrom0str(wind->selected_name));
00271 }
00272 else
00273 {
00274 wind->selected_name = NULL;
00275 }
00276 }
00277
00278 static void
00279 gnc_ui_qif_account_picker_row_activated_cb(GtkTreeView *view,
00280 GtkTreePath *path,
00281 GtkTreeViewColumn *column,
00282 gpointer user_data)
00283 {
00284 QIFAccountPickerDialog *wind = user_data;
00285 g_return_if_fail(wind);
00286
00287 gtk_dialog_response(GTK_DIALOG(wind->dialog), GTK_RESPONSE_OK);
00288 }
00289
00290 static int
00291 gnc_ui_qif_account_picker_map_cb(GtkWidget * w, gpointer user_data)
00292 {
00293 QIFAccountPickerDialog * wind = user_data;
00294
00295
00296
00297
00298 build_acct_tree(wind, wind->qif_wind);
00299 return FALSE;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 gboolean
00313 qif_account_picker_dialog(QIFImportWindow * qif_wind, SCM map_entry)
00314 {
00315 QIFAccountPickerDialog * wind;
00316 SCM gnc_name = scm_c_eval_string("qif-map-entry:gnc-name");
00317 SCM set_gnc_name = scm_c_eval_string("qif-map-entry:set-gnc-name!");
00318 SCM orig_acct = scm_call_1(gnc_name, map_entry);
00319 int response;
00320 GladeXML *xml;
00321 GtkWidget *button;
00322
00323 wind = g_new0(QIFAccountPickerDialog, 1);
00324
00325
00326 wind->map_entry = map_entry;
00327 scm_gc_protect_object(wind->map_entry);
00328
00329
00330 wind->selected_name = g_strdup(scm_to_locale_string(orig_acct));
00331
00332
00333 xml = gnc_glade_xml_new("qif.glade", "QIF Import Account Picker");
00334
00335 glade_xml_signal_connect_data(xml,
00336 "gnc_ui_qif_account_picker_new_cb",
00337 G_CALLBACK(gnc_ui_qif_account_picker_new_cb),
00338 wind);
00339
00340 wind->dialog = glade_xml_get_widget(xml, "QIF Import Account Picker");
00341 wind->treeview = GTK_TREE_VIEW(glade_xml_get_widget(xml, "account_tree"));
00342 wind->qif_wind = qif_wind;
00343
00344
00345 {
00346 GtkTreeStore *store;
00347 GtkCellRenderer *renderer;
00348 GtkTreeViewColumn *column;
00349 GtkTreeSelection *selection;
00350
00351 store = gtk_tree_store_new(NUM_ACCOUNT_COLS, G_TYPE_STRING, G_TYPE_STRING,
00352 G_TYPE_BOOLEAN);
00353 gtk_tree_view_set_model(wind->treeview, GTK_TREE_MODEL(store));
00354 g_object_unref(store);
00355
00356 renderer = gtk_cell_renderer_text_new();
00357 column = gtk_tree_view_column_new_with_attributes(_("Account"),
00358 renderer,
00359 "text",
00360 ACCOUNT_COL_NAME,
00361 NULL);
00362 g_object_set(column, "expand", TRUE, NULL);
00363 gtk_tree_view_append_column(wind->treeview, column);
00364
00365 renderer = gtk_cell_renderer_toggle_new();
00366 g_object_set(renderer, "activatable", FALSE, NULL);
00367 column = gtk_tree_view_column_new_with_attributes(_("New?"),
00368 renderer,
00369 "active",
00370 ACCOUNT_COL_CHECK,
00371 NULL);
00372 gtk_tree_view_append_column(wind->treeview, column);
00373
00374 selection = gtk_tree_view_get_selection(wind->treeview);
00375 g_signal_connect(selection, "changed",
00376 G_CALLBACK(gnc_ui_qif_account_picker_changed_cb), wind);
00377 g_signal_connect(wind->treeview, "row-activated",
00378 G_CALLBACK(gnc_ui_qif_account_picker_row_activated_cb),
00379 wind);
00380 }
00381
00382 g_signal_connect_after(wind->dialog, "map",
00383 G_CALLBACK(gnc_ui_qif_account_picker_map_cb),
00384 wind);
00385
00386 button = glade_xml_get_widget(xml, "newbutton");
00387 gtk_button_set_use_stock(GTK_BUTTON(button), TRUE);
00388
00389
00390
00391 build_acct_tree(wind, wind->qif_wind);
00392
00393 do
00394 {
00395 response = gtk_dialog_run(GTK_DIALOG(wind->dialog));
00396 }
00397 while (response == GNC_RESPONSE_NEW);
00398 gtk_widget_destroy(wind->dialog);
00399
00400 scm_gc_unprotect_object(wind->map_entry);
00401 g_free(wind->selected_name);
00402 g_free(wind);
00403
00404 if (response == GTK_RESPONSE_OK)
00405 return TRUE;
00406
00407
00408 scm_call_2(set_gnc_name, map_entry, orig_acct);
00409
00410 return FALSE;
00411 }