GnuCash c935c2f+
Loading...
Searching...
No Matches
dialog-custom-report.c
1/**************************************************************************\
2 * dialog-custom-report.c -- dialog for managing custom reports *
3 * *
4 * Copyright (C) 2009 Andrew Sackville-West (andrew@swclan.homelinux.org) *
5 * *
6 * This program is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU General Public License as *
8 * published by the Free Software Foundation; either version 2 of *
9 * the License, or (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, contact: *
18 * *
19 * Free Software Foundation Voice: +1-617-542-5942 *
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21 * Boston, MA 02110-1301, USA gnu@gnu.org *
22\*************************************************************************/
23
24#include <config.h>
25
26#include <glib/gi18n.h>
27#include <gtk/gtk.h>
28#include <libguile.h>
29#include "swig-runtime.h"
30
31#include "business-gnome-utils.h"
33#include "dialog-utils.h"
34#include "gnc-main-window.h"
35#include "window-report.h"
36#include "guile-mappings.h"
37#include "gnc-guile-utils.h"
38#include "gnc-gui-query.h"
39#include "gnc-ui.h"
40#include "gnc-ui-util.h"
41#include "gnc-report.h"
43
44#define GNC_PREFS_GROUP_REPORT_SAVED_CONFIGS "dialogs.report-saved-configs"
45
46/* convenience for accessing columns in the GtkListStore that holds
47 the reports */
48enum
49{
50 COL_NAME = 0,
51 COL_NUM,
52 NUM_COLS
53};
54
55enum
56{
57 VIEW_COL_NAME = 0,
58 VIEW_COL_RUN,
59 VIEW_COL_EDIT,
60 VIEW_COL_DELETE,
61 NUM_VIEW_COLS
62};
63
64/* all the pertinent stuff needed to pass around */
65typedef struct _CustomReportDialog
66{
67 /* dialog */
68 GtkWidget *dialog;
69 GtkWidget *reportview;
70 GncMainWindow *window;
71 GtkTreeViewColumn *namecol;
72 GtkCellRenderer *namerenderer;
73 GtkTreeViewColumn *runcol;
74 GtkTreeViewColumn *editcol;
75 GtkTreeViewColumn *delcol;
76 GtkTreeViewColumn *dummycol;
77
78 /* data */
79 SCM reportlist;
80
82
83void custom_report_dialog_destroy_cb (GtkWidget* widget, gpointer data);
84void custom_report_dialog_close_cb(GtkWidget* widget, gpointer data);
85void custom_report_help_cb(GtkWidget* widget, gpointer data);
86void close_custom_report_clicked_cb(GtkWidget* widget, gpointer data);
87void custom_report_list_view_row_activated_cb(GtkTreeView *view, GtkTreePath *path,
88 GtkTreeViewColumn *column, gpointer data);
89gboolean custom_report_list_view_clicked_cb(GtkTreeView *view, GdkEventButton *event, gpointer data);
90void custom_report_name_edited_cb(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer data);
91gboolean custom_report_query_tooltip_cb (GtkTreeView *view,
92 gint x,
93 gint y,
94 gboolean keyboard_mode,
95 GtkTooltip *tooltip,
96 gpointer data);
97
98static gboolean
99tree_model_free (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
100 gpointer data)
101{
102 GncGUID *guid;
103 gtk_tree_model_get (model, iter, COL_NUM, &guid, -1);
104 guid_free (guid);
105 return FALSE;
106}
107
108static void
109empty_tree_model (GtkTreeModel *model)
110{
111 gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc)tree_model_free, NULL);
112 gtk_list_store_clear (GTK_LIST_STORE (model));
113}
114
115void
116custom_report_dialog_destroy_cb (GtkWidget* widget, gpointer data)
117{
118 CustomReportDialog *crd = data;
119 empty_tree_model (gtk_tree_view_get_model (GTK_TREE_VIEW(crd->reportview)));
120 g_free (crd);
121}
122
123void
124custom_report_dialog_close_cb(GtkWidget* widget, gpointer data)
125{
126 CustomReportDialog *crd = data;
127 gnc_save_window_size(GNC_PREFS_GROUP_REPORT_SAVED_CONFIGS, GTK_WINDOW(crd->dialog));
128
129 gtk_widget_destroy(crd->dialog);
130}
131
132void
133custom_report_help_cb (GtkWidget *widget, gpointer data)
134{
135 CustomReportDialog *crd = data;
136 gnc_gnome_help (GTK_WINDOW(crd->dialog), DF_MANUAL, DL_USAGE_CUSTOMREP);
137}
138
139void
140close_custom_report_clicked_cb(GtkWidget* widget, gpointer data)
141{
142 CustomReportDialog *crd = data;
143 custom_report_dialog_close_cb(NULL, crd);
144}
145
146/********************************************************************
147 * update_report_list
148 *
149 * this procedure does the real work of displaying a sorted list of
150 * available custom reports
151 ********************************************************************/
152static void
153update_report_list(GtkListStore *store, CustomReportDialog *crd)
154{
155 SCM get_rpt_guids = scm_c_eval_string("gnc:custom-report-template-guids");
156 SCM template_menu_name = scm_c_eval_string("gnc:report-template-menu-name/report-guid");
157 SCM rpt_guids;
158 GtkTreeIter iter;
159 GtkTreeModel *model = GTK_TREE_MODEL (store);
160
161 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), COL_NAME, GTK_SORT_ASCENDING);
162
163 crd->reportlist = scm_call_0(get_rpt_guids);
164 rpt_guids = crd->reportlist;
165
166 empty_tree_model (model);
167
168 if (scm_is_list(rpt_guids))
169 {
170 /* for all the report guids in the list, store them, with a reference,
171 in the gtkliststore */
172 while ( !scm_is_null(rpt_guids) )
173 {
174 GncGUID *guid = guid_malloc ();
175 gchar *guid_str = scm_to_utf8_string (SCM_CAR(rpt_guids));
176 gchar *name = gnc_scm_to_utf8_string (scm_call_2(template_menu_name, SCM_CAR(rpt_guids), SCM_BOOL_F));
177
178 if (string_to_guid (guid_str, guid))
179 {
180 gtk_list_store_append(store, &iter);
181 gtk_list_store_set(store, &iter,
182 COL_NAME, name,
183 COL_NUM, guid,
184 -1);
185 }
186 g_free (name);
187 g_free (guid_str);
188
189 rpt_guids = SCM_CDR(rpt_guids);
190 }
191 }
192}
193
194static GtkTreeModel *
195create_and_fill_report_list(CustomReportDialog *crd)
196{
197 GtkListStore *store;
198
199 store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_POINTER);
200
201 update_report_list(store, crd);
202
203 return GTK_TREE_MODEL (store);
204}
205
206static void
207set_reports_view_and_model(CustomReportDialog *crd)
208{
209 GtkCellRenderer *renderer;
210 GtkTreeModel *model;
211 gint number_of_columns;
212
213 crd->namerenderer = gtk_cell_renderer_text_new();
214 g_signal_connect (G_OBJECT (crd->namerenderer), "edited",
215 G_CALLBACK (custom_report_name_edited_cb), crd);
216 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (crd->reportview), -1,
217 "Report Name", crd->namerenderer,
218 "text", COL_NAME,
219 NULL);
220 crd->namecol = gtk_tree_view_get_column (GTK_TREE_VIEW (crd->reportview), VIEW_COL_NAME);
221 gtk_tree_view_column_set_expand (crd->namecol, TRUE);
222
223 renderer = gtk_cell_renderer_pixbuf_new();
224 g_object_set (G_OBJECT (renderer), "icon-name", "system-run", NULL);
225 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (crd->reportview), -1,
226 "R", renderer,
227 NULL);
228 crd->runcol = gtk_tree_view_get_column (GTK_TREE_VIEW (crd->reportview), VIEW_COL_RUN);
229
230 renderer = gtk_cell_renderer_pixbuf_new();
231 g_object_set (G_OBJECT (renderer), "icon-name", "accessories-text-editor", NULL);
232 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (crd->reportview), -1,
233 "E", renderer,
234 NULL);
235 crd->editcol = gtk_tree_view_get_column (GTK_TREE_VIEW (crd->reportview), VIEW_COL_EDIT);
236
237 renderer = gtk_cell_renderer_pixbuf_new();
238 g_object_set (G_OBJECT (renderer), "icon-name", "edit-delete", NULL);
239 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (crd->reportview), -1,
240 "D", renderer,
241 NULL);
242 crd->delcol = gtk_tree_view_get_column (GTK_TREE_VIEW (crd->reportview), VIEW_COL_DELETE);
243
244 // this is a dummy column which will be set the same width of the vertical scrollbar
245 renderer = gtk_cell_renderer_text_new();
246 number_of_columns = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (crd->reportview), -1,
247 "", renderer,
248 NULL);
249
250 crd->dummycol = gtk_tree_view_get_column (GTK_TREE_VIEW (crd->reportview), number_of_columns -1);
251
252 model = create_and_fill_report_list(crd);
253
254 gtk_tree_view_set_model (GTK_TREE_VIEW (crd->reportview), model);
255
256 g_object_unref(model);
257}
258
259/**************************************************************
260 * custom_report_run_report
261 *
262 * this procedure sets up and calls the report on the scheme
263 * side. This is what makes the report actually run.
264 **************************************************************/
265static void
266custom_report_run_report(SCM guid,
268{
269 SCM make_report = scm_c_eval_string("gnc:make-report");
270 int report_id;
271 GncMainWindow *window = crd->window;
272
273 if (scm_is_null(guid))
274 return;
275
276 /* this generates the report */
277 report_id = scm_to_int (scm_call_1(make_report, guid));
278
279 /* do this *before* displaying the report because sometimes that
280 takes a while... */
281 custom_report_dialog_close_cb(NULL, crd);
282
283 /* display the report */
284 gnc_main_window_open_report(report_id, window);
285
286}
287
288/**************************************************************
289 * custom_report_run_report
290 *
291 * this procedure sets up and calls the report on the scheme
292 * side. This is what makes the report actually run.
293 **************************************************************/
294static void
295custom_report_edit_report_name (SCM guid,
297 gchar *new_name)
298{
299 SCM rename_report = scm_c_eval_string("gnc:rename-report");
300 SCM new_name_scm = scm_from_utf8_string(new_name);
301
302 if (scm_is_null(guid) || !new_name || (*new_name == '\0'))
303 return;
304
305 /* rename the report */
306 scm_call_2(rename_report, guid, new_name_scm);
307 update_report_list(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(crd->reportview))),
308 crd);
309
310}
311
312/*********************************************************************
313 * custom_report_delete
314 *
315 * this will delete the report, update the reports list and leave the
316 * dialog active for additional usage.
317 *********************************************************************/
318static void
319custom_report_delete (SCM guid, CustomReportDialog *crd)
320{
321 SCM template_menu_name = scm_c_eval_string("gnc:report-template-menu-name/report-guid");
322 gchar *report_name;
323
324 if (scm_is_null (guid))
325 return;
326
327 report_name = gnc_scm_to_utf8_string(scm_call_2(template_menu_name, guid, SCM_BOOL_F));
328
329 /* we must confirm the user wants to delete their precious custom report! */
330 if (gnc_verify_dialog( GTK_WINDOW (crd->dialog), FALSE, _("Are you sure you want to delete %s?"), report_name))
331 {
332 SCM del_report = scm_c_eval_string("gnc:delete-report");
333 scm_call_1(del_report, guid);
334 update_report_list(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(crd->reportview))),
335 crd);
336 }
337 g_free (report_name);
338}
339
340/********************************************************************
341 * get_custom_report_selection
342 *
343 * this helper function is called to get the selection when the user
344 * clicks on "Run" or "Delete". Includes calling a dialog when there
345 * is no selection.
346 *
347 * const gchar* message -- the message to provide user if there is no
348 * actual selection found.
349 *********************************************************************/
350static SCM
351get_custom_report_selection(CustomReportDialog *crd,
352 const gchar* message)
353{
354 GtkTreeSelection *sel;
355 GtkTreeModel *model;
356 GtkTreeIter iter;
357 GncGUID *guid;
358 gchar *guid_str;
359 SCM scm_guid;
360
361 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(crd->reportview));
362
363 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
364 {
365 /* no selection, notify user */
366 gnc_error_dialog (GTK_WINDOW (crd->dialog), "%s", message);
367 return SCM_EOL;
368 }
369
370 gtk_tree_model_get (model, &iter, COL_NUM, &guid, -1);
371 guid_str = guid_to_string (guid);
372 scm_guid = scm_from_utf8_string (guid_str);
373 g_free (guid_str);
374 return scm_guid;
375}
376
377/**************************************************************
378 * custom_report_list_view_row_activated_cb
379 *
380 * this is the double-click signal. No need to call
381 * get_custom_report_selection as the double-click implies the
382 * selection.
383 **************************************************************/
384void
385custom_report_list_view_row_activated_cb(GtkTreeView *view, GtkTreePath *path,
386 GtkTreeViewColumn *column, gpointer data)
387{
388 CustomReportDialog *crd = data;
389 GtkTreeModel *model;
390 GtkTreeIter iter;
391
392 model = gtk_tree_view_get_model(view);
393
394 if (gtk_tree_model_get_iter(model, &iter, path))
395 {
396 if (column == crd->namecol)
397 {
398 GncGUID *guid;
399 gchar *guid_str;
400
401 gtk_tree_model_get(model, &iter, COL_NUM, &guid, -1);
402 guid_str = g_new0 (gchar, GUID_ENCODING_LENGTH+1 );
403 guid_to_string_buff (guid, guid_str);
404
405 custom_report_run_report(scm_from_utf8_string (guid_str), crd);
406 g_free (guid_str);
407 }
408 }
409}
410
411/**************************************************************
412 * custom_report_list_view_clicked_cb
413 *
414 * this callback is called whenever a user clicked somewhere in
415 * the treeview widget. If the click was on an edit or delete
416 * pictogram, the corresponding action will be executed on the
417 * selected row.
418 **************************************************************/
419gboolean
420custom_report_list_view_clicked_cb(GtkTreeView *view, GdkEventButton *event, gpointer data)
421{
422 CustomReportDialog *crd = data;
423 GtkTreePath *path = NULL;
424 GtkTreeViewColumn *column = NULL;
425 gint cellx, celly;
426
427 g_return_val_if_fail ( view != NULL, FALSE );
428
429 if (gtk_tree_view_get_path_at_pos (view, event->x, event->y,
430 &path, &column,
431 &cellx, &celly))
432 {
433 if (column == crd->runcol)
434 {
435 SCM guid = get_custom_report_selection(crd, _("You must select a report configuration to load."));
436 custom_report_run_report (guid, crd);
437 gtk_tree_path_free (path);
438 return TRUE;
439 }
440 else if (column == crd->editcol)
441 {
442 g_object_set(G_OBJECT(crd->namerenderer), "editable", TRUE, NULL);
443 gtk_tree_view_set_cursor_on_cell (view, path, crd->namecol,
444 crd->namerenderer, TRUE);
445 gtk_tree_path_free (path);
446 return TRUE;
447 }
448 else if (column == crd->delcol)
449 {
450 SCM guid = get_custom_report_selection(crd, _("You must select a report configuration to delete."));
451 custom_report_delete (guid, crd);
452 gtk_tree_path_free (path);
453 return TRUE;
454 }
455 gtk_tree_path_free (path);
456 }
457 return FALSE;
458}
459
460void
461custom_report_name_edited_cb(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer data)
462{
463 CustomReportDialog *crd = data;
464 SCM guid = get_custom_report_selection(crd, _("Unable to change report configuration name."));
465 SCM unique_name_func = scm_c_eval_string("gnc:report-template-has-unique-name?");
466 SCM new_name_scm = scm_from_utf8_string(new_text);
467
468 g_object_set(G_OBJECT(crd->namerenderer), "editable", FALSE, NULL);
469 if (scm_is_null (guid))
470 return;
471
472 if (scm_is_true (scm_call_2 (unique_name_func, guid, new_name_scm)))
473 {
474 gchar *default_guid = gnc_get_default_invoice_print_report ();
475 gchar *guid_string = scm_to_utf8_string (guid);
476
477 custom_report_edit_report_name (guid, crd, new_text);
478
479 // check to see if default report name has been changed
480 if (g_strcmp0 (default_guid, guid_string) == 0)
481 {
482 QofBook *book = gnc_get_current_book ();
483 gchar *default_name = qof_book_get_default_invoice_report_name (book);
484
485 if (g_strcmp0 (default_name, new_text) != 0)
486 qof_book_set_default_invoice_report (book, default_guid, new_text);
487 g_free (default_name);
488 }
489 g_free (guid_string);
490 g_free (default_guid);
491 }
492 else
493 gnc_error_dialog (GTK_WINDOW (crd->dialog), "%s",
494 _("A saved report configuration with this name already exists, please choose another name.") );
495}
496
497gboolean
498custom_report_query_tooltip_cb (GtkTreeView *view,
499 gint x,
500 gint y,
501 gboolean keyboard_mode,
502 GtkTooltip *tooltip,
503 gpointer data)
504{
505 CustomReportDialog *crd = data;
506 GtkTreePath *path = NULL;
507 GtkTreeViewColumn *column = NULL;
508 gint cellx, celly;
509
510 g_return_val_if_fail ( view != NULL, FALSE );
511
512 if (gtk_tree_view_get_path_at_pos (view, x, y,
513 &path, &column,
514 &cellx, &celly))
515 {
516 if (column != crd->namecol)
517 {
518 gtk_tree_view_set_tooltip_cell (view, tooltip, path, column, NULL);
519 if (column == crd->runcol)
520 gtk_tooltip_set_text (tooltip, _("Load report configuration"));
521 else if (column == crd->editcol)
522 gtk_tooltip_set_text (tooltip, _("Edit report configuration name"));
523 else if (column == crd->delcol)
524 gtk_tooltip_set_text (tooltip, _("Delete report configuration"));
525 gtk_tree_path_free (path);
526 return TRUE;
527 }
528 else
529 gtk_tooltip_set_text (tooltip, NULL);
530 gtk_tree_path_free (path);
531 }
532 return FALSE;
533}
534
535static gboolean
536custom_report_event_cb (GtkWidget *widget, GdkEventKey *event,
537 gpointer user_data)
538{
539 if (event->keyval == GDK_KEY_Escape)
540 {
541 custom_report_dialog_close_cb (widget, user_data);
542 return TRUE;
543 }
544 return FALSE;
545}
546
547
548/* Internal function that builds the dialog */
549static CustomReportDialog *
550gnc_ui_custom_report_internal(GncMainWindow * window)
551{
552 GtkBuilder *builder;
554 GtkTreeIter iter;
555 GtkTreeModel *model;
556 GtkWidget *no_report_notification;
557 GtkWidget *scroll_window;
558 GtkWidget *vscroll;
559 GtkRequisition nat_sb;
560
561 crd = g_new0(CustomReportDialog, 1);
562
563 builder = gtk_builder_new();
564 gnc_builder_add_from_file (builder, "dialog-custom-report.glade", "custom_report_dialog");
565
566 crd->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "custom_report_dialog"));
567 crd->reportview = GTK_WIDGET(gtk_builder_get_object (builder, "custom_report_list_view"));
568 scroll_window = GTK_WIDGET(gtk_builder_get_object (builder, "custom_report_sw"));
569 no_report_notification = GTK_WIDGET(gtk_builder_get_object (builder, "label2"));
570 set_reports_view_and_model(crd);
571 crd->window = window;
572
573 // get the vertical scroll bar width
574 vscroll = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (scroll_window));
575 gtk_widget_get_preferred_size (vscroll, NULL, &nat_sb);
576
577 // set the width of the dummy column to that of the scrollbar
578 gtk_tree_view_column_set_fixed_width (crd->dummycol, nat_sb.width);
579
580 gtk_window_set_transient_for (GTK_WINDOW (crd->dialog), GTK_WINDOW(window));
581
582 // Set the name for this dialog so it can be easily manipulated with css
583 gtk_widget_set_name (GTK_WIDGET(crd->dialog), "gnc-id-custom-report");
584
585 gnc_restore_window_size (GNC_PREFS_GROUP_REPORT_SAVED_CONFIGS,
586 GTK_WINDOW(crd->dialog), GTK_WINDOW(window));
587
588 /* connect the signals */
589 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, crd);
590
591 gtk_widget_show_all(crd->dialog);
592
593 // Use this event to capture the escape key being pressed
594 g_signal_connect (crd->dialog, "key_press_event",
595 G_CALLBACK(custom_report_event_cb), crd);
596
597 /* check if there are currently saved reports available
598 * by checking if there is a first element */
599 model = gtk_tree_view_get_model (GTK_TREE_VIEW (crd->reportview));
600 if (gtk_tree_model_get_iter_first (model, &iter))
601 {
602 /* saved reports available
603 -> hide the "no reports available" notification */
604 gtk_widget_hide(no_report_notification);
605 }
606 else
607 {
608 /* hide the scrolled window of the report list */
609 gtk_widget_hide(crd->reportview);
610 }
611
612 g_object_unref(G_OBJECT(builder));
613
614 return crd;
615}
616
617/***********************************************************
618 * gnc_ui_custom_report
619 *
620 * this is the primary driver for the custom report dialog.
621 ***********************************************************/
622void
623gnc_ui_custom_report(GncMainWindow * window)
624{
625 gnc_ui_custom_report_internal (window);
626}
627
628/***********************************************************
629 * gnc_ui_custom_report_edit_name
630 *
631 * open the custom report dialog and highlight the given
632 * report's name for editing.
633 ***********************************************************/
634void
635gnc_ui_custom_report_edit_name (GncMainWindow * window, SCM scm_guid)
636{
637 SCM is_custom_report;
638 CustomReportDialog *crd = gnc_ui_custom_report_internal (window);
639 GtkTreeModel *model;
640 GtkTreeIter iter;
641 GncGUID *guid;
642 gchar *guid_str;
643 gboolean valid_iter;
644
645 is_custom_report = scm_c_eval_string ("gnc:report-template-is-custom/template-guid?");
646 if (scm_is_false (scm_call_1 (is_custom_report, scm_guid)))
647 return;
648
649 guid = guid_malloc ();
650 guid_str = scm_to_utf8_string (scm_guid);
651 if (!string_to_guid (guid_str, guid))
652 goto cleanup;
653
654 /* Look up the row for the requested guid */
655 model = gtk_tree_view_get_model (GTK_TREE_VIEW (crd->reportview));
656 valid_iter = gtk_tree_model_get_iter_first (model, &iter);
657
658 while (valid_iter)
659 {
660 GncGUID *row_guid;
661 gtk_tree_model_get (model, &iter, COL_NUM, &row_guid, -1);
662
663 if (guid_equal (guid, row_guid))
664 {
665 /* We found the row for the requested guid
666 * Now let's set the report's name cell in edit mode
667 * so the user can edit the name.
668 */
669 GtkTreePath *path;
670 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (crd->reportview));
671 gtk_tree_selection_select_iter (selection, &iter);
672 path = gtk_tree_model_get_path (model, &iter);
673 g_object_set(G_OBJECT(crd->namerenderer), "editable", TRUE, NULL);
674 gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (crd->reportview),
675 path, crd->namecol,
676 crd->namerenderer, TRUE);
677 gtk_tree_path_free (path);
678 break;
679 }
680
681 valid_iter = gtk_tree_model_iter_next (model, &iter);
682 }
683
684cleanup:
685 guid_free (guid);
686 g_free (guid_str);
687}
This file contains the functions to present a GUI to manage custom reports.
Functions for adding content to a window.
utility functions for the GnuCash UI
gchar * qof_book_get_default_invoice_report_name(const QofBook *book)
Get the name of the Invoice Report to be used as the default for printing Invoices.
Definition qofbook.cpp:1119
void qof_book_set_default_invoice_report(QofBook *book, const gchar *guid, const gchar *name)
Save the Invoice Report name / guid to be used as the default for printing Invoices.
Definition qofbook.cpp:1044
gchar * guid_to_string(const GncGUID *guid)
The guid_to_string() routine returns a null-terminated string encoding of the id.
Definition guid.cpp:199
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
Definition guid.h:84
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Given two GUIDs, return TRUE if they are non-NULL and equal.
Definition guid.cpp:237
GncGUID * guid_malloc(void)
Allocate memory for a GUID.
Definition guid.cpp:139
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
Definition guid.cpp:208
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
The type used to store guids in C.
Definition guid.h:75
QofBook reference.
Definition qofbook-p.hpp:47