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