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