00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025
00026 #include <glib/gi18n.h>
00027 #include <libguile.h>
00028 #include "swig-runtime.h"
00029
00030 #include "dialog-column-view.h"
00031 #include "dialog-options.h"
00032 #include "dialog-utils.h"
00033 #include "option-util.h"
00034 #include "window-report.h"
00035 #include "guile-mappings.h"
00036 #include "gnc-report.h"
00037
00038 enum available_cols
00039 {
00040 AVAILABLE_COL_NAME = 0,
00041 AVAILABLE_COL_ROW,
00042 NUM_AVAILABLE_COLS
00043 };
00044
00045 enum contents_cols
00046 {
00047 CONTENTS_COL_NAME = 0,
00048 CONTENTS_COL_ROW,
00049 CONTENTS_COL_REPORT_ROWS,
00050 CONTENTS_COL_REPORT_COLS,
00051 NUM_CONTENTS_COLS
00052 };
00053
00054 struct gncp_column_view_edit
00055 {
00056 GNCOptionWin * optwin;
00057 GtkTreeView * available;
00058 GtkTreeView * contents;
00059
00060 SCM options;
00061 SCM view;
00062 GNCOptionDB * odb;
00063
00064 SCM available_list;
00065 int available_selected;
00066
00067 SCM contents_list;
00068 int contents_selected;
00069 };
00070
00071 static void gnc_column_view_edit_add_cb(GtkButton * button,
00072 gpointer user_data);
00073 static void gnc_column_view_edit_remove_cb(GtkButton * button,
00074 gpointer user_data);
00075 static void gnc_edit_column_view_move_up_cb(GtkButton * button,
00076 gpointer user_data);
00077 static void gnc_edit_column_view_move_down_cb(GtkButton * button,
00078 gpointer user_data);
00079 static void gnc_column_view_edit_size_cb(GtkButton * button,
00080 gpointer user_data);
00081
00082
00083 static void
00084 gnc_column_view_set_option(GNCOptionDB * odb, char * section, char * name,
00085 SCM new_value)
00086 {
00087 GNCOption * option =
00088 gnc_option_db_get_option_by_name(odb, section, name);
00089
00090 if (option)
00091 {
00092 gnc_option_db_set_option(odb, section, name, new_value);
00093
00094
00095 gnc_option_set_changed (option, TRUE);
00096 }
00097 }
00098
00099 static void
00100 gnc_column_view_edit_destroy(gnc_column_view_edit * view)
00101 {
00102 gnc_options_dialog_destroy(view->optwin);
00103 scm_gc_unprotect_object(view->options);
00104 scm_gc_unprotect_object(view->view);
00105 gnc_option_db_destroy(view->odb);
00106 g_free(view);
00107 }
00108
00109 static void
00110 update_display_lists(gnc_column_view_edit * view)
00111 {
00112 SCM get_names = scm_c_eval_string("gnc:all-report-template-names");
00113 SCM template_menu_name = scm_c_eval_string("gnc:report-template-menu-name/report-guid");
00114 SCM report_menu_name = scm_c_eval_string("gnc:report-menu-name");
00115 SCM names = scm_call_0(get_names);
00116 SCM contents =
00117 gnc_option_db_lookup_option(view->odb, "__general", "report-list",
00118 SCM_BOOL_F);
00119 SCM this_report;
00120 SCM selection;
00121 const gchar *name;
00122 int row, i, id;
00123 GtkListStore *store;
00124 GtkTreeIter iter;
00125 GtkTreePath *path;
00126 GtkTreeSelection *tree_selection;
00127
00128
00129
00130 row = view->available_selected;
00131
00132 if (scm_is_list(view->available_list) && !scm_is_null (view->available_list))
00133 {
00134 row = MIN (row, scm_ilength (view->available_list) - 1);
00135 selection = scm_list_ref (view->available_list, scm_int2num (row));
00136 }
00137 else
00138 {
00139 selection = SCM_UNDEFINED;
00140 }
00141
00142 scm_gc_unprotect_object(view->available_list);
00143 view->available_list = names;
00144 scm_gc_protect_object(view->available_list);
00145
00146 store = GTK_LIST_STORE(gtk_tree_view_get_model(view->available));
00147 gtk_list_store_clear(store);
00148
00149 if (scm_is_list(names))
00150 {
00151 for (i = 0; !scm_is_null(names); names = SCM_CDR(names), i++)
00152 {
00153 if (scm_is_equal (SCM_CAR(names), selection))
00154 row = i;
00155 name = _(scm_to_locale_string(scm_call_2(template_menu_name, SCM_CAR(names),
00156 SCM_BOOL_F)));
00157 gtk_list_store_append(store, &iter);
00158 gtk_list_store_set(store, &iter,
00159 AVAILABLE_COL_NAME, name,
00160 AVAILABLE_COL_ROW, i,
00161 -1);
00162 }
00163
00164 }
00165
00166 tree_selection = gtk_tree_view_get_selection(view->available);
00167 path = gtk_tree_path_new_from_indices(row, -1);
00168 gtk_tree_selection_select_path(tree_selection, path);
00169 gtk_tree_path_free(path);
00170
00171
00172
00173 row = view->contents_selected;
00174
00175 if (scm_is_list(view->contents_list) && !scm_is_null (view->contents_list))
00176 {
00177 row = MIN (row, scm_ilength (view->contents_list) - 1);
00178 selection = scm_list_ref (view->contents_list, scm_int2num (row));
00179 }
00180 else
00181 {
00182 selection = SCM_UNDEFINED;
00183 }
00184
00185 scm_gc_unprotect_object(view->contents_list);
00186 view->contents_list = contents;
00187 scm_gc_protect_object(view->contents_list);
00188
00189 store = GTK_LIST_STORE(gtk_tree_view_get_model(view->contents));
00190 gtk_list_store_clear(store);
00191 if (scm_is_list(contents))
00192 {
00193 for (i = 0; !scm_is_null(contents); contents = SCM_CDR(contents), i++)
00194 {
00195 if (scm_is_equal (SCM_CAR(contents), selection))
00196 row = i;
00197
00198 id = scm_num2int(SCM_CAAR(contents), SCM_ARG1, G_STRFUNC);
00199 this_report = gnc_report_find(id);
00200 name = _(scm_to_locale_string(scm_call_1(report_menu_name, this_report)));
00201
00202 gtk_list_store_append(store, &iter);
00203 gtk_list_store_set
00204 (store, &iter,
00205 CONTENTS_COL_NAME, name,
00206 CONTENTS_COL_ROW, i,
00207 CONTENTS_COL_REPORT_COLS, scm_num2int(SCM_CADR(SCM_CAR(contents)),
00208 SCM_ARG1, G_STRFUNC),
00209 CONTENTS_COL_REPORT_ROWS, scm_num2int(SCM_CADDR(SCM_CAR(contents)),
00210 SCM_ARG1, G_STRFUNC),
00211 -1);
00212 }
00213 }
00214
00215 tree_selection = gtk_tree_view_get_selection(view->contents);
00216 path = gtk_tree_path_new_from_indices(row, -1);
00217 gtk_tree_selection_select_path(tree_selection, path);
00218
00219 gtk_tree_path_free(path);
00220 }
00221
00222 static void
00223 gnc_column_view_select_avail_cb(GtkTreeSelection *selection,
00224 gnc_column_view_edit *r)
00225 {
00226 GtkTreeModel *model;
00227 GtkTreeIter iter;
00228
00229 if (gtk_tree_selection_get_selected(selection, &model, &iter))
00230 gtk_tree_model_get(model, &iter,
00231 AVAILABLE_COL_ROW, &r->available_selected,
00232 -1);
00233 }
00234
00235 static void
00236 gnc_column_view_select_contents_cb(GtkTreeSelection *selection,
00237 gnc_column_view_edit *r)
00238 {
00239 GtkTreeModel *model;
00240 GtkTreeIter iter;
00241
00242 if (gtk_tree_selection_get_selected(selection, &model, &iter))
00243 gtk_tree_model_get(model, &iter,
00244 AVAILABLE_COL_ROW, &r->contents_selected,
00245 -1);
00246 }
00247
00248 static void
00249 gnc_column_view_edit_apply_cb(GNCOptionWin * w, gpointer user_data)
00250 {
00251 SCM dirty_report = scm_c_eval_string("gnc:report-set-dirty?!");
00252 gnc_column_view_edit * win = user_data;
00253
00254 if (!win) return;
00255 gnc_option_db_commit(win->odb);
00256 scm_call_2(dirty_report, win->view, SCM_BOOL_T);
00257 }
00258
00259 static void
00260 gnc_column_view_edit_close_cb(GNCOptionWin * win, gpointer user_data)
00261 {
00262 gnc_column_view_edit * r = user_data;
00263 SCM set_editor = scm_c_eval_string("gnc:report-set-editor-widget!");
00264
00265 scm_call_2(set_editor, r->view, SCM_BOOL_F);
00266 gnc_column_view_edit_destroy(r);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 GtkWidget *
00276 gnc_column_view_edit_options(SCM options, SCM view)
00277 {
00278 SCM get_editor = scm_c_eval_string("gnc:report-editor-widget");
00279 SCM ptr;
00280 GtkWidget * editor;
00281 GtkListStore *store;
00282 GtkCellRenderer *renderer;
00283 GtkTreeViewColumn *column;
00284 GtkTreeSelection *selection;
00285
00286 ptr = scm_call_1(get_editor, view);
00287 if (ptr != SCM_BOOL_F)
00288 {
00289 #define FUNC_NAME "gtk_window_present"
00290 GtkWindow * w = SWIG_MustGetPtr(ptr, SWIG_TypeQuery("_p_GtkWidget"), 1, 0);
00291 gtk_window_present(w);
00292 #undef FUNC_NAME
00293 return NULL;
00294 }
00295 else
00296 {
00297 gnc_column_view_edit * r = g_new0(gnc_column_view_edit, 1);
00298 GladeXML *xml;
00299
00300 r->optwin = gnc_options_dialog_new(NULL);
00301
00302
00303 {
00304 GtkWidget *dialog, *page_list;
00305
00306 dialog = gnc_options_dialog_widget(r->optwin);
00307 page_list = gnc_glade_lookup_widget (dialog, "page_list");
00308 gtk_widget_hide(page_list);
00309 }
00310
00311 xml = gnc_glade_xml_new ("report.glade", "view_contents_table");
00312
00313 glade_xml_signal_connect_data
00314 (xml, "gnc_column_view_edit_add_cb",
00315 G_CALLBACK (gnc_column_view_edit_add_cb), r);
00316
00317 glade_xml_signal_connect_data
00318 (xml, "gnc_column_view_edit_remove_cb",
00319 G_CALLBACK (gnc_column_view_edit_remove_cb), r);
00320
00321 glade_xml_signal_connect_data
00322 (xml, "gnc_edit_column_view_move_up_cb",
00323 G_CALLBACK (gnc_edit_column_view_move_up_cb), r);
00324
00325 glade_xml_signal_connect_data
00326 (xml, "gnc_edit_column_view_move_down_cb",
00327 G_CALLBACK (gnc_edit_column_view_move_down_cb), r);
00328
00329 glade_xml_signal_connect_data
00330 (xml, "gnc_column_view_edit_size_cb",
00331 G_CALLBACK (gnc_column_view_edit_size_cb), r);
00332
00333 editor = glade_xml_get_widget (xml, "view_contents_table");
00334 r->available = GTK_TREE_VIEW (glade_xml_get_widget (xml, "available_view"));
00335 r->contents = GTK_TREE_VIEW (glade_xml_get_widget (xml, "contents_view"));
00336 r->options = options;
00337 r->view = view;
00338 r->available_selected = 0;
00339 r->available_list = SCM_EOL;
00340 r->contents_selected = 0;
00341 r->contents_list = SCM_EOL;
00342 r->odb = gnc_option_db_new(r->options);
00343
00344 gnc_options_dialog_build_contents(r->optwin, r->odb);
00345
00346 gtk_notebook_append_page(GTK_NOTEBOOK(gnc_options_dialog_notebook
00347 (r->optwin)),
00348 editor,
00349 gtk_label_new(_("Contents")));
00350
00351 scm_gc_protect_object(r->options);
00352 scm_gc_protect_object(r->view);
00353 scm_gc_protect_object(r->available_list);
00354 scm_gc_protect_object(r->contents_list);
00355
00356
00357 store = gtk_list_store_new (NUM_AVAILABLE_COLS, G_TYPE_STRING, G_TYPE_INT);
00358 gtk_tree_view_set_model(r->available, GTK_TREE_MODEL(store));
00359 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), AVAILABLE_COL_NAME, GTK_SORT_ASCENDING);
00360 g_object_unref(store);
00361
00362 renderer = gtk_cell_renderer_text_new();
00363 column = gtk_tree_view_column_new_with_attributes("", renderer,
00364 "text", AVAILABLE_COL_NAME,
00365 NULL);
00366 gtk_tree_view_append_column(r->available, column);
00367
00368 selection = gtk_tree_view_get_selection(r->available);
00369 g_signal_connect(selection, "changed",
00370 G_CALLBACK(gnc_column_view_select_avail_cb), r);
00371
00372
00373 store = gtk_list_store_new (NUM_CONTENTS_COLS, G_TYPE_STRING, G_TYPE_INT,
00374 G_TYPE_INT, G_TYPE_INT);
00375 gtk_tree_view_set_model(r->contents, GTK_TREE_MODEL(store));
00376 g_object_unref(store);
00377
00378 renderer = gtk_cell_renderer_text_new();
00379 column = gtk_tree_view_column_new_with_attributes(_("Report"), renderer,
00380 "text", CONTENTS_COL_NAME,
00381 NULL);
00382 gtk_tree_view_append_column(r->contents, column);
00383
00384 renderer = gtk_cell_renderer_text_new();
00385 column = gtk_tree_view_column_new_with_attributes(_("Rows"), renderer,
00386 "text", CONTENTS_COL_REPORT_ROWS,
00387 NULL);
00388 gtk_tree_view_append_column(r->contents, column);
00389
00390 renderer = gtk_cell_renderer_text_new();
00391 column = gtk_tree_view_column_new_with_attributes(_("Cols"), renderer,
00392 "text", CONTENTS_COL_REPORT_COLS,
00393 NULL);
00394 gtk_tree_view_append_column(r->contents, column);
00395
00396 selection = gtk_tree_view_get_selection(r->contents);
00397 g_signal_connect(selection, "changed",
00398 G_CALLBACK(gnc_column_view_select_contents_cb), r);
00399
00400 update_display_lists(r);
00401
00402 gnc_options_dialog_set_apply_cb(r->optwin,
00403 gnc_column_view_edit_apply_cb, r);
00404 gnc_options_dialog_set_close_cb(r->optwin,
00405 gnc_column_view_edit_close_cb, r);
00406
00407 gtk_widget_show(gnc_options_dialog_widget(r->optwin));
00408 return gnc_options_dialog_widget(r->optwin);
00409 }
00410 }
00411
00412 static void
00413 gnc_column_view_edit_add_cb(GtkButton * button, gpointer user_data)
00414 {
00415 gnc_column_view_edit * r = user_data;
00416 SCM make_report = scm_c_eval_string("gnc:make-report");
00417 SCM mark_report = scm_c_eval_string("gnc:report-set-needs-save?!");
00418 SCM template_name;
00419 SCM new_report;
00420 SCM newlist = SCM_EOL;
00421 SCM oldlist = r->contents_list;
00422 int count;
00423 int oldlength, id;
00424
00425 if (scm_is_list(r->available_list) &&
00426 (scm_ilength(r->available_list) > r->available_selected))
00427 {
00428 template_name = scm_list_ref(r->available_list,
00429 scm_int2num(r->available_selected));
00430 new_report = scm_call_1(make_report, template_name);
00431 id = scm_num2int(new_report, SCM_ARG1, G_STRFUNC);
00432 scm_call_2(mark_report, gnc_report_find(id), SCM_BOOL_T);
00433 oldlength = scm_ilength(r->contents_list);
00434
00435 if (oldlength > r->contents_selected)
00436 {
00437 for (count = 0; count < r->contents_selected; count++)
00438 {
00439 newlist = scm_cons(SCM_CAR(oldlist), newlist);
00440 oldlist = SCM_CDR(oldlist);
00441 }
00442 newlist = scm_append
00443 (scm_listify(scm_reverse(scm_cons(SCM_LIST4(new_report,
00444 scm_int2num(1),
00445 scm_int2num(1),
00446 SCM_BOOL_F),
00447 newlist)),
00448 oldlist,
00449 SCM_UNDEFINED));
00450 }
00451 else
00452 {
00453 newlist = scm_append
00454 (scm_listify(oldlist,
00455 SCM_LIST1(SCM_LIST4(new_report,
00456 scm_int2num(1),
00457 scm_int2num(1),
00458 SCM_BOOL_F)),
00459 SCM_UNDEFINED));
00460 r->contents_selected = oldlength;
00461 }
00462
00463 scm_gc_unprotect_object(r->contents_list);
00464 r->contents_list = newlist;
00465 scm_gc_protect_object(r->contents_list);
00466
00467 gnc_column_view_set_option(r->odb, "__general", "report-list",
00468 r->contents_list);
00469 gnc_options_dialog_changed (r->optwin);
00470 }
00471
00472 update_display_lists(r);
00473 }
00474
00475 static void
00476 gnc_column_view_edit_remove_cb(GtkButton * button, gpointer user_data)
00477 {
00478 gnc_column_view_edit * r = user_data;
00479 SCM newlist = SCM_EOL;
00480 SCM oldlist = r->contents_list;
00481 int count;
00482 int oldlength;
00483
00484 if (scm_is_list(r->contents_list))
00485 {
00486 oldlength = scm_ilength(r->contents_list);
00487 if (oldlength > r->contents_selected)
00488 {
00489 for (count = 0; count < r->contents_selected; count++)
00490 {
00491 newlist = scm_cons(SCM_CAR(oldlist), newlist);
00492 oldlist = SCM_CDR(oldlist);
00493 }
00494 if (count <= oldlength)
00495 {
00496 newlist = scm_append(scm_listify(scm_reverse(newlist), SCM_CDR(oldlist), SCM_UNDEFINED));
00497 }
00498 }
00499
00500 if (r->contents_selected > 0 && oldlength == r->contents_selected + 1)
00501 {
00502 r->contents_selected --;
00503 }
00504
00505 scm_gc_unprotect_object(r->contents_list);
00506 r->contents_list = newlist;
00507 scm_gc_protect_object(r->contents_list);
00508
00509 gnc_column_view_set_option(r->odb, "__general", "report-list",
00510 r->contents_list);
00511
00512 gnc_options_dialog_changed (r->optwin);
00513 }
00514
00515 update_display_lists(r);
00516 }
00517
00518 static void
00519 gnc_edit_column_view_move_up_cb(GtkButton * button, gpointer user_data)
00520 {
00521 gnc_column_view_edit * r = user_data;
00522 SCM oldlist = r->contents_list;
00523 SCM newlist = SCM_EOL;
00524 SCM temp;
00525 int oldlength;
00526 int count;
00527
00528 oldlength = scm_ilength(r->contents_list);
00529 if ((r->contents_selected > 0) && (oldlength > r->contents_selected))
00530 {
00531 for (count = 1; count < r->contents_selected; count++)
00532 {
00533 newlist = scm_cons(SCM_CAR(oldlist), newlist);
00534 oldlist = SCM_CDR(oldlist);
00535 }
00536 temp = SCM_CAR(oldlist);
00537 oldlist = SCM_CDR(oldlist);
00538 newlist = scm_cons(temp, scm_cons(SCM_CAR(oldlist), newlist));
00539 newlist = scm_append(scm_listify(scm_reverse(newlist), SCM_CDR(oldlist), SCM_UNDEFINED));
00540
00541 scm_gc_unprotect_object(r->contents_list);
00542 r->contents_list = newlist;
00543 scm_gc_protect_object(r->contents_list);
00544
00545 r->contents_selected = r->contents_selected - 1;
00546
00547 gnc_column_view_set_option(r->odb, "__general", "report-list",
00548 r->contents_list);
00549
00550 gnc_options_dialog_changed (r->optwin);
00551
00552 update_display_lists(r);
00553 }
00554 }
00555
00556 static void
00557 gnc_edit_column_view_move_down_cb(GtkButton * button, gpointer user_data)
00558 {
00559 gnc_column_view_edit * r = user_data;
00560 SCM oldlist = r->contents_list;
00561 SCM newlist = SCM_EOL;
00562 SCM temp;
00563 int oldlength;
00564 int count;
00565
00566 oldlength = scm_ilength(r->contents_list);
00567 if (oldlength > (r->contents_selected + 1))
00568 {
00569 for (count = 0; count < r->contents_selected; count++)
00570 {
00571 newlist = scm_cons(SCM_CAR(oldlist), newlist);
00572 oldlist = SCM_CDR(oldlist);
00573 }
00574 temp = SCM_CAR(oldlist);
00575 oldlist = SCM_CDR(oldlist);
00576 newlist = scm_cons(temp, scm_cons(SCM_CAR(oldlist), newlist));
00577 newlist = scm_append(scm_listify(scm_reverse(newlist), SCM_CDR(oldlist), SCM_UNDEFINED));
00578
00579 scm_gc_unprotect_object(r->contents_list);
00580 r->contents_list = newlist;
00581 scm_gc_protect_object(r->contents_list);
00582
00583 r->contents_selected = r->contents_selected + 1;
00584
00585 gnc_column_view_set_option(r->odb, "__general", "report-list",
00586 r->contents_list);
00587
00588 gnc_options_dialog_changed (r->optwin);
00589
00590 update_display_lists(r);
00591 }
00592 }
00593
00594 static void
00595 gnc_column_view_edit_size_cb(GtkButton * button, gpointer user_data)
00596 {
00597 gnc_column_view_edit * r = user_data;
00598 GtkWidget * rowspin;
00599 GtkWidget * colspin;
00600 GtkWidget * dlg;
00601 GladeXML *xml;
00602 SCM current;
00603 int length;
00604 int dlg_ret;
00605
00606 xml = gnc_glade_xml_new ("report.glade", "Edit Report Size");
00607 dlg = glade_xml_get_widget (xml, "Edit Report Size");
00608
00609
00610 rowspin = glade_xml_get_widget (xml, "row_spin");
00611 colspin = glade_xml_get_widget (xml, "col_spin");
00612
00613 length = scm_ilength(r->contents_list);
00614 if (length > r->contents_selected)
00615 {
00616 current = scm_list_ref(r->contents_list,
00617 scm_int2num(r->contents_selected));
00618 gtk_spin_button_set_value(GTK_SPIN_BUTTON(colspin),
00619 (float)scm_num2int(SCM_CADR(current),
00620 SCM_ARG1, G_STRFUNC));
00621 gtk_spin_button_set_value(GTK_SPIN_BUTTON(rowspin),
00622 (float)scm_num2int(SCM_CADDR(current),
00623 SCM_ARG1, G_STRFUNC));
00624
00625 dlg_ret = gtk_dialog_run(GTK_DIALOG(dlg));
00626 gtk_widget_hide(dlg);
00627
00628 if (dlg_ret == GTK_RESPONSE_OK)
00629 {
00630 current = SCM_LIST4(SCM_CAR(current),
00631 scm_int2num(gtk_spin_button_get_value_as_int
00632 (GTK_SPIN_BUTTON(colspin))),
00633 scm_int2num(gtk_spin_button_get_value_as_int
00634 (GTK_SPIN_BUTTON(rowspin))),
00635 SCM_BOOL_F);
00636 scm_gc_unprotect_object(r->contents_list);
00637 r->contents_list = scm_list_set_x(r->contents_list,
00638 scm_int2num(r->contents_selected),
00639 current);
00640 scm_gc_protect_object(r->contents_list);
00641 gnc_options_dialog_changed (r->optwin);
00642 update_display_lists(r);
00643 }
00644 gtk_widget_destroy(dlg);
00645 }
00646 }