GnuCash  4.11-11-ge9df8d41d2+
gnc-plugin-page-owner-tree.c
Go to the documentation of this file.
1 /*
2  * gnc-plugin-page-owner-tree.c --
3  *
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 
34 #include <config.h>
35 
36 #include <gtk/gtk.h>
37 #include <glib/gi18n.h>
38 #include "swig-runtime.h"
39 
40 #include "gnc-plugin.h"
42 #include "gnc-plugin-page-report.h"
43 
44 #include "dialog-vendor.h"
45 #include "dialog-customer.h"
46 #include "dialog-employee.h"
47 #include "dialog-invoice.h"
48 #include "dialog-job.h"
49 #include "dialog-payment.h"
50 
51 #include "gncOwner.h"
52 #include "dialog-utils.h"
53 #include "gnc-component-manager.h"
54 #include "gnc-engine.h"
55 #include "gnc-gnome-utils.h"
56 #include "gnc-gobject-utils.h"
57 #include "gnc-icons.h"
58 #include "gnc-session.h"
59 #include "gnc-tree-view-owner.h"
60 #include "gnc-ui.h"
61 #include "gnc-ui-util.h"
62 #include "gnc-window.h"
63 #include "guile-mappings.h"
64 #include "dialog-lot-viewer.h"
66 
67 /* This static indicates the debugging module that this .o belongs to. */
68 static QofLogModule log_module = GNC_MOD_GUI;
69 
70 #define PLUGIN_PAGE_ACCT_TREE_CM_CLASS "plugin-page-owner-tree"
71 
72 #define DELETE_DIALOG_FILTER "filter"
73 #define DELETE_DIALOG_OWNER "owner"
74 
75 enum
76 {
77  OWNER_SELECTED,
78  LAST_SIGNAL
79 };
80 
82 {
83  GtkWidget *widget;
84  GtkTreeView *tree_view;
85  gint component_id;
86  GncOwnerType owner_type;
89 
90 #define GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(o) \
91  ((GncPluginPageOwnerTreePrivate*)g_type_instance_get_private((GTypeInstance*)o, GNC_TYPE_PLUGIN_PAGE_OWNER_TREE))
92 
93 static GObjectClass *parent_class = NULL;
94 
95 /************************************************************
96  * Prototypes *
97  ************************************************************/
98 /* Plugin Actions */
99 static void gnc_plugin_page_owner_tree_class_init (GncPluginPageOwnerTreeClass *klass);
100 static void gnc_plugin_page_owner_tree_init (GncPluginPageOwnerTree *plugin_page);
101 static void gnc_plugin_page_owner_tree_finalize (GObject *object);
102 static void gnc_plugin_page_owner_tree_selected (GObject *object, gpointer user_data);
103 
104 static GtkWidget *gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page);
105 static void gnc_plugin_page_owner_tree_destroy_widget (GncPluginPage *plugin_page);
106 static void gnc_plugin_page_owner_tree_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
107 static GncPluginPage *gnc_plugin_page_owner_tree_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
108 
109 /* Callbacks */
110 static gboolean gnc_plugin_page_owner_tree_button_press_cb (GtkWidget *widget,
111  GdkEventButton *event,
112  GncPluginPage *page);
113 static void gnc_plugin_page_owner_tree_double_click_cb (GtkTreeView *treeview,
114  GtkTreePath *path,
115  GtkTreeViewColumn *col,
116  GncPluginPageOwnerTree *page);
117 
118 static void gnc_plugin_page_owner_tree_selection_changed_cb (GtkTreeSelection *selection,
119  GncPluginPageOwnerTree *page);
120 
121 /* Command callbacks */
122 static void gnc_plugin_page_owner_tree_cmd_new_owner (GtkAction *action, GncPluginPageOwnerTree *page);
123 static void gnc_plugin_page_owner_tree_cmd_edit_owner (GtkAction *action, GncPluginPageOwnerTree *page);
124 #if 0 /* Disabled due to crash */
125 static void gnc_plugin_page_owner_tree_cmd_delete_owner (GtkAction *action, GncPluginPageOwnerTree *page);
126 #endif
127 static void gnc_plugin_page_owner_tree_cmd_view_filter_by (GtkAction *action, GncPluginPageOwnerTree *page);
128 static void gnc_plugin_page_owner_tree_cmd_refresh (GtkAction *action, GncPluginPageOwnerTree *page);
129 static void gnc_plugin_page_owner_tree_cmd_new_invoice (GtkAction *action, GncPluginPageOwnerTree *page);
130 static void gnc_plugin_page_owner_tree_cmd_owners_report (GtkAction *action, GncPluginPageOwnerTree *plugin_page);
131 static void gnc_plugin_page_owner_tree_cmd_owner_report (GtkAction *action, GncPluginPageOwnerTree *plugin_page);
132 static void gnc_plugin_page_owner_tree_cmd_process_payment (GtkAction *action, GncPluginPageOwnerTree *plugin_page);
133 
134 
135 static guint plugin_page_signals[LAST_SIGNAL] = { 0 };
136 
137 
138 static GtkActionEntry gnc_plugin_page_owner_tree_actions [] =
139 {
140  /* Toplevel */
141  { "FakeToplevel", NULL, "", NULL, NULL, NULL },
142 
143  /* Edit menu */
144  {
145  "OTEditVendorAction", GNC_ICON_EDIT_ACCOUNT, N_("E_dit Vendor"), "<primary>e",
146  N_("Edit the selected vendor"),
147  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_edit_owner)
148  },
149  {
150  "OTEditCustomerAction", GNC_ICON_EDIT_ACCOUNT, N_("E_dit Customer"), "<primary>e",
151  N_("Edit the selected customer"),
152  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_edit_owner)
153  },
154  {
155  "OTEditEmployeeAction", GNC_ICON_EDIT_ACCOUNT, N_("E_dit Employee"), "<primary>e",
156  N_("Edit the selected employee"),
157  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_edit_owner)
158  },
159  {
160  "OTNewVendorAction", GNC_ICON_NEW_ACCOUNT, N_("_New Vendor..."), NULL,
161  N_("Create a new vendor"),
162  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_new_owner)
163  },
164  {
165  "OTNewCustomerAction", GNC_ICON_NEW_ACCOUNT, N_("_New Customer..."), NULL,
166  N_("Create a new customer"),
167  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_new_owner)
168  },
169  {
170  "OTNewEmployeeAction", GNC_ICON_NEW_ACCOUNT, N_("_New Employee..."), NULL,
171  N_("Create a new employee"),
172  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_new_owner)
173  },
174 
175 #if 0 /* Disabled due to crash */
176  {
177  "EditDeleteOwnerAction", GNC_ICON_DELETE_ACCOUNT, N_("_Delete Owner..."), "Delete",
178  N_("Delete selected owner"),
179  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_delete_owner)
180  },
181 #endif /* Disabled due to crash */
182 
183  /* View menu */
184  {
185  "ViewFilterByAction", NULL, N_("_Filter By..."), NULL, NULL,
186  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_view_filter_by)
187  },
188  {
189  "ViewRefreshAction", "view-refresh", N_("_Refresh"), "<primary>r",
190  N_("Refresh this window"),
191  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_refresh)
192  },
193 
194  /* Business menu */
195  {
196  "OTNewBillAction", GNC_ICON_INVOICE_NEW, N_("New _Bill..."), NULL,
197  N_("Create a new bill"),
198  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_new_invoice)
199  },
200  {
201  "OTNewInvoiceAction", GNC_ICON_INVOICE_NEW, N_("New _Invoice..."), NULL,
202  N_("Create a new invoice"),
203  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_new_invoice)
204  },
205  {
206  "OTNewVoucherAction", GNC_ICON_INVOICE_NEW, N_("New _Voucher..."), NULL,
207  N_("Create a new voucher"),
208  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_new_invoice)
209  },
210  {
211  "OTVendorListingReportAction", "document-print-preview", N_("Vendor Listing"), NULL,
212  N_("Show vendor aging overview for all vendors"),
213  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_owners_report)
214  },
215  {
216  "OTCustomerListingReportAction", "document-print-preview", N_("Customer Listing"), NULL,
217  N_("Show customer aging overview for all customers"),
218  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_owners_report)
219  },
220  {
221  "OTVendorReportAction", NULL, N_("Vendor Report"), NULL,
222  N_("Show vendor report"),
223  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_owner_report)
224  },
225  {
226  "OTCustomerReportAction", NULL, N_("Customer Report"), NULL,
227  N_("Show customer report"),
228  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_owner_report)
229  },
230  {
231  "OTEmployeeReportAction", NULL, N_("Employee Report"), NULL,
232  N_("Show employee report"),
233  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_owner_report)
234  },
235  {
236  "OTProcessPaymentAction", GNC_ICON_INVOICE_PAY,
237  N_("Process Payment"), NULL, N_("Process Payment"),
238  G_CALLBACK (gnc_plugin_page_owner_tree_cmd_process_payment)
239  },
240 };
242 static guint gnc_plugin_page_owner_tree_n_actions = G_N_ELEMENTS (gnc_plugin_page_owner_tree_actions);
243 
244 
247 static const gchar *actions_requiring_owner_rw[] =
248 {
249  "OTEditVendorAction",
250  "OTEditCustomerAction",
251  "OTEditEmployeeAction",
252  "OTProcessPaymentAction",
253 /* FIXME disabled due to crash "EditDeleteOwnerAction", */
254  NULL
255 };
256 
259 static const gchar *actions_requiring_owner_always[] =
260 {
261  "OTVendorReportAction",
262  "OTCustomerReportAction",
263  "OTEmployeeReportAction",
264  "OTProcessPaymentAction",
265  NULL
266 };
267 
268 /* This is the list of actions which are switched inactive in a read-only book. */
269 static const gchar* readonly_inactive_actions[] =
270 {
271  "OTNewVendorAction",
272  "OTNewCustomerAction",
273  "OTNewEmployeeAction",
274  "OTNewBillAction",
275  "OTNewInvoiceAction",
276  "OTNewVoucherAction",
277  "OTProcessPaymentAction",
278  NULL
279 };
280 
281 
283 static action_toolbar_labels toolbar_labels[] =
284 {
285  { "OTEditVendorAction", N_("Edit") },
286  { "OTEditCustomerAction", N_("Edit") },
287  { "OTEditEmployeeAction", N_("Edit") },
288  { "OTNewVendorAction", N_("New") },
289  { "OTNewCustomerAction", N_("New") },
290  { "OTNewEmployeeAction", N_("New") },
291  { "OTNewBillAction", N_("New Bill") },
292  { "OTNewInvoiceAction", N_("New Invoice") },
293  { "OTNewVoucherAction", N_("New Voucher") },
294  { "OTVendorListingReportAction", N_("Vendor Listing") },
295  { "OTCustomerListingReportAction", N_("Customer Listing") },
296  { "OTProcessPaymentAction", N_("Process Payment") },
297 /* FIXME disable due to crash { "EditDeleteOwnerAction", N_("Delete") },*/
298  { NULL, NULL },
299 };
300 
304 typedef struct
305 {
307  const char *action_name;
309  GncOwnerType owner_type;
311 
312 static action_owners_struct action_owners[] =
313 {
314  { "OTEditVendorAction", GNC_OWNER_VENDOR },
315  { "OTEditCustomerAction", GNC_OWNER_CUSTOMER },
316  { "OTEditEmployeeAction", GNC_OWNER_EMPLOYEE },
317  { "OTNewVendorAction", GNC_OWNER_VENDOR },
318  { "OTNewCustomerAction", GNC_OWNER_CUSTOMER },
319  { "OTNewEmployeeAction", GNC_OWNER_EMPLOYEE },
320  { "OTNewBillAction", GNC_OWNER_VENDOR },
321  { "OTNewInvoiceAction", GNC_OWNER_CUSTOMER },
322  { "OTNewVoucherAction", GNC_OWNER_EMPLOYEE },
323  { "OTVendorListingReportAction", GNC_OWNER_VENDOR },
324  { "OTCustomerListingReportAction", GNC_OWNER_CUSTOMER },
325  { "OTVendorReportAction", GNC_OWNER_VENDOR },
326  { "OTCustomerReportAction", GNC_OWNER_CUSTOMER },
327  { "OTEmployeeReportAction", GNC_OWNER_EMPLOYEE },
328  { NULL, GNC_OWNER_NONE },
329 };
330 
332 gnc_plugin_page_owner_tree_new (GncOwnerType owner_type)
333 {
334  GncPluginPageOwnerTree *plugin_page;
335 
337  const GList *item;
338 
339  GtkActionGroup *action_group;
340  GtkAction *action;
341  gint i;
342 
343  g_return_val_if_fail( (owner_type != GNC_OWNER_UNDEFINED)
344  && (owner_type != GNC_OWNER_NONE), NULL);
345  ENTER(" ");
346 
347  /* Is there an existing page? */
348  item = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_OWNER_TREE_NAME);
349  for ( ; item; item = g_list_next(item))
350  {
351  plugin_page = (GncPluginPageOwnerTree *)item->data;
352  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
353  if (priv->owner_type == owner_type)
354  {
355  LEAVE("existing %s tree page %p", gncOwnerTypeToQofIdType(owner_type), plugin_page);
356  return GNC_PLUGIN_PAGE(plugin_page);
357  }
358  }
359 
360  plugin_page = g_object_new(GNC_TYPE_PLUGIN_PAGE_OWNER_TREE, NULL);
361 
362  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
363  priv->owner_type = owner_type;
364 
365  /* Hide menu and toolbar items that are not relevant for the active owner list */
366  action_group = gnc_plugin_page_get_action_group(GNC_PLUGIN_PAGE(plugin_page));
367  for (i = 0; action_owners[i].action_name; i++)
368  {
369  action = gtk_action_group_get_action (action_group, action_owners[i].action_name);
370  g_object_set (G_OBJECT(action),
371  "visible", (priv->owner_type == action_owners[i].owner_type),
372  NULL);
373  }
374 
375  LEAVE("new %s tree page %p", gncOwnerTypeToQofIdType(owner_type), plugin_page);
376  return GNC_PLUGIN_PAGE(plugin_page);
377 }
378 
383 static gboolean
384 gnc_plugin_page_owner_focus_widget (GncPluginPage *owner_plugin_page)
385 {
386  if (GNC_IS_PLUGIN_PAGE_OWNER_TREE(owner_plugin_page))
387  {
388  GncPluginPageOwnerTreePrivate *priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(owner_plugin_page);
389  GtkTreeView *tree_view = priv->tree_view;
390 
391  if (GTK_IS_TREE_VIEW(tree_view))
392  {
393  if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
394  gtk_widget_grab_focus (GTK_WIDGET(tree_view));
395  }
396  }
397  return FALSE;
398 }
399 
400 G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageOwnerTree, gnc_plugin_page_owner_tree, GNC_TYPE_PLUGIN_PAGE)
401 
402 static void
403 gnc_plugin_page_owner_tree_class_init (GncPluginPageOwnerTreeClass *klass)
404 {
405  GObjectClass *object_class = G_OBJECT_CLASS (klass);
406  GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
407 
408  parent_class = g_type_class_peek_parent (klass);
409 
410  object_class->finalize = gnc_plugin_page_owner_tree_finalize;
411 
412  gnc_plugin_class->tab_icon = GNC_ICON_ACCOUNT;
413  gnc_plugin_class->plugin_name = GNC_PLUGIN_PAGE_OWNER_TREE_NAME;
414  gnc_plugin_class->create_widget = gnc_plugin_page_owner_tree_create_widget;
415  gnc_plugin_class->destroy_widget = gnc_plugin_page_owner_tree_destroy_widget;
416  gnc_plugin_class->save_page = gnc_plugin_page_owner_tree_save_page;
417  gnc_plugin_class->recreate_page = gnc_plugin_page_owner_tree_recreate_page;
418  gnc_plugin_class->focus_page_function = gnc_plugin_page_owner_focus_widget;
419 
420  plugin_page_signals[OWNER_SELECTED] =
421  g_signal_new ("owner_selected",
422  G_OBJECT_CLASS_TYPE (object_class),
423  G_SIGNAL_RUN_FIRST,
424  G_STRUCT_OFFSET (GncPluginPageOwnerTreeClass, owner_selected),
425  NULL, NULL,
426  g_cclosure_marshal_VOID__POINTER,
427  G_TYPE_NONE, 1,
428  G_TYPE_POINTER);
429 }
430 
431 static void
432 gnc_plugin_page_owner_tree_init (GncPluginPageOwnerTree *plugin_page)
433 {
434  GtkActionGroup *action_group;
436  GncPluginPage *parent;
437 
438  ENTER("page %p", plugin_page);
439  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
440 
441  /* Init parent declared variables */
442  parent = GNC_PLUGIN_PAGE(plugin_page);
443  g_object_set(G_OBJECT(plugin_page),
444  "page-name", _("Owners"),
445  "page-uri", "default:",
446  "ui-description", "gnc-plugin-page-owner-tree-ui.xml",
447  NULL);
448  g_signal_connect (G_OBJECT (plugin_page), "selected",
449  G_CALLBACK (gnc_plugin_page_owner_tree_selected), plugin_page);
450 
451  /* change me when the system supports multiple books */
452  gnc_plugin_page_add_book(parent, gnc_get_current_book());
453 
454  /* Create menu and toolbar information */
455  action_group =
457  "GncPluginPageOwnerTreeActions");
458  gtk_action_group_add_actions(action_group,
459  gnc_plugin_page_owner_tree_actions,
460  gnc_plugin_page_owner_tree_n_actions,
461  plugin_page);
462  gnc_plugin_init_short_names (action_group, toolbar_labels);
463 
464 
465  /* Init filter */
466  priv->fd.show_inactive = TRUE;
467  priv->fd.show_zero_total = TRUE;
468 
469  LEAVE("page %p, priv %p, action group %p",
470  plugin_page, priv, action_group);
471 }
472 
473 static void
474 gnc_plugin_page_owner_tree_finalize (GObject *object)
475 {
478 
479  ENTER("object %p", object);
480  page = GNC_PLUGIN_PAGE_OWNER_TREE (object);
481  g_return_if_fail (GNC_IS_PLUGIN_PAGE_OWNER_TREE (page));
482  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
483  g_return_if_fail (priv != NULL);
484 
485  G_OBJECT_CLASS (parent_class)->finalize (object);
486  LEAVE(" ");
487 }
488 
489 static void update_inactive_actions(GncPluginPage *plugin_page)
490 {
491  GtkActionGroup *action_group;
492  gboolean is_sensitive = !qof_book_is_readonly(gnc_get_current_book());
493 
494  // We are readonly - so we have to switch particular actions to inactive.
495  g_return_if_fail(plugin_page);
496  g_return_if_fail(GNC_IS_PLUGIN_PAGE(plugin_page));
497 
498  /* Get the action group */
499  action_group = gnc_plugin_page_get_action_group(plugin_page);
500  g_return_if_fail(GTK_IS_ACTION_GROUP (action_group));
501 
502  /* Set the action's sensitivity */
503  gnc_plugin_update_actions (action_group, readonly_inactive_actions,
504  "sensitive", is_sensitive);
505 }
506 
507 static void
508 gnc_plugin_page_owner_tree_selected (GObject *object, gpointer user_data)
509 {
510  GncPluginPage *page = GNC_PLUGIN_PAGE (object);
511  g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
512  update_inactive_actions(page);
513 }
514 
515 
516 GncOwner *
518 {
520  GncOwner *owner;
521 
522  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
523  ENTER("page %p (tree view %p)", page, priv->tree_view);
524  owner = gnc_tree_view_owner_get_selected_owner (GNC_TREE_VIEW_OWNER(priv->tree_view));
525  if (owner == NULL)
526  {
527  LEAVE("no owner");
528  return NULL;
529  }
530 
531  LEAVE("owner %p", owner);
532  return owner;
533 }
534 
535 
536 /* Virtual Functions */
537 
538 static void
539 gnc_plugin_page_owner_refresh_cb (GHashTable *changes, gpointer user_data)
540 {
541  GncPluginPageOwnerTree *page = user_data;
543 
544  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
545 
546  /* We're only looking for forced updates here. */
547  if (changes)
548  return;
549 
550  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
551  gtk_widget_queue_draw(priv->widget);
552 }
553 
554 static void
555 gnc_plugin_page_owner_tree_close_cb (gpointer user_data)
556 {
557  GncPluginPage *plugin_page;
558 
559  plugin_page = GNC_PLUGIN_PAGE(user_data);
560  gnc_main_window_close_page(plugin_page);
561 }
562 
563 static GtkWidget *
564 gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page)
565 {
568  GtkTreeSelection *selection;
569  GtkTreeView *tree_view;
570  GtkWidget *scrolled_window;
571  GtkTreeViewColumn *col;
572  const gchar *state_section = NULL;
573  gchar* label = "";
574  const gchar *style_label = NULL;
575 
576  ENTER("page %p", plugin_page);
577  page = GNC_PLUGIN_PAGE_OWNER_TREE (plugin_page);
578  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
579  if (priv->widget != NULL)
580  {
581  LEAVE("widget = %p", priv->widget);
582  return priv->widget;
583  }
584 
585  priv->widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
586  gtk_box_set_homogeneous (GTK_BOX (priv->widget), FALSE);
587  gtk_widget_show (priv->widget);
588 
589  // Set the name for this widget so it can be easily manipulated with css
590  gtk_widget_set_name (GTK_WIDGET(priv->widget), "gnc-id-owner-page");
591 
592  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
593  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
594  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
595  gtk_widget_show (scrolled_window);
596  gtk_box_pack_start (GTK_BOX (priv->widget), scrolled_window,
597  TRUE, TRUE, 0);
598 
599  tree_view = gnc_tree_view_owner_new(priv->owner_type);
600 
601  /* Show default columns */
603  GNC_TREE_VIEW(tree_view), GNC_OWNER_TREE_ID_COL);
604  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
606  GNC_TREE_VIEW(tree_view), GNC_OWNER_TREE_ADDRESS_1_COL);
607  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
609  GNC_TREE_VIEW(tree_view), GNC_OWNER_TREE_ADDRESS_2_COL);
610  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
612  GNC_TREE_VIEW(tree_view), GNC_OWNER_TREE_PHONE_COL);
613  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
614  gnc_tree_view_configure_columns(GNC_TREE_VIEW(tree_view));
615 
616  switch (priv->owner_type)
617  {
618  case GNC_OWNER_NONE :
619  case GNC_OWNER_UNDEFINED :
620  PWARN("missing owner_type");
621  label = _("Unknown");
622  style_label = "gnc-class-unknown";
623  break;
624  case GNC_OWNER_CUSTOMER :
625  label = _("Customers");
626  state_section = "Customers Overview";
627  style_label = "gnc-class-customers";
628  break;
629  case GNC_OWNER_JOB :
630  label = _("Jobs");
631  state_section = "Jobs Overview";
632  style_label = "gnc-class-jobs";
633  break;
634  case GNC_OWNER_VENDOR :
635  label = _("Vendors");
636  state_section = "Vendors Overview";
637  style_label = "gnc-class-vendors";
638  break;
639  case GNC_OWNER_EMPLOYEE :
640  label = _("Employees");
641  state_section = "Employees Overview";
642  style_label = "gnc-class-employees";
643  break;
644  }
645 
646  // Set a secondary style context for this page so it can be easily manipulated with css
647  gnc_widget_style_context_add_class (GTK_WIDGET(priv->widget), style_label);
648 
649  g_object_set(G_OBJECT(tree_view), "state-section", state_section,
650  "show-column-menu", TRUE,
651  NULL);
652 
653  g_object_set(G_OBJECT(plugin_page), "page-name", label, NULL);
654 
655  priv->tree_view = tree_view;
656  selection = gtk_tree_view_get_selection(tree_view);
657  g_signal_connect (G_OBJECT (selection), "changed",
658  G_CALLBACK (gnc_plugin_page_owner_tree_selection_changed_cb), page);
659  g_signal_connect (G_OBJECT (tree_view), "button-press-event",
660  G_CALLBACK (gnc_plugin_page_owner_tree_button_press_cb), page);
661  g_signal_connect (G_OBJECT (tree_view), "row-activated",
662  G_CALLBACK (gnc_plugin_page_owner_tree_double_click_cb), page);
663 
664  gtk_tree_view_set_headers_visible(tree_view, TRUE);
665  gnc_plugin_page_owner_tree_selection_changed_cb (NULL, page);
666  gtk_widget_show (GTK_WIDGET (tree_view));
667  gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET(tree_view));
668 
669  priv->fd.tree_view = GNC_TREE_VIEW_OWNER(priv->tree_view);
671  GNC_TREE_VIEW_OWNER(tree_view),
673 
674  priv->component_id =
675  gnc_register_gui_component(PLUGIN_PAGE_ACCT_TREE_CM_CLASS,
676  gnc_plugin_page_owner_refresh_cb,
677  gnc_plugin_page_owner_tree_close_cb,
678  page);
679  gnc_gui_component_set_session (priv->component_id,
680  gnc_get_current_session());
681 
682  g_signal_connect (G_OBJECT(plugin_page), "inserted",
683  G_CALLBACK(gnc_plugin_page_inserted_cb),
684  NULL);
685 
686  LEAVE("widget = %p", priv->widget);
687  return priv->widget;
688 }
689 
690 static void
691 gnc_plugin_page_owner_tree_destroy_widget (GncPluginPage *plugin_page)
692 {
695 
696  ENTER("page %p", plugin_page);
697  page = GNC_PLUGIN_PAGE_OWNER_TREE (plugin_page);
698  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
699 
700  // Remove the page_changed signal callback
701  gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
702 
703  // Remove the page focus idle function if present
704  g_idle_remove_by_data (plugin_page);
705 
706  if (priv->widget)
707  {
708  g_object_unref(G_OBJECT(priv->widget));
709  priv->widget = NULL;
710  }
711 
712  if (priv->component_id)
713  {
714  gnc_unregister_gui_component(priv->component_id);
715  priv->component_id = 0;
716  }
717 
718  LEAVE("widget destroyed");
719 }
720 
721 #define OWNER_TYPE_LABEL "OwnerType"
722 
732 static void
733 gnc_plugin_page_owner_tree_save_page (GncPluginPage *plugin_page,
734  GKeyFile *key_file,
735  const gchar *group_name)
736 {
737  GncPluginPageOwnerTree *owner_page;
739 
740  g_return_if_fail (GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
741  g_return_if_fail (key_file != NULL);
742  g_return_if_fail (group_name != NULL);
743 
744  ENTER("page %p, key_file %p, group_name %s", plugin_page, key_file,
745  group_name);
746 
747  owner_page = GNC_PLUGIN_PAGE_OWNER_TREE(plugin_page);
748  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(owner_page);
749 
750  g_key_file_set_integer(key_file, group_name, OWNER_TYPE_LABEL,
751  priv->owner_type);
752 
753  gnc_tree_view_owner_save(GNC_TREE_VIEW_OWNER(priv->tree_view),
754  &priv->fd, key_file, group_name);
755  LEAVE(" ");
756 }
757 
758 
759 
769 static GncPluginPage *
770 gnc_plugin_page_owner_tree_recreate_page (GtkWidget *window,
771  GKeyFile *key_file,
772  const gchar *group_name)
773 {
774  GncPluginPageOwnerTree *owner_page;
776  GncPluginPage *page;
777  GncOwnerType owner_type;
778 
779  g_return_val_if_fail(key_file, NULL);
780  g_return_val_if_fail(group_name, NULL);
781  ENTER("key_file %p, group_name %s", key_file, group_name);
782 
783  /* Create the new page. */
784  owner_type = g_key_file_get_integer(key_file, group_name, OWNER_TYPE_LABEL, NULL);
785  page = gnc_plugin_page_owner_tree_new(owner_type);
786  owner_page = GNC_PLUGIN_PAGE_OWNER_TREE(page);
787  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(owner_page);
788 
789  /* Install it now so we can then manipulate the created widget */
790  gnc_main_window_open_page(GNC_MAIN_WINDOW(window), page);
791 
792  gnc_tree_view_owner_restore(GNC_TREE_VIEW_OWNER(priv->tree_view),
793  &priv->fd, key_file, group_name, owner_type);
794  LEAVE(" ");
795  return page;
796 }
797 
798 /* Wrapper function to open the proper edit dialog, depending on the owner type */
799 static void gnc_ui_owner_edit (GtkWindow *parent, GncOwner *owner)
800 {
801  if (NULL == owner) return;
802 
803  switch (owner->type)
804  {
805  case GNC_OWNER_NONE :
806  case GNC_OWNER_UNDEFINED :
807  break;
808  case GNC_OWNER_CUSTOMER :
809  {
810  gnc_ui_customer_edit (parent, owner->owner.customer);
811  break;
812  }
813  case GNC_OWNER_JOB :
814  {
815  gnc_ui_job_edit (parent, owner->owner.job);
816  break;
817  }
818  case GNC_OWNER_VENDOR :
819  {
820  gnc_ui_vendor_edit (parent, owner->owner.vendor);
821  break;
822  }
823  case GNC_OWNER_EMPLOYEE :
824  {
825  gnc_ui_employee_edit (parent, owner->owner.employee);
826  break;
827  }
828  }
829 }
830 
831 
832 /* Callbacks */
833 
841 static gboolean
842 gnc_plugin_page_owner_tree_button_press_cb (GtkWidget *widget,
843  GdkEventButton *event,
844  GncPluginPage *page)
845 {
846  g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
847 
848  ENTER("widget %p, event %p, page %p", widget, event, page);
849  gnc_main_window_button_press_cb(widget, event, page);
850  LEAVE(" ");
851 
852  /* Always return FALSE. This will let the tree view callback run as
853  * well which will select the item under the cursor. By the time
854  * the user sees the menu both callbacks will have run and the menu
855  * actions will operate on the just-selected owner. */
856  return FALSE;
857 }
858 
859 static void
860 gnc_plugin_page_owner_tree_double_click_cb (GtkTreeView *treeview,
861  GtkTreePath *path,
862  GtkTreeViewColumn *col,
864 {
865  gnc_plugin_page_owner_tree_cmd_owner_report (NULL, page);
866 }
867 
868 static void
869 gnc_plugin_page_owner_tree_selection_changed_cb (GtkTreeSelection *selection,
871 {
872  GtkActionGroup *action_group;
873  GtkTreeView *view;
874  GncOwner *owner = NULL;
875  gboolean sensitive;
876  gboolean is_readwrite = !qof_book_is_readonly(gnc_get_current_book());
877 
878  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
879 
880  if (!selection)
881  {
882  sensitive = FALSE;
883  }
884  else
885  {
886  g_return_if_fail(GTK_IS_TREE_SELECTION(selection));
887  view = gtk_tree_selection_get_tree_view (selection);
888  owner = gnc_tree_view_owner_get_selected_owner (GNC_TREE_VIEW_OWNER(view));
889  sensitive = (owner != NULL);
890  }
891 
892  action_group = gnc_plugin_page_get_action_group(GNC_PLUGIN_PAGE(page));
893  gnc_plugin_update_actions (action_group, actions_requiring_owner_always,
894  "sensitive", sensitive);
895  gnc_plugin_update_actions (action_group, actions_requiring_owner_rw,
896  "sensitive", sensitive && is_readwrite);
897  g_signal_emit (page, plugin_page_signals[OWNER_SELECTED], 0, owner);
898 }
899 
900 /******************************************************************/
901 /* Report helper functions */
902 /******************************************************************/
903 
904 static int
905 build_aging_report (GncOwnerType owner_type)
906 {
907  gchar *report_name = NULL;
908  gchar *report_title = NULL;
909  SCM args;
910  SCM func;
911  SCM arg;
912 
913  args = SCM_EOL;
914 
915  switch (owner_type)
916  {
917  case GNC_OWNER_NONE :
918  case GNC_OWNER_UNDEFINED :
919  case GNC_OWNER_EMPLOYEE :
920  case GNC_OWNER_JOB :
921  {
922  return -1;
923  }
924  case GNC_OWNER_VENDOR :
925  {
926  report_name = "gnc:payables-report-create";
927  report_title = _("Vendor Listing");
928  break;
929  }
930  case GNC_OWNER_CUSTOMER :
931  {
932  report_name = "gnc:receivables-report-create";
933  report_title = _("Customer Listing");
934  break;
935  }
936  }
937 
938  /* Find report generator function in guile */
939  func = scm_c_eval_string (report_name);
940  g_return_val_if_fail (scm_is_procedure (func), -1);
941 
942  /* Option Show zero's ? - Yes for the listing report */
943  arg = SCM_BOOL_T;
944  args = scm_cons (arg, args);
945  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
946 
947  /* Option Report title */
948  arg = scm_from_utf8_string (report_title);
949  args = scm_cons (arg, args);
950 
951  /* Option Account - Using False to select default account
952  *
953  * XXX I'm not sure if it would make sense to use another
954  * account than default */
955  arg = SCM_BOOL_F;
956  args = scm_cons (arg, args);
957  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
958 
959 
960  /* Apply the function to the args */
961  arg = scm_apply (func, args, SCM_EOL);
962  g_return_val_if_fail (scm_is_exact (arg), -1);
963 
964  return scm_to_int (arg);
965 }
966 
967 static int build_owner_report (GncOwner *owner, Account *acc)
968 {
969  SCM args;
970  SCM func;
971  SCM arg;
972 
973  g_return_val_if_fail (owner, -1);
974 
975  args = SCM_EOL;
976 
977  func = scm_c_eval_string ("gnc:owner-report-create-with-enddate");
978  g_return_val_if_fail (scm_is_procedure (func), -1);
979 
980  args = scm_cons (SCM_BOOL_F, args); /* enddate is #f */
981 
982  if (acc)
983  {
984  swig_type_info * qtype = SWIG_TypeQuery("_p_Account");
985  g_return_val_if_fail (qtype, -1);
986 
987  arg = SWIG_NewPointerObj(acc, qtype, 0);
988  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
989  args = scm_cons (arg, args);
990  }
991  else
992  {
993  args = scm_cons (SCM_BOOL_F, args);
994  }
995 
996  arg = SWIG_NewPointerObj(owner, SWIG_TypeQuery("_p__gncOwner"), 0);
997  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
998  args = scm_cons (arg, args);
999 
1000  /* Apply the function to the args */
1001  arg = scm_apply (func, args, SCM_EOL);
1002  g_return_val_if_fail (scm_is_exact (arg), -1);
1003  return scm_to_int (arg);
1004 }
1005 
1006 
1007 /************************************************************/
1008 /* Command callbacks */
1009 /************************************************************/
1010 
1011 static void
1012 gnc_plugin_page_owner_tree_cmd_new_owner (GtkAction *action, GncPluginPageOwnerTree *page)
1013 {
1015  GtkWindow *parent;
1016 
1017  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
1018 
1019  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE (page);
1020  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page)));
1021 
1022  switch (priv->owner_type)
1023  {
1024  case GNC_OWNER_NONE :
1025  case GNC_OWNER_UNDEFINED :
1026  break;
1027  case GNC_OWNER_CUSTOMER :
1028  {
1029  gnc_ui_customer_new (parent, gnc_get_current_book ());
1030  break;
1031  }
1032  case GNC_OWNER_JOB :
1033  {
1034  /* XXX currently not properly implemented, so disabled for now
1035  gnc_ui_job_new (owner, gnc_get_current_book ()); */
1036  break;
1037  }
1038  case GNC_OWNER_VENDOR :
1039  {
1040  gnc_ui_vendor_new (parent, gnc_get_current_book ());
1041  break;
1042  }
1043  case GNC_OWNER_EMPLOYEE :
1044  {
1045  gnc_ui_employee_new (parent, gnc_get_current_book ());
1046  break;
1047  }
1048  }
1049 }
1050 
1051 static void
1052 gnc_plugin_page_owner_tree_cmd_edit_owner (GtkAction *action, GncPluginPageOwnerTree *page)
1053 {
1054  GtkWindow *parent;
1056  if (NULL == owner) return;
1057 
1058  ENTER("action %p, page %p", action, page);
1059 
1060  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page)));
1061  gnc_ui_owner_edit (parent, owner);
1062 
1063  LEAVE(" ");
1064 }
1065 
1066 #if 0 /* Disabled due to crash */
1067 static void
1068 gnc_plugin_page_owner_tree_cmd_delete_owner (GtkAction *action, GncPluginPageOwnerTree *page)
1069 {
1071  gchar *owner_name;
1072  GtkWidget *window;
1073  GtkWidget *dialog = NULL;
1074  gint response;
1075  GList* list;
1076 
1077  if (NULL == owner) return;
1078 
1079  /* If the owner has objects referring to it, show the list - the owner can't be deleted until these
1080  references are dealt with. */
1081  list = qof_instance_get_referring_object_list(QOF_INSTANCE(gncOwnerGetUndefined(owner)));
1082  if (list != NULL)
1083  {
1084 #define EXPLANATION "The list below shows objects which make use of the owner which you want to delete.\nBefore you can delete it, you must either delete those objects or else modify them so they make use\nof another owner"
1085 
1086  gnc_ui_object_references_show( _(EXPLANATION), list);
1087  g_list_free(list);
1088  return;
1089  }
1090 
1091  window = gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(page));
1092  owner_name = g_strdup (gncOwnerGetName(owner));
1093  if (!owner_name)
1094  {
1095  owner_name = g_strdup (_("(no name)"));
1096  }
1097 
1098  /*
1099  * Present a message to the user which specifies what will be
1100  * deleted, then ask for verification.
1101  */
1102  {
1103  char *message = g_strdup_printf(_("The owner %s will be deleted.\nAre you sure you want to do this?"), owner_name);
1104 
1105  dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1106  GTK_DIALOG_DESTROY_WITH_PARENT,
1107  GTK_MESSAGE_QUESTION,
1108  GTK_BUTTONS_NONE,
1109  "%s", message);
1110  g_free(message);
1111  gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1112  _("_Cancel"), GTK_RESPONSE_CANCEL,
1113  _("_Delete"), GTK_RESPONSE_ACCEPT,
1114  (gchar *)NULL);
1115  gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
1116  response = gtk_dialog_run(GTK_DIALOG(dialog));
1117  gtk_widget_destroy(dialog);
1118 
1119  if (GTK_RESPONSE_ACCEPT == response)
1120  {
1121  /* FIXME The code below results in a crash.
1122  * The corresponding menu item/toolbar button is disabled until this is fixed. */
1123  gnc_set_busy_cursor(NULL, TRUE);
1124  gnc_suspend_gui_refresh ();
1125  gncOwnerBeginEdit (owner);
1126  gncOwnerDestroy (owner);
1127  gnc_resume_gui_refresh ();
1128  gnc_unset_busy_cursor(NULL);
1129  }
1130  }
1131  g_free(owner_name);
1132 }
1133 #endif /* Disabled due to crash */
1134 
1135 /*********************/
1136 
1137 static void
1138 gnc_plugin_page_owner_tree_cmd_view_filter_by (GtkAction *action,
1139  GncPluginPageOwnerTree *page)
1140 {
1142 
1143  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
1144  ENTER("(action %p, page %p)", action, page);
1145 
1146  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
1147  owner_filter_dialog_create(&priv->fd, GNC_PLUGIN_PAGE(page));
1148  LEAVE(" ");
1149 }
1150 
1151 static void
1152 gnc_plugin_page_owner_tree_cmd_refresh (GtkAction *action,
1153  GncPluginPageOwnerTree *page)
1154 {
1156 
1157  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
1158 
1159  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
1160  gtk_widget_queue_draw (priv->widget);
1161 }
1162 
1163 static void
1164 gnc_plugin_page_owner_tree_cmd_new_invoice (GtkAction *action,
1165  GncPluginPageOwnerTree *page)
1166 {
1168  GncOwner current_owner;
1169  GtkWindow *parent;
1170 
1171  ENTER("action %p, page %p", action, page);
1172 
1173  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
1174  switch (priv->owner_type)
1175  {
1176  case GNC_OWNER_NONE :
1177  case GNC_OWNER_UNDEFINED :
1178  gncOwnerInitUndefined(&current_owner, NULL);
1179  break;
1180  case GNC_OWNER_CUSTOMER :
1181  {
1182  gncOwnerInitCustomer(&current_owner,
1184  break;
1185  }
1186  case GNC_OWNER_JOB :
1187  {
1188  gncOwnerInitJob(&current_owner,
1190  break;
1191  }
1192  case GNC_OWNER_VENDOR :
1193  {
1194  gncOwnerInitVendor(&current_owner,
1196  break;
1197  }
1198  case GNC_OWNER_EMPLOYEE :
1199  {
1200  gncOwnerInitEmployee(&current_owner,
1202  break;
1203  }
1204  }
1205 
1206  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page)));
1207  if (gncOwnerGetType(&current_owner) != GNC_OWNER_UNDEFINED)
1208  gnc_ui_invoice_new (parent, &current_owner, gnc_get_current_book ());
1209 
1210  LEAVE(" ");
1211 }
1212 
1213 static void
1214 gnc_plugin_page_owner_tree_cmd_owners_report (GtkAction *action,
1215  GncPluginPageOwnerTree *plugin_page)
1216 {
1218  int id;
1219 
1220  ENTER("(action %p, plugin_page %p)", action, plugin_page);
1221 
1222  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1223 
1224  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
1225  id = build_aging_report (priv->owner_type);
1226  if (id >= 0)
1227  {
1228  GncMainWindow *window;
1229  window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
1230  gnc_main_window_open_report(id, window);
1231  }
1232 
1233  LEAVE(" ");
1234 }
1235 
1236 static void
1237 gnc_plugin_page_owner_tree_cmd_owner_report (GtkAction *action,
1238  GncPluginPageOwnerTree *plugin_page)
1239 {
1240  GncOwner *current_owner;
1241  int id;
1242 
1243  ENTER("(action %p, plugin_page %p)", action, plugin_page);
1244 
1245  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1246 
1247  current_owner = gnc_plugin_page_owner_tree_get_current_owner (plugin_page);
1248  id = build_owner_report (current_owner, NULL);
1249  if (id >= 0)
1250  {
1251  GncMainWindow *window;
1252  window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
1253  gnc_main_window_open_report(id, window);
1254  }
1255 
1256  LEAVE(" ");
1257 }
1258 
1259 
1260 static void
1261 gnc_plugin_page_owner_tree_cmd_process_payment (GtkAction *action,
1262  GncPluginPageOwnerTree *plugin_page)
1263 {
1264  ENTER("(action %p, plugin_page %p)", action, plugin_page);
1265 
1266  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1267 
1268  gnc_ui_payment_new (GTK_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window),
1270  gnc_get_current_book ());
1271 
1272  LEAVE(" ");
1273 }
GtkWidget * gnc_plugin_page_get_window(GncPluginPage *page)
Retrieve a pointer to the GncMainWindow (GtkWindow) containing this page.
const gchar * tab_icon
The relative name of the icon that should be shown on the tab for this page.
GtkTreeView * gnc_tree_view_owner_new(GncOwnerType owner_type)
Create a new owner tree view for one type of owners.
gboolean(* focus_page_function)(GncPluginPage *plugin_page)
This function performs specific actions to set the focus on a specific widget.
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.
gboolean gnc_main_window_button_press_cb(GtkWidget *whatever, GdkEventButton *event, GncPluginPage *page)
Callback function invoked when the user clicks in the content of any Gnucash window.
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.
GtkTreeView implementation for gnucash owner tree.
utility functions for the GnuCash UI
GncPluginPage *(* recreate_page)(GtkWidget *window, GKeyFile *file, const gchar *group)
Create a new page based on the information saved during a previous instantiation of gnucash...
Functions that are supported by all types of windows.
A structure for defining alternate action names for use in the toolbar.
Definition: gnc-plugin.h:228
GncOwnerType owner_type
The owner type to show this action for.
GtkActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
Retrieve the GtkActionGroup object associated with this page.
GtkTreeViewColumn * gnc_tree_view_find_column_by_name(GncTreeView *view, const gchar *wanted)
Find a tree column given the "pref name" used with saved state.
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
This file contains the functions to present a dialog box with a list of object references and an expl...
void gncOwnerBeginEdit(GncOwner *owner)
These are convenience wrappers around gnc{Vendor,Customer,Job,Employee}* functions.
Definition: gncOwner.c:73
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
void(* destroy_widget)(GncPluginPage *plugin_page)
Function called to destroy the display widget for a particular type of plugin.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
The class data structure for a content plugin.
Functions providing a page which lists owners of one type.
Gobject helper routines.
Map actions to owners.
void gnc_plugin_page_disconnect_page_changed(GncPluginPage *page)
Disconnect the page_changed_id signal callback.
void gnc_plugin_init_short_names(GtkActionGroup *action_group, action_toolbar_labels *toolbar_labels)
Add "short" labels to existing actions.
Definition: gnc-plugin.c:234
const char * action_name
The name of the action.
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.
const gchar * plugin_name
The textual name of this plugin.
GtkWidget *(* create_widget)(GncPluginPage *plugin_page)
Function called to create the display widget for a particular type of plugin.
GncOwner * gnc_plugin_page_owner_tree_get_current_owner(GncPluginPageOwnerTree *page)
Given a pointer to an owner tree plugin page, return the selected owner (if any). ...
QofIdTypeConst gncOwnerTypeToQofIdType(GncOwnerType t)
Returns the QofIdType of the given GncOwnerType, or NULL if no suitable one exists.
Definition: gncOwner.c:236
gpointer gncOwnerGetUndefined(const GncOwner *owner)
If the given owner is of type GNC_OWNER_UNDEFINED, returns the undefined pointer, which is usually NU...
Definition: gncOwner.c:363
Gnome specific utility functions.
All type declarations for the whole Gnucash engine.
void(* save_page)(GncPluginPage *page, GKeyFile *file, const gchar *group)
Save enough information about this page so that it can be recreated next time the user starts gnucash...
GList * qof_instance_get_referring_object_list(const QofInstance *inst)
Returns a list of objects which refer to a specific object.
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
Definition: gncOwner.c:201
GncJob * gncOwnerGetJob(const GncOwner *owner)
If the given owner is of type GNC_OWNER_JOB, returns the pointer to the job object.
Definition: gncOwner.c:377
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
Definition: qofbook.cpp:580
void gnc_plugin_update_actions(GtkActionGroup *action_group, const gchar **action_names, const gchar *property_name, gboolean value)
Update a property on a set of existing GtkActions.
Definition: gnc-plugin.c:280
void gnc_plugin_page_inserted_cb(GncPluginPage *page, gpointer user_data)
Set up the page_changed callback for when the current page is changed.
void gnc_main_window_close_page(GncPluginPage *page)
Remove a data plugin page from a window and display the previous page.
Functions for adding plugins to a GnuCash window.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
GncVendor * gncOwnerGetVendor(const GncOwner *owner)
If the given owner is of type GNC_OWNER_VENDOR, returns the pointer to the vendor object...
Definition: gncOwner.c:384
GncCustomer * gncOwnerGetCustomer(const GncOwner *owner)
If the given owner is of type GNC_OWNER_CUSTOMER, returns the pointer to the customer object...
Definition: gncOwner.c:370
void gnc_plugin_page_add_book(GncPluginPage *page, QofBook *book)
Add a book reference to the specified page.
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...
GtkActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
Create the GtkActionGroup object associated with this page.
The instance data structure for a main window object.
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...
GncEmployee * gncOwnerGetEmployee(const GncOwner *owner)
If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object...
Definition: gncOwner.c:391
GncPluginPage * gnc_plugin_page_owner_tree_new(GncOwnerType owner_type)
Create a new "owner tree" plugin page.