GnuCash  5.6-150-g038405b370+
gnc-tree-view-owner.c
1 /********************************************************************\
2  * gnc-tree-view-owner.c -- GtkTreeView implementation to display *
3  * owners in a GtkTreeView. *
4  * Copyright (C) 2011 Geert Janssens <geert@kobaltwit.be> *
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 
25 #include <config.h>
26 
27 #include <gtk/gtk.h>
28 #include <glib/gi18n.h>
29 #include <string.h>
30 
31 #include "gnc-tree-view.h"
32 #include "gnc-tree-model-owner.h"
33 #include "gnc-tree-view-owner.h"
34 
35 #include "gncOwner.h"
36 #include "gnc-accounting-period.h"
37 #include "gnc-commodity.h"
38 #include "gnc-component-manager.h"
39 #include "gnc-engine.h"
40 #include "gnc-glib-utils.h"
41 #include "gnc-gobject-utils.h"
42 #include "gnc-hooks.h"
43 #include "gnc-session.h"
44 #include "gnc-icons.h"
45 #include "gnc-ui-balances.h"
46 #include "dialog-utils.h"
47 #include "window-main-summarybar.h"
48 
49 #define SAMPLE_OWNER_VALUE "$1,000,000.00"
50 
53 /* This static indicates the debugging module that this .o belongs to. */
54 static QofLogModule log_module = GNC_MOD_GUI;
55 
57 static void gnc_tree_view_owner_finalize (GObject *object);
58 
59 static void gtvo_update_column_names (GncTreeViewOwner *view);
60 static void gtvo_currency_changed_cb (void);
61 
62 static gboolean gnc_tree_view_owner_filter_helper (GtkTreeModel *model,
63  GtkTreeIter *iter,
64  gpointer data);
65 
66 #if 0 /* Not Used */
67 static void gtvo_setup_column_renderer_edited_cb(GncTreeViewOwner *owner_view,
68  GtkTreeViewColumn *column,
69  GtkCellRenderer *renderer,
70  GncTreeViewOwnerColumnTextEdited col_edited_cb);
71 #endif /* Not Used */
72 
74 {
75  GncTreeView gnc_tree_view;
76  int stamp;
77 
78  OwnerViewInfo ovi;
79 
81  gpointer filter_data;
82  GSourceFunc filter_destroy;
83 
84  GtkTreeViewColumn *name_column;
85  GtkTreeViewColumn *id_column;
86  GtkTreeViewColumn *balance_report_column;
87  GtkTreeViewColumn *notes_column;
88 };
89 
90 
91 /************************************************************/
92 /* g_object required functions */
93 /************************************************************/
94 
95 G_DEFINE_TYPE(GncTreeViewOwner, gnc_tree_view_owner, GNC_TYPE_TREE_VIEW)
96 
97 static void
98 gnc_tree_view_owner_class_init (GncTreeViewOwnerClass *klass)
99 {
100  GObjectClass *o_class;
101 
102  /* GObject signals */
103  o_class = G_OBJECT_CLASS (klass);
104  o_class->finalize = gnc_tree_view_owner_finalize;
105 
106  gnc_hook_add_dangler(HOOK_CURRENCY_CHANGED,
107  (GFunc)gtvo_currency_changed_cb, NULL, NULL);
108 }
109 
110 /********************************************************************\
111  * gnc_init_owner_view_info *
112  * initialize an owner view info structure with default values *
113  * *
114  * Args: ovi - structure to initialize *
115  * Returns: nothing *
116 \********************************************************************/
117 static void
118 gnc_init_owner_view_info(OwnerViewInfo *ovi)
119 {
120  ovi->show_inactive = FALSE;
121 }
122 
123 static void
124 gnc_tree_view_owner_init (GncTreeViewOwner *view)
125 {
126  gnc_init_owner_view_info(&view->ovi);
127 }
128 
129 static void
130 gnc_tree_view_owner_finalize (GObject *object)
131 {
132  ENTER("view %p", object);
133  g_return_if_fail (object != NULL);
134  g_return_if_fail (GNC_IS_TREE_VIEW_OWNER (object));
135 
136  GncTreeViewOwner *view = GNC_TREE_VIEW_OWNER (object);
137 
138  if (view->filter_destroy)
139  {
140  view->filter_destroy(view->filter_data);
141  view->filter_destroy = NULL;
142  }
143  view->filter_fn = NULL;
144 
145  G_OBJECT_CLASS (gnc_tree_view_owner_parent_class)->finalize (object);
146  LEAVE(" ");
147 }
148 
149 
150 /************************************************************
151  * Callbacks *
152  ************************************************************/
153 static void
154 gnc_tree_view_owner_active_toggled (GtkCellRendererToggle *cell,
155  const gchar *s_path_str,
156  gpointer user_data)
157 {
158  GncTreeViewOwner *tree_view;
159  GtkTreePath *s_path;
160  GncOwner *owner;
161  gboolean active;
162 
163  /* Change the requested owner */
164  tree_view = user_data;
165  s_path = gtk_tree_path_new_from_string (s_path_str);
166  owner = gnc_tree_view_owner_get_owner_from_path (tree_view, s_path);
167  if (owner)
168  {
169  active = !gtk_cell_renderer_toggle_get_active (cell); // hasn't changed yet.
170  gncOwnerSetActive (owner, active);
171  }
172 
173  /* Clean up */
174  gtk_tree_path_free (s_path);
175 }
176 
177 
178 /************************************************************/
179 /* sort functions */
180 /************************************************************/
181 
182 static GtkTreeModel *
183 sort_cb_setup_w_iters (GtkTreeModel *f_model,
184  GtkTreeIter *f_iter_a,
185  GtkTreeIter *f_iter_b,
186  GtkTreeIter *iter_a,
187  GtkTreeIter *iter_b,
188  const GncOwner **owner_a,
189  const GncOwner **owner_b)
190 {
191  GtkTreeModel *model;
192 
193  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
194  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
195  iter_a,
196  f_iter_a);
197  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
198  iter_b,
199  f_iter_b);
200  *owner_a = gnc_tree_model_owner_get_owner (GNC_TREE_MODEL_OWNER(model), iter_a);
201  *owner_b = gnc_tree_model_owner_get_owner (GNC_TREE_MODEL_OWNER(model), iter_b);
202  return model;
203 }
204 
205 static void
206 sort_cb_setup (GtkTreeModel *f_model,
207  GtkTreeIter *f_iter_a,
208  GtkTreeIter *f_iter_b,
209  const GncOwner **owner_a,
210  const GncOwner **owner_b)
211 {
212  GtkTreeIter iter_a, iter_b;
213 
214  sort_cb_setup_w_iters (f_model, f_iter_a, f_iter_b,
215  &iter_a, &iter_b, owner_a, owner_b);
216 }
217 
218 static gint
219 sort_by_string (GtkTreeModel *f_model,
220  GtkTreeIter *f_iter1,
221  GtkTreeIter *f_iter2,
222  gpointer user_data)
223 {
224  GtkTreeModel *model;
225  GtkTreeIter iter1, iter2;
226  const GncOwner *owner1, *owner2;
227  gchar *str1, *str2;
228  gint column = GPOINTER_TO_INT(user_data);
229  gint result;
230 
231  model = sort_cb_setup_w_iters(f_model, f_iter1, f_iter2, &iter1, &iter2, &owner1, &owner2);
232 
233  /* Get the strings. */
234  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter1, column, &str1, -1);
235  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter2, column, &str2, -1);
236 
237  result = safe_utf8_collate(str1, str2);
238  g_free(str1);
239  g_free(str2);
240  if (result != 0)
241  return result;
242  return gncOwnerCompare(owner1, owner2);
243 }
244 
245 static gint
246 sort_by_string_natural (GtkTreeModel *f_model,
247  GtkTreeIter *f_iter1,
248  GtkTreeIter *f_iter2,
249  gpointer user_data)
250 {
251  GtkTreeModel *model;
252  GtkTreeIter iter1, iter2;
253  gint column = GPOINTER_TO_INT(user_data);
254  gchar *str1, *str2;
255  const GncOwner *owner1, *owner2;
256  gint result;
257 
258  model = sort_cb_setup_w_iters(f_model, f_iter1, f_iter2, &iter1, &iter2, &owner1, &owner2);
259 
260  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter1, column, &str1, -1);
261  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter2, column, &str2, -1);
262 
263  result = safe_utf8_collate_natural(str1, str2);
264 
265  g_free(str1);
266  g_free(str2);
267 
268  if (result != 0)
269  return result;
270 
271  return gncOwnerCompare(owner1, owner2);
272 }
273 
274 static gint
275 sort_by_boolean (GtkTreeModel *f_model,
276  GtkTreeIter *f_iter1,
277  GtkTreeIter *f_iter2,
278  gpointer user_data)
279 {
280  GtkTreeModel *model;
281  GtkTreeIter iter1, iter2;
282  const GncOwner *owner1, *owner2;
283  gboolean *bool1, *bool2;
284  gint column = GPOINTER_TO_INT(user_data);
285 
286  model = sort_cb_setup_w_iters(f_model, f_iter1, f_iter2, &iter1, &iter2, &owner1, &owner2);
287 
288  /* Get the booleans. */
289  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter1, column, &bool1, -1);
290  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter2, column, &bool2, -1);
291 
292  if (bool1)
293  {
294  if (!bool2)
295  return 1; /* bool1 > bool2 */
296  }
297  else
298  {
299  if (bool2)
300  return -1; /* bool2 > bool1 */
301  }
302  return gncOwnerCompare(owner1, owner2);
303 }
304 
305 static gint
306 sort_by_xxx_value (GtkTreeModel *f_model,
307  GtkTreeIter *f_iter_a,
308  GtkTreeIter *f_iter_b,
309  gpointer user_data)
310 {
311  GncOwner *owner_a, *owner_b;
312  gnc_numeric balance_a, balance_b;
313  gint result;
314 
315  /* Find the owners */
316  sort_cb_setup (f_model, f_iter_a, f_iter_b, (const GncOwner**)&owner_a, (const GncOwner**)&owner_b);
317 
318  balance_a = gnc_ui_owner_get_balance_full(owner_a, NULL, NULL);
319  balance_b = gnc_ui_owner_get_balance_full(owner_b, NULL, NULL);
320 
321  result = gnc_numeric_compare(balance_a, balance_b);
322  if (result != 0)
323  return result;
324  return gncOwnerCompare(owner_a, owner_b);
325 }
326 
327 static gint
328 sort_by_balance_value (GtkTreeModel *f_model,
329  GtkTreeIter *f_iter_a,
330  GtkTreeIter *f_iter_b,
331  gpointer user_data)
332 {
333  return sort_by_xxx_value (f_model, f_iter_a, f_iter_b, user_data);
334 }
335 
336 
337 /************************************************************/
338 /* New View Creation */
339 /************************************************************/
340 
341 /*
342  * Create a new owner tree view for one type of owners.
343  * This view will be based on a model that is common to all views of
344  * the same set of books, but will have its own private filter on that
345  * model.
346  */
347 GtkTreeView *
348 gnc_tree_view_owner_new (GncOwnerType owner_type)
349 {
350  GtkTreeModel *model, *f_model, *s_model;
351  const gchar *sample_type, *sample_currency;
352  const gchar *owner_name = NULL, * owner_id = NULL;
353 
354  ENTER(" ");
355 
356  switch (owner_type)
357  {
358  case GNC_OWNER_NONE :
359  case GNC_OWNER_UNDEFINED :
360  PWARN("missing owner_type");
361  owner_name = _("Name");
362  owner_id = _("ID #");
363  break;
364  case GNC_OWNER_CUSTOMER :
365  owner_name = _("Company Name");
366  owner_id = _("Customer Number");
367  break;
368  case GNC_OWNER_JOB :
369  owner_name = _("Job Name");
370  owner_id = _("Job Number");
371  break;
372  case GNC_OWNER_VENDOR :
373  owner_name = _("Company Name");
374  owner_id = _("Vendor Number");
375  break;
376  case GNC_OWNER_EMPLOYEE :
377  owner_name = _("Employee Name");
378  owner_id = _("Employee Number");
379  break;
380  }
381  /* Create our view */
382  GncTreeViewOwner *view = g_object_new (GNC_TYPE_TREE_VIEW_OWNER,
383  "name", "gnc-id-owner-tree", NULL);
384 
385  /* Create/get a pointer to the existing model for this set of books. */
386  model = gnc_tree_model_owner_new (owner_type);
387 
388  /* Set up the view private filter layer on the common model. */
389  f_model = gtk_tree_model_filter_new (model, NULL);
390  /* A GncTreeModelOwner is based on a GncTreeModel, which is a
391  * GObject that provides a GtkTreeModel interface. */
392  g_object_unref(G_OBJECT(model));
393 
394  /* Set up the view private sort layer on the common model. */
395  s_model = gtk_tree_model_sort_new_with_model(f_model);
396  g_object_unref(G_OBJECT(f_model));
397  gtk_tree_view_set_model (GTK_TREE_VIEW (view), s_model);
398  g_object_unref(G_OBJECT(s_model));
399 
400  /* Set default visibilities */
401  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(view), FALSE);
402 
403  sample_type = gncOwnerTypeToQofIdType (GNC_OWNER_CUSTOMER);
405 
406  view->name_column
407  = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), owner_name, GNC_OWNER_TREE_NAME_COL,
408  NULL, "GnuCash Inc.",
409  GNC_TREE_MODEL_OWNER_COL_NAME,
410  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
411  sort_by_string);
412  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Type"), GNC_OWNER_TREE_TYPE_COL,
413  NULL, sample_type,
414  GNC_TREE_MODEL_OWNER_COL_TYPE,
415  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
416  sort_by_string);
417  view->id_column
418  = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), owner_id, GNC_OWNER_TREE_ID_COL,
419  NULL, "1-123-1234",
420  GNC_TREE_MODEL_OWNER_COL_ID,
421  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
422  sort_by_string_natural);
423  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Currency"), GNC_OWNER_TREE_CURRENCY_COL,
424  NULL, sample_currency,
425  GNC_TREE_MODEL_OWNER_COL_CURRENCY,
426  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
427  sort_by_string);
428  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address Name"), GNC_OWNER_TREE_ADDRESS_NAME_COL,
429  NULL, "GnuCash Inc.",
430  GNC_TREE_MODEL_OWNER_COL_ADDRESS_NAME,
431  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
432  sort_by_string);
433  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address 1"), GNC_OWNER_TREE_ADDRESS_1_COL,
434  NULL, "Free Software Foundation",
435  GNC_TREE_MODEL_OWNER_COL_ADDRESS_1,
436  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
437  sort_by_string);
438  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address 2"), GNC_OWNER_TREE_ADDRESS_2_COL,
439  NULL, "51 Franklin Street, Fifth Floor",
440  GNC_TREE_MODEL_OWNER_COL_ADDRESS_2,
441  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
442  sort_by_string);
443  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address 3"), GNC_OWNER_TREE_ADDRESS_3_COL,
444  NULL, "Boston, MA 02110-1301",
445  GNC_TREE_MODEL_OWNER_COL_ADDRESS_3,
446  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
447  sort_by_string);
448  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address 4"), GNC_OWNER_TREE_ADDRESS_4_COL,
449  NULL, "USA",
450  GNC_TREE_MODEL_OWNER_COL_ADDRESS_4,
451  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
452  sort_by_string);
453  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Phone"), GNC_OWNER_TREE_PHONE_COL,
454  NULL, "+1-617-542-5942",
455  GNC_TREE_MODEL_OWNER_COL_PHONE,
456  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
457  sort_by_string);
458  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Fax"), GNC_OWNER_TREE_FAX_COL,
459  NULL, "+1-617-542-2652",
460  GNC_TREE_MODEL_OWNER_COL_FAX,
461  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
462  sort_by_string);
463  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("E-mail"), GNC_OWNER_TREE_EMAIL_COL,
464  NULL, "gnu@gnu.org",
465  GNC_TREE_MODEL_OWNER_COL_EMAIL,
466  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
467  sort_by_string);
468  gnc_tree_view_add_numeric_column(GNC_TREE_VIEW(view), _("Balance"), GNC_OWNER_TREE_BALANCE_COL,
469  SAMPLE_OWNER_VALUE,
470  GNC_TREE_MODEL_OWNER_COL_BALANCE,
471  GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE,
472  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
473  sort_by_balance_value);
474 
475  view->balance_report_column
476  = gnc_tree_view_add_numeric_column(GNC_TREE_VIEW(view), _("Balance"), GNC_OWNER_TREE_BALANCE_REPORT_COL,
477  SAMPLE_OWNER_VALUE,
478  GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT,
479  GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE,
480  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
481  sort_by_balance_value);
482 
483  view->notes_column
484  = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Notes"), GNC_OWNER_TREE_NOTES_COL, NULL,
485  "Sample owner notes.",
486  GNC_TREE_MODEL_OWNER_COL_NOTES,
487  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
488  sort_by_string);
489  gnc_tree_view_add_toggle_column (GNC_TREE_VIEW(view), _("Active"),
490  C_("Column letter for 'Active'", "A"),
491  GNC_OWNER_TREE_ACTIVE_COL,
492  GNC_TREE_MODEL_OWNER_COL_ACTIVE,
493  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
494  sort_by_boolean,
495  gnc_tree_view_owner_active_toggled);
496 
497  /* Update column titles to use the currency name. */
498  gtvo_update_column_names(view);
499 
500  /* By default only the first column is visible. */
501  gnc_tree_view_configure_columns(GNC_TREE_VIEW(view));
502  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (f_model),
503  gnc_tree_view_owner_filter_helper,
504  view,
505  NULL);
506 
507  /* Default the sorting to owner name */
508  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
509  GNC_TREE_MODEL_OWNER_COL_NAME,
510  GTK_SORT_ASCENDING);
511 
512  gtk_widget_show(GTK_WIDGET(view));
513  LEAVE("%p", view);
514  return GTK_TREE_VIEW(view);
515 }
516 
517 /************************************************************/
518 /* Auxiliary Functions */
519 /************************************************************/
520 
521 #define debug_path(fn, path) { \
522  gchar *path_string = gtk_tree_path_to_string(path); \
523  fn("tree path %s", path_string); \
524  g_free(path_string); \
525  }
526 
527 #if 0 /* Not Used */
528 static GtkTreePath *
529 gnc_tree_view_owner_get_path_from_owner (GncTreeViewOwner *view,
530  GncOwner *owner)
531 {
532  GtkTreeModel *model, *f_model, *s_model;
533  GtkTreePath *path, *f_path, *s_path;
534 
535  ENTER("view %p, owner %p (%s)", view, owner, gncOwnerGetName(owner));
536 
537  if (owner == NULL)
538  {
539  LEAVE("no owner");
540  return NULL;
541  }
542 
543  /* Reach down to the real model and get a path for this owner */
544  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
545  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
546  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
547  path = gnc_tree_model_owner_get_path_from_owner (GNC_TREE_MODEL_OWNER(model), owner);
548  if (path == NULL)
549  {
550  LEAVE("no path");
551  return NULL;
552  }
553 
554  /* convert back to a filtered path */
555  f_path = gtk_tree_model_filter_convert_child_path_to_path (GTK_TREE_MODEL_FILTER (f_model), path);
556  gtk_tree_path_free(path);
557  if (!f_path)
558  {
559  LEAVE("no filter path");
560  return NULL;
561  }
562 
563  /* convert back to a sorted path */
564  s_path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT (s_model), f_path);
565  gtk_tree_path_free(f_path);
566  debug_path(LEAVE, s_path);
567  return s_path;
568 }
569 
570 static gboolean
571 gnc_tree_view_owner_get_iter_from_owner (GncTreeViewOwner *view,
572  GncOwner *owner,
573  GtkTreeIter *s_iter)
574 {
575  GtkTreeModel *model, *f_model, *s_model;
576  GtkTreeIter iter, f_iter;
577 
578  g_return_val_if_fail(GNC_IS_TREE_VIEW_OWNER(view), FALSE);
579  g_return_val_if_fail(owner != NULL, FALSE);
580  g_return_val_if_fail(s_iter != NULL, FALSE);
581 
582  ENTER("view %p, owner %p (%s)", view, owner, gncOwnerGetName(owner));
583 
584  /* Reach down to the real model and get an iter for this owner */
585  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
586  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
587  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
589  GNC_TREE_MODEL_OWNER(model), owner, &iter))
590  {
591  LEAVE("model_get_iter_from_owner failed");
592  return FALSE;
593  }
594 
595  /* convert back to a sort iter */
596  gtk_tree_model_filter_convert_child_iter_to_iter (
597  GTK_TREE_MODEL_FILTER(f_model), &f_iter, &iter);
598  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(s_model),
599  s_iter, &f_iter);
600  LEAVE(" ");
601  return TRUE;
602 }
603 #endif /* Not Used */
604 
605 /************************************************************/
606 /* Owner Tree View Filter Functions */
607 /************************************************************/
608 
609 static gboolean
610 gnc_tree_view_owner_filter_helper (GtkTreeModel *model,
611  GtkTreeIter *iter,
612  gpointer data)
613 {
614  GncOwner *owner;
615  GncTreeViewOwner *view = data;
616 
617  g_return_val_if_fail (GNC_IS_TREE_MODEL_OWNER (model), FALSE);
618  g_return_val_if_fail (iter != NULL, FALSE);
619 
621  GNC_TREE_MODEL_OWNER(model), iter);
622 
623  if (view->filter_fn)
624  return view->filter_fn(owner, view->filter_data);
625  else return TRUE;
626 }
627 
628 /*
629  * Set an GtkTreeModel visible filter on this owner. This filter will be
630  * called for each owner that the tree is about to show, and the
631  * owner will be passed to the callback function.
632  *
633  * Use NULL as func to remove filter.
634  */
635 void
636 gnc_tree_view_owner_set_filter (GncTreeViewOwner *view,
638  gpointer data,
639  GSourceFunc destroy)
640 {
641  ENTER("view %p, filter func %p, data %p, destroy %p",
642  view, func, data, destroy);
643 
644  g_return_if_fail(GNC_IS_TREE_VIEW_OWNER(view));
645 
646  if (view->filter_destroy)
647  {
648  view->filter_destroy(view->filter_data);
649  }
650  view->filter_destroy = destroy;
651  view->filter_data = data;
652  view->filter_fn = func;
653 
655  LEAVE(" ");
656 }
657 
658 /*
659  * Forces the entire owner tree to be re-evaluated for visibility.
660  */
661 void
662 gnc_tree_view_owner_refilter (GncTreeViewOwner *view)
663 {
664  GtkTreeModel *f_model, *s_model;
665 
666  g_return_if_fail(GNC_IS_TREE_VIEW_OWNER(view));
667 
668  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
669  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
670  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model));
671 }
672 
673 /************************************************************/
674 /* Owner Tree View Get/Set Functions */
675 /************************************************************/
676 
677 /*
678  * Retrieve the selected owner from an owner tree view. The
679  * owner tree must be in single selection mode.
680  */
681 GncOwner *
683  GtkTreePath *s_path)
684 {
685  GtkTreeModel *model, *f_model, *s_model;
686  GtkTreePath *path, *f_path;
687  GtkTreeIter iter;
688  GncOwner *owner;
689 
690  ENTER("view %p", view);
691  g_return_val_if_fail (GNC_IS_TREE_VIEW_OWNER (view), NULL);
692  g_return_val_if_fail (s_path != NULL, NULL);
693 
694  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
695  f_path = gtk_tree_model_sort_convert_path_to_child_path (
696  GTK_TREE_MODEL_SORT (s_model), s_path);
697  if (!f_path)
698  {
699  LEAVE("no filter path");
700  return NULL;
701  }
702 
703  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
704  path = gtk_tree_model_filter_convert_path_to_child_path (
705  GTK_TREE_MODEL_FILTER (f_model), f_path);
706  gtk_tree_path_free(f_path);
707  if (!path)
708  {
709  LEAVE("no path");
710  return NULL;
711  }
712 
713  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
714  if (!gtk_tree_model_get_iter (model, &iter, path))
715  {
716  LEAVE("no iter");
717  return NULL;
718  }
719 
720  owner = iter.user_data;
721  gtk_tree_path_free(path);
722  LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner));
723  return owner;
724 }
725 
726 
727 GncOwner *
729  GtkTreeIter *s_iter)
730 {
731  GtkTreeModel *model, *f_model;
732  GtkTreeIter iter, f_iter;
733  GncOwner *owner;
734 
735  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT(s_model), NULL);
736  g_return_val_if_fail (s_iter != NULL, NULL);
737 
738  ENTER("model %p, iter %p", s_model, s_iter);
739 
740  gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT(s_model),
741  &f_iter,
742  s_iter);
743  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
744  gtk_tree_model_filter_convert_iter_to_child_iter (
745  GTK_TREE_MODEL_FILTER(f_model), &iter, &f_iter);
746  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
748  GNC_TREE_MODEL_OWNER(model), &iter);
749  LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner));
750  return owner;
751 }
752 
753 
754 /*
755  * Retrieve the selected owner from an owner tree view. The
756  * owner tree must be in single selection mode.
757  */
758 GncOwner *
760 {
761  GtkTreeSelection *selection;
762  GtkTreeModel *f_model, *s_model;
763  GtkTreeIter iter, f_iter, s_iter;
764  GncOwner *owner;
765  GtkSelectionMode mode;
766 
767  ENTER("view %p", view);
768  g_return_val_if_fail (GNC_IS_TREE_VIEW_OWNER (view), NULL);
769 
770  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
771  mode = gtk_tree_selection_get_mode(selection);
772  if ((mode != GTK_SELECTION_SINGLE) && (mode != GTK_SELECTION_BROWSE))
773  {
774  return NULL;
775  }
776  if (!gtk_tree_selection_get_selected (selection, &s_model, &s_iter))
777  {
778  LEAVE("no owner, get_selected failed");
779  return FALSE;
780  }
781 
782  gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
783  &f_iter, &s_iter);
784 
785  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
786  gtk_tree_model_filter_convert_iter_to_child_iter (
787  GTK_TREE_MODEL_FILTER (f_model), &iter, &f_iter);
788 
789  owner = iter.user_data;
790  LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner));
791  return owner;
792 }
793 
794 /*
795  * Selects a single owner in the owner tree view. The owner
796  * tree must be in single selection mode.
797  */
798 void
800  GncOwner *owner)
801 {
802  GtkTreeModel *model, *f_model, *s_model;
803  GtkTreePath *path, *f_path, *s_path;
804  GtkTreeSelection *selection;
805 
806  ENTER("view %p, owner %p (%s)", view,
807  owner, gncOwnerGetName (owner));
808  g_return_if_fail (GNC_IS_TREE_VIEW_OWNER (view));
809 
810  /* Clear any existing selection. */
811  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
812  gtk_tree_selection_unselect_all (selection);
813 
814  if (owner == NULL)
815  return;
816 
817  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
818  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
819  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
820 
822  GNC_TREE_MODEL_OWNER(model), owner);
823  if (path == NULL)
824  {
825  LEAVE("no path");
826  return;
827  }
828  debug_path(DEBUG, path);
829 
830  f_path = gtk_tree_model_filter_convert_child_path_to_path (
831  GTK_TREE_MODEL_FILTER (f_model), path);
832  gtk_tree_path_free(path);
833  if (f_path == NULL)
834  {
835  LEAVE("no filter path");
836  return;
837  }
838  debug_path(DEBUG, f_path);
839 
840  s_path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT (s_model),
841  f_path);
842  gtk_tree_path_free(f_path);
843  if (s_path == NULL)
844  {
845  LEAVE("no sort path");
846  return;
847  }
848 
849  gtk_tree_selection_select_path (selection, s_path);
850 
851  /* give gtk+ a chance to resize the tree view first by handling pending
852  * configure events */
853  while (gtk_events_pending ())
854  gtk_main_iteration ();
855  gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(view), s_path, NULL, FALSE, 0.0, 0.0);
856  debug_path(LEAVE, s_path);
857  gtk_tree_path_free(s_path);
858 }
859 
860 /* Information re selection process */
861 typedef struct
862 {
863  GList* return_list;
864  GncTreeViewOwner* view;
866 
867 #if 0 /* Not Used */
868 /*
869  * This helper function is called once for each row in the tree view
870  * that is currently selected. Its task is to append the corresponding
871  * owner to the end of a glist.
872  */
873 static void
874 get_selected_owners_helper (GtkTreeModel *s_model,
875  GtkTreePath *s_path,
876  GtkTreeIter *s_iter,
877  gpointer data)
878 {
879  GncTreeViewSelectionInfo *gtvsi = data;
880  GtkTreeModel *f_model;
881  GtkTreeIter iter, f_iter;
882  GncOwner *owner;
883 
884  gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
885  &f_iter, s_iter);
886 
887  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
888  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
889  &iter, &f_iter);
890  owner = iter.user_data;
891 
892  /* Only selected if it passes the filter */
893  if (gtvsi->view->filter_fn == NULL || gtvsi->view->filter_fn(owner, gtvsi->view->filter_data))
894  {
895  gtvsi->return_list = g_list_append(gtvsi->return_list, owner);
896  }
897 }
898 #endif /* Not Used */
899 
900 /************************************************************/
901 /* Owner Tree View Add Column Functions */
902 /************************************************************/
903 
904 static void
905 gtvo_update_column_name (GtkTreeViewColumn *column,
906  const gchar *fmt,
907  const gchar *mnemonic)
908 {
909  gchar *name;
910 
911  g_return_if_fail(column);
912 
913  name = g_strdup_printf(fmt, mnemonic);
914  gtk_tree_view_column_set_title(column, name);
915  g_free(name);
916 }
917 
918 
919 static void
920 gtvo_update_column_names (GncTreeViewOwner *view)
921 {
922  const gchar *mnemonic = gnc_commodity_get_mnemonic(gnc_default_report_currency());
923 
924  gtvo_update_column_name(view->balance_report_column,
925  /* Translators: %s is a currency mnemonic.*/
926  _("Balance (%s)"), mnemonic);
927  gnc_tree_view_set_show_column_menu(GNC_TREE_VIEW(view), FALSE);
928  gnc_tree_view_set_show_column_menu(GNC_TREE_VIEW(view), TRUE);
929 }
930 
931 
932 static void
933 gtvo_currency_changed_cb (void)
934 {
935  const GList *views, *ptr;
936 
937  views = gnc_gobject_tracking_get_list (GNC_TREE_VIEW_OWNER_NAME);
938  for (ptr = views; ptr; ptr = g_list_next(ptr))
939  {
940  gtvo_update_column_names (ptr->data);
941  }
942 }
943 
944 #if 0 /* Not Used */
945 /* This function implements a custom mapping between an owner's KVP
946  * and the cell renderer's 'text' property. */
947 static void
948 owner_cell_kvp_data_func (GtkTreeViewColumn *tree_column,
949  GtkCellRenderer *cell,
950  GtkTreeModel *s_model,
951  GtkTreeIter *s_iter,
952  gpointer key)
953 {
954  GncOwner *owner;
955  GValue v = G_VALUE_INIT;
956 
957  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model));
958  owner = gnc_tree_view_owner_get_owner_from_iter(s_model, s_iter);
959  qof_instance_get_kvp (QOF_INSTANCE (owner), (gchar*)key, &v);
960  if (G_VALUE_HOLDS_STRING)
961  g_object_set (G_OBJECT (cell),
962  "text", g_value_get_string (&v),
963  "xalign", 0.0,
964  NULL);
965 
966 }
967 
968 static void col_edited_helper(GtkCellRendererText *cell, gchar *path_string,
969  gchar *new_text, gpointer _s_model)
970 {
971  GncOwner *owner;
972  GtkTreeModel *s_model;
973  GtkTreeIter s_iter;
974  GncTreeViewOwnerColumnTextEdited col_edited_cb;
975  GtkTreeViewColumn *col;
976 
977  col_edited_cb = g_object_get_data(G_OBJECT(cell),
978  "column_edited_callback");
979  col = GTK_TREE_VIEW_COLUMN(g_object_get_data(G_OBJECT(cell),
980  "column_view"));
981  s_model = GTK_TREE_MODEL(_s_model);
982 
983  if (!gtk_tree_model_get_iter_from_string(s_model, &s_iter, path_string))
984  return;
985 
986  owner = gnc_tree_view_owner_get_owner_from_iter(s_model, &s_iter);
987  col_edited_cb(owner, col, new_text);
988 }
989 
990 static void col_source_helper(GtkTreeViewColumn *col, GtkCellRenderer *cell,
991  GtkTreeModel *s_model, GtkTreeIter *s_iter,
992  gpointer _col_source_cb)
993 {
994  GncOwner *owner;
995  gchar *text;
996  GncTreeViewOwnerColumnSource col_source_cb;
997 
998  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model));
999  col_source_cb = (GncTreeViewOwnerColumnSource) _col_source_cb;
1000  owner = gnc_tree_view_owner_get_owner_from_iter(s_model, s_iter);
1001  text = col_source_cb(owner, col, cell);
1002  g_object_set (G_OBJECT (cell), "text", text, "xalign", 1.0, NULL);
1003  g_free(text);
1004 }
1005 
1010 void
1011 gtvo_setup_column_renderer_edited_cb(GncTreeViewOwner *owner_view,
1012  GtkTreeViewColumn *column,
1013  GtkCellRenderer *renderer,
1014  GncTreeViewOwnerColumnTextEdited col_edited_cb)
1015 {
1016  GtkTreeModel *s_model;
1017 
1018  if (col_edited_cb == NULL)
1019  {
1020  g_object_set(G_OBJECT(renderer), "editable", FALSE, NULL);
1021  g_object_set_data(G_OBJECT(renderer), "column_edited_callback", col_edited_cb);
1022  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(owner_view));
1023  g_signal_handlers_disconnect_by_func(G_OBJECT(renderer), col_edited_cb, s_model);
1024  g_object_set_data(G_OBJECT(renderer), "column_view", column);
1025  }
1026  else
1027  {
1028  g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL);
1029  g_object_set_data(G_OBJECT(renderer), "column_edited_callback",
1030  col_edited_cb);
1031  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(owner_view));
1032  g_signal_connect(G_OBJECT(renderer), "edited",
1033  (GCallback) col_edited_helper, s_model);
1034  g_object_set_data(G_OBJECT(renderer), "column_view", column);
1035  }
1036 }
1037 #endif /* Not Used */
1038 
1039 /* BEGIN FILTER FUNCTIONS */
1040 #define FILTER_TREE_VIEW "types_tree_view"
1041 
1053 gboolean
1055  gpointer user_data)
1056 {
1057  OwnerFilterDialog *fd = user_data;
1058  gnc_numeric total;
1059 
1060  ENTER("owner %p:%s", owner, gncOwnerGetName(owner));
1061 
1062  if (!fd->show_inactive && !gncOwnerGetActive (owner))
1063  {
1064  LEAVE(" hide: inactive");
1065  return FALSE;
1066  }
1067 
1068  if (!fd->show_zero_total)
1069  {
1070  total = gncOwnerGetBalanceInCurrency (owner, NULL);
1071  if (gnc_numeric_zero_p(total))
1072  {
1073  LEAVE(" hide: zero balance");
1074  return FALSE;
1075  }
1076  }
1077 
1078  return TRUE;
1079 }
1080 
1087 void
1088 gppot_filter_show_inactive_toggled_cb (GtkToggleButton *button,
1089  OwnerFilterDialog *fd)
1090 {
1091  g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button));
1092 
1093  ENTER("button %p", button);
1094  fd->show_inactive = !gtk_toggle_button_get_active(button);
1095  gnc_tree_view_owner_refilter(fd->tree_view);
1096  LEAVE("show_inactive %d", fd->show_inactive);
1097 }
1098 
1105 void
1106 gppot_filter_show_zero_toggled_cb (GtkToggleButton *button,
1107  OwnerFilterDialog *fd)
1108 {
1109  g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button));
1110 
1111  ENTER("button %p", button);
1112  fd->show_zero_total = gtk_toggle_button_get_active(button);
1113  gnc_tree_view_owner_refilter(fd->tree_view);
1114  LEAVE("show_zero %d", fd->show_zero_total);
1115 }
1116 
1126 void
1127 gppot_filter_response_cb (GtkWidget *dialog,
1128  gint response,
1129  OwnerFilterDialog *fd)
1130 {
1131  gpointer gptemp;
1132 
1133  g_return_if_fail(GTK_IS_DIALOG(dialog));
1134 
1135  ENTER("dialog %p, response %d", dialog, response);
1136 
1137  if (response != GTK_RESPONSE_OK)
1138  {
1139  fd->show_inactive = fd->original_show_inactive;
1140  fd->show_zero_total = fd->original_show_zero_total;
1141  gnc_tree_view_owner_refilter(fd->tree_view);
1142  }
1143 
1144  /* Clean up and delete dialog */
1145  gptemp = (gpointer)fd->dialog;
1146  g_atomic_pointer_compare_and_exchange(&gptemp,
1147  (gpointer)dialog, NULL);
1148  fd->dialog = gptemp;
1149  gtk_widget_destroy(dialog);
1150  LEAVE("");
1151 }
1152 
1153 void
1154 owner_filter_dialog_create(OwnerFilterDialog *fd, GncPluginPage *page)
1155 {
1156  GtkWidget *dialog, *button;
1157  GtkBuilder *builder;
1158  gchar *title;
1159 
1160  ENTER("(fd %p, page %p)", fd, page);
1161 
1162  if (fd->dialog)
1163  {
1164  gtk_window_present(GTK_WINDOW(fd->dialog));
1165  LEAVE("existing dialog");
1166  return;
1167  }
1168 
1169  /* Create the dialog */
1170  builder = gtk_builder_new();
1171  gnc_builder_add_from_file (builder, "gnc-tree-view-owner.glade", "filter_by_dialog");
1172  dialog = GTK_WIDGET(gtk_builder_get_object (builder, "filter_by_dialog"));
1173  fd->dialog = dialog;
1174  gtk_window_set_transient_for(GTK_WINDOW(dialog),
1175  GTK_WINDOW(GNC_PLUGIN_PAGE(page)->window));
1176  /* Translators: The %s is the name of the plugin page */
1177  title = g_strdup_printf(_("Filter %s by…"),
1178  gnc_plugin_page_get_page_name(GNC_PLUGIN_PAGE(page)));
1179  gtk_window_set_title(GTK_WINDOW(dialog), title);
1180  g_free(title);
1181 
1182  /* Remember current state */
1183  fd->original_show_inactive = fd->show_inactive;
1184  fd->original_show_zero_total = fd->show_zero_total;
1185 
1186  /* Update the dialog widgets for the current state */
1187  button = GTK_WIDGET(gtk_builder_get_object (builder, "show_inactive"));
1188  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
1189  !fd->show_inactive);
1190  button = GTK_WIDGET(gtk_builder_get_object (builder, "show_zero"));
1191  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
1192  fd->show_zero_total);
1193 
1194  /* Wire up the rest of the callbacks */
1195  gtk_builder_connect_signals (builder, fd);
1196  g_object_unref(G_OBJECT(builder));
1197 
1198  /* Show it */
1199  gtk_widget_show_all (dialog);
1200  LEAVE(" ");
1201 }
1202 
1203 #define OWNER_SELECTED_LABEL "SelectedOwner"
1204 #define SHOW_INACTIVE_LABEL "ShowInactive"
1205 #define SHOW_ZERO_LABEL "ShowZeroTotal"
1206 
1207 typedef struct foo
1208 {
1209  GKeyFile *key_file;
1210  const gchar *group_name;
1211 } bar_t;
1212 
1223 static void
1224 tree_save_selected_row (GncTreeViewOwner *view,
1225  gpointer user_data)
1226 {
1227  GncOwner *owner;
1228  bar_t *bar = user_data;
1229  const gchar *owner_name;
1230 
1232  if (owner == NULL)
1233  return;
1234 
1235  owner_name = gncOwnerGetName (owner);
1236  if (owner_name == NULL)
1237  return;
1238 
1239  g_key_file_set_string(bar->key_file, bar->group_name, OWNER_SELECTED_LABEL,
1240  owner_name);
1241 }
1242 
1243 void
1244 gnc_tree_view_owner_save(GncTreeViewOwner *view,
1245  OwnerFilterDialog *fd,
1246  GKeyFile *key_file, const gchar *group_name)
1247 {
1248  bar_t bar;
1249 
1250  g_return_if_fail (key_file != NULL);
1251  g_return_if_fail (group_name != NULL);
1252 
1253  ENTER("view %p, key_file %p, group_name %s", view, key_file,
1254  group_name);
1255 
1256  g_key_file_set_boolean(key_file, group_name, SHOW_INACTIVE_LABEL,
1257  fd->show_inactive);
1258  g_key_file_set_boolean(key_file, group_name, SHOW_ZERO_LABEL,
1259  fd->show_zero_total);
1260 
1261  bar.key_file = key_file;
1262  bar.group_name = group_name;
1263  tree_save_selected_row(view, &bar);
1264  LEAVE(" ");
1265 
1266 }
1267 
1275 static void
1276 tree_restore_selected_row (GncTreeViewOwner *view,
1277  GncOwnerType owner_type,
1278  const gchar *owner_guid_str)
1279 {
1280  GncOwner *owner = gncOwnerNew();
1281  QofBook *book;
1282  GncGUID owner_guid;
1283 
1284  book = qof_session_get_book (gnc_get_current_session());
1285  if (string_to_guid (owner_guid_str, &owner_guid))
1286  if (gncOwnerGetOwnerFromTypeGuid (book, owner, gncOwnerTypeToQofIdType(owner_type), &owner_guid))
1288 }
1289 
1290 void
1291 gnc_tree_view_owner_restore(GncTreeViewOwner *view,
1292  OwnerFilterDialog *fd,
1293  GKeyFile *key_file, const gchar *group_name,
1294  GncOwnerType owner_type)
1295 {
1296  GError *error = NULL;
1297  gchar *value;
1298  gboolean show;
1299 
1300  /* Filter information. Ignore missing keys. */
1301  show = g_key_file_get_boolean(key_file, group_name, SHOW_INACTIVE_LABEL, &error);
1302  if (error)
1303  {
1304  g_warning("error reading group %s key %s: %s",
1305  group_name, SHOW_INACTIVE_LABEL, error->message);
1306  g_error_free(error);
1307  error = NULL;
1308  show = TRUE;
1309  }
1310  fd->show_inactive = show;
1311 
1312  show = g_key_file_get_boolean(key_file, group_name, SHOW_ZERO_LABEL, &error);
1313  if (error)
1314  {
1315  g_warning("error reading group %s key %s: %s",
1316  group_name, SHOW_ZERO_LABEL, error->message);
1317  g_error_free(error);
1318  error = NULL;
1319  show = TRUE;
1320  }
1321  fd->show_zero_total = show;
1322 
1323  /* Selected owner (if any) */
1324  value = g_key_file_get_string(key_file, group_name, OWNER_SELECTED_LABEL, NULL);
1325  if (value)
1326  {
1327  tree_restore_selected_row(view, owner_type, value);
1328  g_free(value);
1329  }
1330 
1331  /* Update tree view for any changes */
1333 }
1334 
1335 #if 0 /* Not Used */
1336 static void
1337 gtvo_set_column_editor(GncTreeViewOwner *view,
1338  GtkTreeViewColumn *column,
1339  GncTreeViewOwnerColumnTextEdited edited_cb)
1340 {
1341  GList *renderers_orig, *renderers;
1342  GtkCellRenderer *renderer;
1343 
1344  // look for the first text-renderer; on the 0th column of the owner tree,
1345  // there are two renderers: pixbuf and text. So find the text one.
1346  for (renderers_orig = renderers = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1347  renderers && !GTK_IS_CELL_RENDERER_TEXT(renderers->data);
1348  renderers = renderers->next);
1349  renderer = GTK_CELL_RENDERER(renderers->data);
1350  g_list_free(renderers_orig);
1351  g_return_if_fail(renderer != NULL);
1352  gtvo_setup_column_renderer_edited_cb(GNC_TREE_VIEW_OWNER(view), column, renderer, edited_cb);
1353 }
1354 #endif /* Not Used */
void gnc_tree_view_owner_set_selected_owner(GncTreeViewOwner *view, GncOwner *owner)
This function selects an owner in the owner tree view.
GtkTreeView * gnc_tree_view_owner_new(GncOwnerType owner_type)
Create a new owner tree view for one type of owners.
Business Interface: Object OWNERs.
The instance data structure for a content plugin.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
void gnc_tree_view_owner_set_filter(GncTreeViewOwner *view, gnc_tree_view_owner_filter_func func, gpointer data, GSourceFunc destroy)
This function attaches a filter function to the given owner tree.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
void gnc_tree_view_owner_refilter(GncTreeViewOwner *view)
This function forces the owner tree filter to be evaluated.
GtkTreeView implementation for gnucash owner tree.
GtkTreeModel implementation for gnucash owner tree.
int safe_utf8_collate(const char *da, const char *db)
Collate two UTF-8 strings.
common utilities for manipulating a GtkTreeView within gnucash
GncOwner * gnc_tree_view_owner_get_owner_from_iter(GtkTreeModel *s_model, GtkTreeIter *s_iter)
This function returns the owner associated with the specified iter.
gboolean(* gnc_tree_view_owner_filter_func)(GncOwner *owner, gpointer data)
This is the description of a filter function used by the owner tree.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
const gchar * gnc_plugin_page_get_page_name(GncPluginPage *page)
Retrieve the name of this page.
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...
void gppot_filter_response_cb(GtkWidget *dialog, gint response, OwnerFilterDialog *fd)
The Filter dialog was closed.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
void gnc_tree_view_set_show_column_menu(GncTreeView *view, gboolean visible)
This function is called to set the "show-column-menu" property on this view.
gint gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Returns 1 if a>b, -1 if b>a, 0 if a == b.
GtkTreeViewColumn * gnc_tree_view_add_numeric_column(GncTreeView *view, const gchar *column_title, const gchar *pref_name, const gchar *sizing_text, gint model_data_column, gint model_color_column, gint model_visibility_column, GtkTreeIterCompareFunc column_sort_fn)
This function adds a new numeric column to a GncTreeView base view.
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
gnc_commodity * gnc_default_report_currency(void)
Return the default currency for use in reports, as set by the user.
void qof_instance_get_kvp(QofInstance *, GValue *value, unsigned count,...)
Retrieves the contents of a KVP slot into a provided GValue.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
GtkTreeViewColumn * gnc_tree_view_add_toggle_column(GncTreeView *view, const gchar *column_title, const gchar *column_short_title, const gchar *pref_name, gint model_data_column, gint model_visibility_column, GtkTreeIterCompareFunc column_sort_fn, renderer_toggled toggle_edited_cb)
This function adds a new toggle column to a GncTreeView base view.
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
Definition: qofsession.cpp:574
GtkTreeModel * gnc_tree_model_owner_new(GncOwnerType owner_type)
Create a new GtkTreeModel for manipulating gnucash owners.
Gobject helper routines.
int safe_utf8_collate_natural(const char *da, const char *db)
Collate two UTF-8 strings naturally.
gnc_numeric gncOwnerGetBalanceInCurrency(const GncOwner *owner, const gnc_commodity *report_currency)
Given an owner, extract the open balance from the owner and then convert it to the desired currency...
Definition: gncOwner.c:1478
void gnc_tree_view_configure_columns(GncTreeView *view)
Make all the correct columns visible, respecting their default visibility setting, their "always" visibility setting, and the last saved state if available.
General utilities for dealing with accounting periods.
int gncOwnerCompare(const GncOwner *a, const GncOwner *b)
Sort on name.
Definition: gncOwner.c:590
void gppot_filter_show_inactive_toggled_cb(GtkToggleButton *button, OwnerFilterDialog *fd)
The "only show active" button in the Filter dialog changed state.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
QofIdTypeConst gncOwnerTypeToQofIdType(GncOwnerType t)
Returns the QofIdType of the given GncOwnerType, or NULL if no suitable one exists.
Definition: gncOwner.c:235
GtkTreePath * gnc_tree_model_owner_get_path_from_owner(GncTreeModelOwner *model, GncOwner *owner)
Convert a model/owner pair into a gtk_tree_model_path.
GncOwner * gnc_tree_model_owner_get_owner(GncTreeModelOwner *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash owner.
All type declarations for the whole Gnucash engine.
GLib helper routines.
QofBook reference.
Definition: qofbook-p.hpp:46
GtkTreeViewColumn * gnc_tree_view_add_text_column(GncTreeView *view, const gchar *column_title, const gchar *pref_name, const gchar *icon_name, const gchar *sizing_text, gint model_data_column, gint model_visibility_column, GtkTreeIterCompareFunc column_sort_fn)
This function adds a new text column to a GncTreeView base view.
gboolean gnc_tree_model_owner_get_iter_from_owner(GncTreeModelOwner *model, GncOwner *owner, GtkTreeIter *iter)
Convert a model/owner pair into a gtk_tree_model_iter.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
void gppot_filter_show_zero_toggled_cb(GtkToggleButton *button, OwnerFilterDialog *fd)
The "show zero totals" button in the Filter dialog changed state.
GncOwner * gnc_tree_view_owner_get_selected_owner(GncTreeViewOwner *view)
This function returns the owner associated with the selected item in the owner tree view...
GncOwner * gnc_tree_view_owner_get_owner_from_path(GncTreeViewOwner *view, GtkTreePath *s_path)
This function returns the owner associated with the specified path.
gboolean gnc_plugin_page_owner_tree_filter_owners(GncOwner *owner, gpointer user_data)
This function tells the owner tree view whether or not to filter out a particular owner...
The type used to store guids in C.
Definition: guid.h:75
GncOwner * gncOwnerNew(void)
These two functions are mainly for the convenience of scheme code.
Definition: gncOwner.c:57
Commodity handling public routines.