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_boolean (GtkTreeModel *f_model,
247  GtkTreeIter *f_iter1,
248  GtkTreeIter *f_iter2,
249  gpointer user_data)
250 {
251  GtkTreeModel *model;
252  GtkTreeIter iter1, iter2;
253  const GncOwner *owner1, *owner2;
254  gboolean *bool1, *bool2;
255  gint column = GPOINTER_TO_INT(user_data);
256 
257  model = sort_cb_setup_w_iters(f_model, f_iter1, f_iter2, &iter1, &iter2, &owner1, &owner2);
258 
259  /* Get the booleans. */
260  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter1, column, &bool1, -1);
261  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter2, column, &bool2, -1);
262 
263  if (bool1)
264  {
265  if (!bool2)
266  return 1; /* bool1 > bool2 */
267  }
268  else
269  {
270  if (bool2)
271  return -1; /* bool2 > bool1 */
272  }
273  return gncOwnerCompare(owner1, owner2);
274 }
275 
276 static gint
277 sort_by_xxx_value (GtkTreeModel *f_model,
278  GtkTreeIter *f_iter_a,
279  GtkTreeIter *f_iter_b,
280  gpointer user_data)
281 {
282  GncOwner *owner_a, *owner_b;
283  gnc_numeric balance_a, balance_b;
284  gint result;
285 
286  /* Find the owners */
287  sort_cb_setup (f_model, f_iter_a, f_iter_b, (const GncOwner**)&owner_a, (const GncOwner**)&owner_b);
288 
289  balance_a = gnc_ui_owner_get_balance_full(owner_a, NULL, NULL);
290  balance_b = gnc_ui_owner_get_balance_full(owner_b, NULL, NULL);
291 
292  result = gnc_numeric_compare(balance_a, balance_b);
293  if (result != 0)
294  return result;
295  return gncOwnerCompare(owner_a, owner_b);
296 }
297 
298 static gint
299 sort_by_balance_value (GtkTreeModel *f_model,
300  GtkTreeIter *f_iter_a,
301  GtkTreeIter *f_iter_b,
302  gpointer user_data)
303 {
304  return sort_by_xxx_value (f_model, f_iter_a, f_iter_b, user_data);
305 }
306 
307 
308 /************************************************************/
309 /* New View Creation */
310 /************************************************************/
311 
312 /*
313  * Create a new owner tree view for one type of owners.
314  * This view will be based on a model that is common to all views of
315  * the same set of books, but will have its own private filter on that
316  * model.
317  */
318 GtkTreeView *
319 gnc_tree_view_owner_new (GncOwnerType owner_type)
320 {
321  GtkTreeModel *model, *f_model, *s_model;
322  const gchar *sample_type, *sample_currency;
323  const gchar *owner_name = NULL, * owner_id = NULL;
324 
325  ENTER(" ");
326 
327  switch (owner_type)
328  {
329  case GNC_OWNER_NONE :
330  case GNC_OWNER_UNDEFINED :
331  PWARN("missing owner_type");
332  owner_name = _("Name");
333  owner_id = _("ID #");
334  break;
335  case GNC_OWNER_CUSTOMER :
336  owner_name = _("Company Name");
337  owner_id = _("Customer Number");
338  break;
339  case GNC_OWNER_JOB :
340  owner_name = _("Job Name");
341  owner_id = _("Job Number");
342  break;
343  case GNC_OWNER_VENDOR :
344  owner_name = _("Company Name");
345  owner_id = _("Vendor Number");
346  break;
347  case GNC_OWNER_EMPLOYEE :
348  owner_name = _("Employee Name");
349  owner_id = _("Employee Number");
350  break;
351  }
352  /* Create our view */
353  GncTreeViewOwner *view = g_object_new (GNC_TYPE_TREE_VIEW_OWNER,
354  "name", "gnc-id-owner-tree", NULL);
355 
356  /* Create/get a pointer to the existing model for this set of books. */
357  model = gnc_tree_model_owner_new (owner_type);
358 
359  /* Set up the view private filter layer on the common model. */
360  f_model = gtk_tree_model_filter_new (model, NULL);
361  /* A GncTreeModelOwner is based on a GncTreeModel, which is a
362  * GObject that provides a GtkTreeModel interface. */
363  g_object_unref(G_OBJECT(model));
364 
365  /* Set up the view private sort layer on the common model. */
366  s_model = gtk_tree_model_sort_new_with_model(f_model);
367  g_object_unref(G_OBJECT(f_model));
368  gtk_tree_view_set_model (GTK_TREE_VIEW (view), s_model);
369  g_object_unref(G_OBJECT(s_model));
370 
371  /* Set default visibilities */
372  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(view), FALSE);
373 
374  sample_type = gncOwnerTypeToQofIdType (GNC_OWNER_CUSTOMER);
376 
377  view->name_column
378  = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), owner_name, GNC_OWNER_TREE_NAME_COL,
379  NULL, "GnuCash Inc.",
380  GNC_TREE_MODEL_OWNER_COL_NAME,
381  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
382  sort_by_string);
383  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Type"), GNC_OWNER_TREE_TYPE_COL,
384  NULL, sample_type,
385  GNC_TREE_MODEL_OWNER_COL_TYPE,
386  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
387  sort_by_string);
388  view->id_column
389  = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), owner_id, GNC_OWNER_TREE_ID_COL,
390  NULL, "1-123-1234",
391  GNC_TREE_MODEL_OWNER_COL_ID,
392  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
393  sort_by_string);
394  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Currency"), GNC_OWNER_TREE_CURRENCY_COL,
395  NULL, sample_currency,
396  GNC_TREE_MODEL_OWNER_COL_CURRENCY,
397  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
398  sort_by_string);
399  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address Name"), GNC_OWNER_TREE_ADDRESS_NAME_COL,
400  NULL, "GnuCash Inc.",
401  GNC_TREE_MODEL_OWNER_COL_ADDRESS_NAME,
402  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
403  sort_by_string);
404  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address 1"), GNC_OWNER_TREE_ADDRESS_1_COL,
405  NULL, "Free Software Foundation",
406  GNC_TREE_MODEL_OWNER_COL_ADDRESS_1,
407  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
408  sort_by_string);
409  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address 2"), GNC_OWNER_TREE_ADDRESS_2_COL,
410  NULL, "51 Franklin Street, Fifth Floor",
411  GNC_TREE_MODEL_OWNER_COL_ADDRESS_2,
412  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
413  sort_by_string);
414  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address 3"), GNC_OWNER_TREE_ADDRESS_3_COL,
415  NULL, "Boston, MA 02110-1301",
416  GNC_TREE_MODEL_OWNER_COL_ADDRESS_3,
417  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
418  sort_by_string);
419  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Address 4"), GNC_OWNER_TREE_ADDRESS_4_COL,
420  NULL, "USA",
421  GNC_TREE_MODEL_OWNER_COL_ADDRESS_4,
422  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
423  sort_by_string);
424  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Phone"), GNC_OWNER_TREE_PHONE_COL,
425  NULL, "+1-617-542-5942",
426  GNC_TREE_MODEL_OWNER_COL_PHONE,
427  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
428  sort_by_string);
429  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Fax"), GNC_OWNER_TREE_FAX_COL,
430  NULL, "+1-617-542-2652",
431  GNC_TREE_MODEL_OWNER_COL_FAX,
432  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
433  sort_by_string);
434  gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("E-mail"), GNC_OWNER_TREE_EMAIL_COL,
435  NULL, "gnu@gnu.org",
436  GNC_TREE_MODEL_OWNER_COL_EMAIL,
437  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
438  sort_by_string);
439  gnc_tree_view_add_numeric_column(GNC_TREE_VIEW(view), _("Balance"), GNC_OWNER_TREE_BALANCE_COL,
440  SAMPLE_OWNER_VALUE,
441  GNC_TREE_MODEL_OWNER_COL_BALANCE,
442  GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE,
443  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
444  sort_by_balance_value);
445 
446  view->balance_report_column
447  = gnc_tree_view_add_numeric_column(GNC_TREE_VIEW(view), _("Balance"), GNC_OWNER_TREE_BALANCE_REPORT_COL,
448  SAMPLE_OWNER_VALUE,
449  GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT,
450  GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE,
451  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
452  sort_by_balance_value);
453 
454  view->notes_column
455  = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), _("Notes"), GNC_OWNER_TREE_NOTES_COL, NULL,
456  "Sample owner notes.",
457  GNC_TREE_MODEL_OWNER_COL_NOTES,
458  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
459  sort_by_string);
460  gnc_tree_view_add_toggle_column (GNC_TREE_VIEW(view), _("Active"),
461  C_("Column letter for 'Active'", "A"),
462  GNC_OWNER_TREE_ACTIVE_COL,
463  GNC_TREE_MODEL_OWNER_COL_ACTIVE,
464  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
465  sort_by_boolean,
466  gnc_tree_view_owner_active_toggled);
467 
468  /* Update column titles to use the currency name. */
469  gtvo_update_column_names(view);
470 
471  /* By default only the first column is visible. */
472  gnc_tree_view_configure_columns(GNC_TREE_VIEW(view));
473  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (f_model),
474  gnc_tree_view_owner_filter_helper,
475  view,
476  NULL);
477 
478  /* Default the sorting to owner name */
479  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
480  GNC_TREE_MODEL_OWNER_COL_NAME,
481  GTK_SORT_ASCENDING);
482 
483  gtk_widget_show(GTK_WIDGET(view));
484  LEAVE("%p", view);
485  return GTK_TREE_VIEW(view);
486 }
487 
488 /************************************************************/
489 /* Auxiliary Functions */
490 /************************************************************/
491 
492 #define debug_path(fn, path) { \
493  gchar *path_string = gtk_tree_path_to_string(path); \
494  fn("tree path %s", path_string); \
495  g_free(path_string); \
496  }
497 
498 #if 0 /* Not Used */
499 static GtkTreePath *
500 gnc_tree_view_owner_get_path_from_owner (GncTreeViewOwner *view,
501  GncOwner *owner)
502 {
503  GtkTreeModel *model, *f_model, *s_model;
504  GtkTreePath *path, *f_path, *s_path;
505 
506  ENTER("view %p, owner %p (%s)", view, owner, gncOwnerGetName(owner));
507 
508  if (owner == NULL)
509  {
510  LEAVE("no owner");
511  return NULL;
512  }
513 
514  /* Reach down to the real model and get a path for this owner */
515  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
516  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
517  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
518  path = gnc_tree_model_owner_get_path_from_owner (GNC_TREE_MODEL_OWNER(model), owner);
519  if (path == NULL)
520  {
521  LEAVE("no path");
522  return NULL;
523  }
524 
525  /* convert back to a filtered path */
526  f_path = gtk_tree_model_filter_convert_child_path_to_path (GTK_TREE_MODEL_FILTER (f_model), path);
527  gtk_tree_path_free(path);
528  if (!f_path)
529  {
530  LEAVE("no filter path");
531  return NULL;
532  }
533 
534  /* convert back to a sorted path */
535  s_path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT (s_model), f_path);
536  gtk_tree_path_free(f_path);
537  debug_path(LEAVE, s_path);
538  return s_path;
539 }
540 
541 static gboolean
542 gnc_tree_view_owner_get_iter_from_owner (GncTreeViewOwner *view,
543  GncOwner *owner,
544  GtkTreeIter *s_iter)
545 {
546  GtkTreeModel *model, *f_model, *s_model;
547  GtkTreeIter iter, f_iter;
548 
549  g_return_val_if_fail(GNC_IS_TREE_VIEW_OWNER(view), FALSE);
550  g_return_val_if_fail(owner != NULL, FALSE);
551  g_return_val_if_fail(s_iter != NULL, FALSE);
552 
553  ENTER("view %p, owner %p (%s)", view, owner, gncOwnerGetName(owner));
554 
555  /* Reach down to the real model and get an iter for this owner */
556  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
557  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
558  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
560  GNC_TREE_MODEL_OWNER(model), owner, &iter))
561  {
562  LEAVE("model_get_iter_from_owner failed");
563  return FALSE;
564  }
565 
566  /* convert back to a sort iter */
567  gtk_tree_model_filter_convert_child_iter_to_iter (
568  GTK_TREE_MODEL_FILTER(f_model), &f_iter, &iter);
569  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(s_model),
570  s_iter, &f_iter);
571  LEAVE(" ");
572  return TRUE;
573 }
574 #endif /* Not Used */
575 
576 /************************************************************/
577 /* Owner Tree View Filter Functions */
578 /************************************************************/
579 
580 static gboolean
581 gnc_tree_view_owner_filter_helper (GtkTreeModel *model,
582  GtkTreeIter *iter,
583  gpointer data)
584 {
585  GncOwner *owner;
586  GncTreeViewOwner *view = data;
587 
588  g_return_val_if_fail (GNC_IS_TREE_MODEL_OWNER (model), FALSE);
589  g_return_val_if_fail (iter != NULL, FALSE);
590 
592  GNC_TREE_MODEL_OWNER(model), iter);
593 
594  if (view->filter_fn)
595  return view->filter_fn(owner, view->filter_data);
596  else return TRUE;
597 }
598 
599 /*
600  * Set an GtkTreeModel visible filter on this owner. This filter will be
601  * called for each owner that the tree is about to show, and the
602  * owner will be passed to the callback function.
603  *
604  * Use NULL as func to remove filter.
605  */
606 void
607 gnc_tree_view_owner_set_filter (GncTreeViewOwner *view,
609  gpointer data,
610  GSourceFunc destroy)
611 {
612  ENTER("view %p, filter func %p, data %p, destroy %p",
613  view, func, data, destroy);
614 
615  g_return_if_fail(GNC_IS_TREE_VIEW_OWNER(view));
616 
617  if (view->filter_destroy)
618  {
619  view->filter_destroy(view->filter_data);
620  }
621  view->filter_destroy = destroy;
622  view->filter_data = data;
623  view->filter_fn = func;
624 
626  LEAVE(" ");
627 }
628 
629 /*
630  * Forces the entire owner tree to be re-evaluated for visibility.
631  */
632 void
633 gnc_tree_view_owner_refilter (GncTreeViewOwner *view)
634 {
635  GtkTreeModel *f_model, *s_model;
636 
637  g_return_if_fail(GNC_IS_TREE_VIEW_OWNER(view));
638 
639  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
640  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
641  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model));
642 }
643 
644 /************************************************************/
645 /* Owner Tree View Get/Set Functions */
646 /************************************************************/
647 
648 /*
649  * Retrieve the selected owner from an owner tree view. The
650  * owner tree must be in single selection mode.
651  */
652 GncOwner *
654  GtkTreePath *s_path)
655 {
656  GtkTreeModel *model, *f_model, *s_model;
657  GtkTreePath *path, *f_path;
658  GtkTreeIter iter;
659  GncOwner *owner;
660 
661  ENTER("view %p", view);
662  g_return_val_if_fail (GNC_IS_TREE_VIEW_OWNER (view), NULL);
663  g_return_val_if_fail (s_path != NULL, NULL);
664 
665  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
666  f_path = gtk_tree_model_sort_convert_path_to_child_path (
667  GTK_TREE_MODEL_SORT (s_model), s_path);
668  if (!f_path)
669  {
670  LEAVE("no filter path");
671  return NULL;
672  }
673 
674  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
675  path = gtk_tree_model_filter_convert_path_to_child_path (
676  GTK_TREE_MODEL_FILTER (f_model), f_path);
677  gtk_tree_path_free(f_path);
678  if (!path)
679  {
680  LEAVE("no path");
681  return NULL;
682  }
683 
684  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
685  if (!gtk_tree_model_get_iter (model, &iter, path))
686  {
687  LEAVE("no iter");
688  return NULL;
689  }
690 
691  owner = iter.user_data;
692  gtk_tree_path_free(path);
693  LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner));
694  return owner;
695 }
696 
697 
698 GncOwner *
700  GtkTreeIter *s_iter)
701 {
702  GtkTreeModel *model, *f_model;
703  GtkTreeIter iter, f_iter;
704  GncOwner *owner;
705 
706  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT(s_model), NULL);
707  g_return_val_if_fail (s_iter != NULL, NULL);
708 
709  ENTER("model %p, iter %p", s_model, s_iter);
710 
711  gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT(s_model),
712  &f_iter,
713  s_iter);
714  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
715  gtk_tree_model_filter_convert_iter_to_child_iter (
716  GTK_TREE_MODEL_FILTER(f_model), &iter, &f_iter);
717  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
719  GNC_TREE_MODEL_OWNER(model), &iter);
720  LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner));
721  return owner;
722 }
723 
724 
725 /*
726  * Retrieve the selected owner from an owner tree view. The
727  * owner tree must be in single selection mode.
728  */
729 GncOwner *
731 {
732  GtkTreeSelection *selection;
733  GtkTreeModel *f_model, *s_model;
734  GtkTreeIter iter, f_iter, s_iter;
735  GncOwner *owner;
736  GtkSelectionMode mode;
737 
738  ENTER("view %p", view);
739  g_return_val_if_fail (GNC_IS_TREE_VIEW_OWNER (view), NULL);
740 
741  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
742  mode = gtk_tree_selection_get_mode(selection);
743  if ((mode != GTK_SELECTION_SINGLE) && (mode != GTK_SELECTION_BROWSE))
744  {
745  return NULL;
746  }
747  if (!gtk_tree_selection_get_selected (selection, &s_model, &s_iter))
748  {
749  LEAVE("no owner, get_selected failed");
750  return FALSE;
751  }
752 
753  gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
754  &f_iter, &s_iter);
755 
756  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
757  gtk_tree_model_filter_convert_iter_to_child_iter (
758  GTK_TREE_MODEL_FILTER (f_model), &iter, &f_iter);
759 
760  owner = iter.user_data;
761  LEAVE("owner %p (%s)", owner, gncOwnerGetName (owner));
762  return owner;
763 }
764 
765 /*
766  * Selects a single owner in the owner tree view. The owner
767  * tree must be in single selection mode.
768  */
769 void
771  GncOwner *owner)
772 {
773  GtkTreeModel *model, *f_model, *s_model;
774  GtkTreePath *path, *f_path, *s_path;
775  GtkTreeSelection *selection;
776 
777  ENTER("view %p, owner %p (%s)", view,
778  owner, gncOwnerGetName (owner));
779  g_return_if_fail (GNC_IS_TREE_VIEW_OWNER (view));
780 
781  /* Clear any existing selection. */
782  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
783  gtk_tree_selection_unselect_all (selection);
784 
785  if (owner == NULL)
786  return;
787 
788  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
789  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
790  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
791 
793  GNC_TREE_MODEL_OWNER(model), owner);
794  if (path == NULL)
795  {
796  LEAVE("no path");
797  return;
798  }
799  debug_path(DEBUG, path);
800 
801  f_path = gtk_tree_model_filter_convert_child_path_to_path (
802  GTK_TREE_MODEL_FILTER (f_model), path);
803  gtk_tree_path_free(path);
804  if (f_path == NULL)
805  {
806  LEAVE("no filter path");
807  return;
808  }
809  debug_path(DEBUG, f_path);
810 
811  s_path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT (s_model),
812  f_path);
813  gtk_tree_path_free(f_path);
814  if (s_path == NULL)
815  {
816  LEAVE("no sort path");
817  return;
818  }
819 
820  gtk_tree_selection_select_path (selection, s_path);
821 
822  /* give gtk+ a chance to resize the tree view first by handling pending
823  * configure events */
824  while (gtk_events_pending ())
825  gtk_main_iteration ();
826  gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(view), s_path, NULL, FALSE, 0.0, 0.0);
827  debug_path(LEAVE, s_path);
828  gtk_tree_path_free(s_path);
829 }
830 
831 /* Information re selection process */
832 typedef struct
833 {
834  GList* return_list;
835  GncTreeViewOwner* view;
837 
838 #if 0 /* Not Used */
839 /*
840  * This helper function is called once for each row in the tree view
841  * that is currently selected. Its task is to append the corresponding
842  * owner to the end of a glist.
843  */
844 static void
845 get_selected_owners_helper (GtkTreeModel *s_model,
846  GtkTreePath *s_path,
847  GtkTreeIter *s_iter,
848  gpointer data)
849 {
850  GncTreeViewSelectionInfo *gtvsi = data;
851  GtkTreeModel *f_model;
852  GtkTreeIter iter, f_iter;
853  GncOwner *owner;
854 
855  gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
856  &f_iter, s_iter);
857 
858  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
859  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
860  &iter, &f_iter);
861  owner = iter.user_data;
862 
863  /* Only selected if it passes the filter */
864  if (gtvsi->view->filter_fn == NULL || gtvsi->view->filter_fn(owner, gtvsi->view->filter_data))
865  {
866  gtvsi->return_list = g_list_append(gtvsi->return_list, owner);
867  }
868 }
869 #endif /* Not Used */
870 
871 /************************************************************/
872 /* Owner Tree View Add Column Functions */
873 /************************************************************/
874 
875 static void
876 gtvo_update_column_name (GtkTreeViewColumn *column,
877  const gchar *fmt,
878  const gchar *mnemonic)
879 {
880  gchar *name;
881 
882  g_return_if_fail(column);
883 
884  name = g_strdup_printf(fmt, mnemonic);
885  gtk_tree_view_column_set_title(column, name);
886  g_free(name);
887 }
888 
889 
890 static void
891 gtvo_update_column_names (GncTreeViewOwner *view)
892 {
893  const gchar *mnemonic = gnc_commodity_get_mnemonic(gnc_default_report_currency());
894 
895  gtvo_update_column_name(view->balance_report_column,
896  /* Translators: %s is a currency mnemonic.*/
897  _("Balance (%s)"), mnemonic);
898  gnc_tree_view_set_show_column_menu(GNC_TREE_VIEW(view), FALSE);
899  gnc_tree_view_set_show_column_menu(GNC_TREE_VIEW(view), TRUE);
900 }
901 
902 
903 static void
904 gtvo_currency_changed_cb (void)
905 {
906  const GList *views, *ptr;
907 
908  views = gnc_gobject_tracking_get_list (GNC_TREE_VIEW_OWNER_NAME);
909  for (ptr = views; ptr; ptr = g_list_next(ptr))
910  {
911  gtvo_update_column_names (ptr->data);
912  }
913 }
914 
915 #if 0 /* Not Used */
916 /* This function implements a custom mapping between an owner's KVP
917  * and the cell renderer's 'text' property. */
918 static void
919 owner_cell_kvp_data_func (GtkTreeViewColumn *tree_column,
920  GtkCellRenderer *cell,
921  GtkTreeModel *s_model,
922  GtkTreeIter *s_iter,
923  gpointer key)
924 {
925  GncOwner *owner;
926  GValue v = G_VALUE_INIT;
927 
928  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model));
929  owner = gnc_tree_view_owner_get_owner_from_iter(s_model, s_iter);
930  qof_instance_get_kvp (QOF_INSTANCE (owner), (gchar*)key, &v);
931  if (G_VALUE_HOLDS_STRING)
932  g_object_set (G_OBJECT (cell),
933  "text", g_value_get_string (&v),
934  "xalign", 0.0,
935  NULL);
936 
937 }
938 
939 static void col_edited_helper(GtkCellRendererText *cell, gchar *path_string,
940  gchar *new_text, gpointer _s_model)
941 {
942  GncOwner *owner;
943  GtkTreeModel *s_model;
944  GtkTreeIter s_iter;
945  GncTreeViewOwnerColumnTextEdited col_edited_cb;
946  GtkTreeViewColumn *col;
947 
948  col_edited_cb = g_object_get_data(G_OBJECT(cell),
949  "column_edited_callback");
950  col = GTK_TREE_VIEW_COLUMN(g_object_get_data(G_OBJECT(cell),
951  "column_view"));
952  s_model = GTK_TREE_MODEL(_s_model);
953 
954  if (!gtk_tree_model_get_iter_from_string(s_model, &s_iter, path_string))
955  return;
956 
957  owner = gnc_tree_view_owner_get_owner_from_iter(s_model, &s_iter);
958  col_edited_cb(owner, col, new_text);
959 }
960 
961 static void col_source_helper(GtkTreeViewColumn *col, GtkCellRenderer *cell,
962  GtkTreeModel *s_model, GtkTreeIter *s_iter,
963  gpointer _col_source_cb)
964 {
965  GncOwner *owner;
966  gchar *text;
967  GncTreeViewOwnerColumnSource col_source_cb;
968 
969  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model));
970  col_source_cb = (GncTreeViewOwnerColumnSource) _col_source_cb;
971  owner = gnc_tree_view_owner_get_owner_from_iter(s_model, s_iter);
972  text = col_source_cb(owner, col, cell);
973  g_object_set (G_OBJECT (cell), "text", text, "xalign", 1.0, NULL);
974  g_free(text);
975 }
976 
981 void
982 gtvo_setup_column_renderer_edited_cb(GncTreeViewOwner *owner_view,
983  GtkTreeViewColumn *column,
984  GtkCellRenderer *renderer,
985  GncTreeViewOwnerColumnTextEdited col_edited_cb)
986 {
987  GtkTreeModel *s_model;
988 
989  if (col_edited_cb == NULL)
990  {
991  g_object_set(G_OBJECT(renderer), "editable", FALSE, NULL);
992  g_object_set_data(G_OBJECT(renderer), "column_edited_callback", col_edited_cb);
993  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(owner_view));
994  g_signal_handlers_disconnect_by_func(G_OBJECT(renderer), col_edited_cb, s_model);
995  g_object_set_data(G_OBJECT(renderer), "column_view", column);
996  }
997  else
998  {
999  g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL);
1000  g_object_set_data(G_OBJECT(renderer), "column_edited_callback",
1001  col_edited_cb);
1002  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(owner_view));
1003  g_signal_connect(G_OBJECT(renderer), "edited",
1004  (GCallback) col_edited_helper, s_model);
1005  g_object_set_data(G_OBJECT(renderer), "column_view", column);
1006  }
1007 }
1008 #endif /* Not Used */
1009 
1010 /* BEGIN FILTER FUNCTIONS */
1011 #define FILTER_TREE_VIEW "types_tree_view"
1012 
1024 gboolean
1026  gpointer user_data)
1027 {
1028  OwnerFilterDialog *fd = user_data;
1029  gnc_numeric total;
1030 
1031  ENTER("owner %p:%s", owner, gncOwnerGetName(owner));
1032 
1033  if (!fd->show_inactive && !gncOwnerGetActive (owner))
1034  {
1035  LEAVE(" hide: inactive");
1036  return FALSE;
1037  }
1038 
1039  if (!fd->show_zero_total)
1040  {
1041  total = gncOwnerGetBalanceInCurrency (owner, NULL);
1042  if (gnc_numeric_zero_p(total))
1043  {
1044  LEAVE(" hide: zero balance");
1045  return FALSE;
1046  }
1047  }
1048 
1049  return TRUE;
1050 }
1051 
1058 void
1059 gppot_filter_show_inactive_toggled_cb (GtkToggleButton *button,
1060  OwnerFilterDialog *fd)
1061 {
1062  g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button));
1063 
1064  ENTER("button %p", button);
1065  fd->show_inactive = !gtk_toggle_button_get_active(button);
1066  gnc_tree_view_owner_refilter(fd->tree_view);
1067  LEAVE("show_inactive %d", fd->show_inactive);
1068 }
1069 
1076 void
1077 gppot_filter_show_zero_toggled_cb (GtkToggleButton *button,
1078  OwnerFilterDialog *fd)
1079 {
1080  g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button));
1081 
1082  ENTER("button %p", button);
1083  fd->show_zero_total = gtk_toggle_button_get_active(button);
1084  gnc_tree_view_owner_refilter(fd->tree_view);
1085  LEAVE("show_zero %d", fd->show_zero_total);
1086 }
1087 
1097 void
1098 gppot_filter_response_cb (GtkWidget *dialog,
1099  gint response,
1100  OwnerFilterDialog *fd)
1101 {
1102  gpointer gptemp;
1103 
1104  g_return_if_fail(GTK_IS_DIALOG(dialog));
1105 
1106  ENTER("dialog %p, response %d", dialog, response);
1107 
1108  if (response != GTK_RESPONSE_OK)
1109  {
1110  fd->show_inactive = fd->original_show_inactive;
1111  fd->show_zero_total = fd->original_show_zero_total;
1112  gnc_tree_view_owner_refilter(fd->tree_view);
1113  }
1114 
1115  /* Clean up and delete dialog */
1116  gptemp = (gpointer)fd->dialog;
1117  g_atomic_pointer_compare_and_exchange(&gptemp,
1118  (gpointer)dialog, NULL);
1119  fd->dialog = gptemp;
1120  gtk_widget_destroy(dialog);
1121  LEAVE("");
1122 }
1123 
1124 void
1125 owner_filter_dialog_create(OwnerFilterDialog *fd, GncPluginPage *page)
1126 {
1127  GtkWidget *dialog, *button;
1128  GtkBuilder *builder;
1129  gchar *title;
1130 
1131  ENTER("(fd %p, page %p)", fd, page);
1132 
1133  if (fd->dialog)
1134  {
1135  gtk_window_present(GTK_WINDOW(fd->dialog));
1136  LEAVE("existing dialog");
1137  return;
1138  }
1139 
1140  /* Create the dialog */
1141  builder = gtk_builder_new();
1142  gnc_builder_add_from_file (builder, "gnc-tree-view-owner.glade", "filter_by_dialog");
1143  dialog = GTK_WIDGET(gtk_builder_get_object (builder, "filter_by_dialog"));
1144  fd->dialog = dialog;
1145  gtk_window_set_transient_for(GTK_WINDOW(dialog),
1146  GTK_WINDOW(GNC_PLUGIN_PAGE(page)->window));
1147  /* Translators: The %s is the name of the plugin page */
1148  title = g_strdup_printf(_("Filter %s by…"),
1149  gnc_plugin_page_get_page_name(GNC_PLUGIN_PAGE(page)));
1150  gtk_window_set_title(GTK_WINDOW(dialog), title);
1151  g_free(title);
1152 
1153  /* Remember current state */
1154  fd->original_show_inactive = fd->show_inactive;
1155  fd->original_show_zero_total = fd->show_zero_total;
1156 
1157  /* Update the dialog widgets for the current state */
1158  button = GTK_WIDGET(gtk_builder_get_object (builder, "show_inactive"));
1159  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
1160  !fd->show_inactive);
1161  button = GTK_WIDGET(gtk_builder_get_object (builder, "show_zero"));
1162  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
1163  fd->show_zero_total);
1164 
1165  /* Wire up the rest of the callbacks */
1166  gtk_builder_connect_signals (builder, fd);
1167  g_object_unref(G_OBJECT(builder));
1168 
1169  /* Show it */
1170  gtk_widget_show_all (dialog);
1171  LEAVE(" ");
1172 }
1173 
1174 #define OWNER_SELECTED_LABEL "SelectedOwner"
1175 #define SHOW_INACTIVE_LABEL "ShowInactive"
1176 #define SHOW_ZERO_LABEL "ShowZeroTotal"
1177 
1178 typedef struct foo
1179 {
1180  GKeyFile *key_file;
1181  const gchar *group_name;
1182 } bar_t;
1183 
1194 static void
1195 tree_save_selected_row (GncTreeViewOwner *view,
1196  gpointer user_data)
1197 {
1198  GncOwner *owner;
1199  bar_t *bar = user_data;
1200  const gchar *owner_name;
1201 
1203  if (owner == NULL)
1204  return;
1205 
1206  owner_name = gncOwnerGetName (owner);
1207  if (owner_name == NULL)
1208  return;
1209 
1210  g_key_file_set_string(bar->key_file, bar->group_name, OWNER_SELECTED_LABEL,
1211  owner_name);
1212 }
1213 
1214 void
1215 gnc_tree_view_owner_save(GncTreeViewOwner *view,
1216  OwnerFilterDialog *fd,
1217  GKeyFile *key_file, const gchar *group_name)
1218 {
1219  bar_t bar;
1220 
1221  g_return_if_fail (key_file != NULL);
1222  g_return_if_fail (group_name != NULL);
1223 
1224  ENTER("view %p, key_file %p, group_name %s", view, key_file,
1225  group_name);
1226 
1227  g_key_file_set_boolean(key_file, group_name, SHOW_INACTIVE_LABEL,
1228  fd->show_inactive);
1229  g_key_file_set_boolean(key_file, group_name, SHOW_ZERO_LABEL,
1230  fd->show_zero_total);
1231 
1232  bar.key_file = key_file;
1233  bar.group_name = group_name;
1234  tree_save_selected_row(view, &bar);
1235  LEAVE(" ");
1236 
1237 }
1238 
1246 static void
1247 tree_restore_selected_row (GncTreeViewOwner *view,
1248  GncOwnerType owner_type,
1249  const gchar *owner_guid_str)
1250 {
1251  GncOwner *owner = gncOwnerNew();
1252  QofBook *book;
1253  GncGUID owner_guid;
1254 
1255  book = qof_session_get_book (gnc_get_current_session());
1256  if (string_to_guid (owner_guid_str, &owner_guid))
1257  if (gncOwnerGetOwnerFromTypeGuid (book, owner, gncOwnerTypeToQofIdType(owner_type), &owner_guid))
1259 }
1260 
1261 void
1262 gnc_tree_view_owner_restore(GncTreeViewOwner *view,
1263  OwnerFilterDialog *fd,
1264  GKeyFile *key_file, const gchar *group_name,
1265  GncOwnerType owner_type)
1266 {
1267  GError *error = NULL;
1268  gchar *value;
1269  gboolean show;
1270 
1271  /* Filter information. Ignore missing keys. */
1272  show = g_key_file_get_boolean(key_file, group_name, SHOW_INACTIVE_LABEL, &error);
1273  if (error)
1274  {
1275  g_warning("error reading group %s key %s: %s",
1276  group_name, SHOW_INACTIVE_LABEL, error->message);
1277  g_error_free(error);
1278  error = NULL;
1279  show = TRUE;
1280  }
1281  fd->show_inactive = show;
1282 
1283  show = g_key_file_get_boolean(key_file, group_name, SHOW_ZERO_LABEL, &error);
1284  if (error)
1285  {
1286  g_warning("error reading group %s key %s: %s",
1287  group_name, SHOW_ZERO_LABEL, error->message);
1288  g_error_free(error);
1289  error = NULL;
1290  show = TRUE;
1291  }
1292  fd->show_zero_total = show;
1293 
1294  /* Selected owner (if any) */
1295  value = g_key_file_get_string(key_file, group_name, OWNER_SELECTED_LABEL, NULL);
1296  if (value)
1297  {
1298  tree_restore_selected_row(view, owner_type, value);
1299  g_free(value);
1300  }
1301 
1302  /* Update tree view for any changes */
1304 }
1305 
1306 #if 0 /* Not Used */
1307 static void
1308 gtvo_set_column_editor(GncTreeViewOwner *view,
1309  GtkTreeViewColumn *column,
1310  GncTreeViewOwnerColumnTextEdited edited_cb)
1311 {
1312  GList *renderers_orig, *renderers;
1313  GtkCellRenderer *renderer;
1314 
1315  // look for the first text-renderer; on the 0th column of the owner tree,
1316  // there are two renderers: pixbuf and text. So find the text one.
1317  for (renderers_orig = renderers = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1318  renderers && !GTK_IS_CELL_RENDERER_TEXT(renderers->data);
1319  renderers = renderers->next);
1320  renderer = GTK_CELL_RENDERER(renderers->data);
1321  g_list_free(renderers_orig);
1322  g_return_if_fail(renderer != NULL);
1323  gtvo_setup_column_renderer_edited_cb(GNC_TREE_VIEW_OWNER(view), column, renderer, edited_cb);
1324 }
1325 #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.
int 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.
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.
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.