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