GnuCash  5.6-150-g038405b370+
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"
32 #include "dialog-custom-report.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"
42 #include "gnc-plugin-page-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 */
48 enum
49 {
50  COL_NAME = 0,
51  COL_NUM,
52  NUM_COLS
53 };
54 
55 enum
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 */
65 typedef 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 
83 void custom_report_dialog_destroy_cb (GtkWidget* widget, gpointer data);
84 void custom_report_dialog_close_cb(GtkWidget* widget, gpointer data);
85 void custom_report_help_cb(GtkWidget* widget, gpointer data);
86 void close_custom_report_clicked_cb(GtkWidget* widget, gpointer data);
87 void custom_report_list_view_row_activated_cb(GtkTreeView *view, GtkTreePath *path,
88  GtkTreeViewColumn *column, gpointer data);
89 gboolean custom_report_list_view_clicked_cb(GtkTreeView *view, GdkEventButton *event, gpointer data);
90 void custom_report_name_edited_cb(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer data);
91 gboolean custom_report_query_tooltip_cb (GtkTreeView *view,
92  gint x,
93  gint y,
94  gboolean keyboard_mode,
95  GtkTooltip *tooltip,
96  gpointer data);
97 
98 static gboolean
99 tree_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 
108 static void
109 empty_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 
115 void
116 custom_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 
123 void
124 custom_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 
132 void
133 custom_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 
139 void
140 close_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  ********************************************************************/
152 static void
153 update_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 
194 static GtkTreeModel *
195 create_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 
206 static void
207 set_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  **************************************************************/
265 static void
266 custom_report_run_report(SCM guid,
267  CustomReportDialog *crd)
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  **************************************************************/
294 static void
295 custom_report_edit_report_name (SCM guid,
296  CustomReportDialog *crd,
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  *********************************************************************/
318 static void
319 custom_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  *********************************************************************/
350 static SCM
351 get_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  **************************************************************/
384 void
385 custom_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  **************************************************************/
419 gboolean
420 custom_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 
460 void
461 custom_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 
497 gboolean
498 custom_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 
535 static gboolean
536 custom_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 */
549 static CustomReportDialog *
550 gnc_ui_custom_report_internal(GncMainWindow * window)
551 {
552  GtkBuilder *builder;
553  CustomReportDialog *crd;
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  ***********************************************************/
622 void
623 gnc_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  ***********************************************************/
634 void
635 gnc_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 
684 cleanup:
685  guid_free (guid);
686  g_free (guid_str);
687 }
utility functions for the GnuCash UI
gboolean string_to_guid(const gchar *string, GncGUID *guid)
Given a string, replace the given guid with the parsed one unless the given value is null...
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:173
Functions for adding content to a window.
This file contains the functions to present a GUI to manage custom reports.
GncGUID * guid_malloc(void)
Allocate memory for a GUID.
Definition: guid.cpp:104
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome&#39;s yelp for linux, and open to a given link within a gi...
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:204
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
Definition: guid.h:84
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:1026
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:1101
gchar * guid_to_string(const GncGUID *guid)
The guid_to_string() routine returns a null-terminated string encoding of the id. ...
Definition: guid.cpp:164
The type used to store guids in C.
Definition: guid.h:75
This column holds a copy of the check format name and is what is displayed to the user in the combobo...