GnuCash  5.6-150-g038405b370+
gnc-plugin-page-owner-tree.cpp
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 G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageOwnerTree, gnc_plugin_page_owner_tree, GNC_TYPE_PLUGIN_PAGE)
91 
92 #define GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(o) \
93  ((GncPluginPageOwnerTreePrivate*)gnc_plugin_page_owner_tree_get_instance_private((GncPluginPageOwnerTree*)o))
94 
95 /************************************************************
96  * Prototypes *
97  ************************************************************/
98 /* Plugin Actions */
99 static void gnc_plugin_page_owner_tree_finalize (GObject *object);
100 static void gnc_plugin_page_owner_tree_selected (GObject *object, gpointer user_data);
101 
102 static GtkWidget *gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page);
103 static void gnc_plugin_page_owner_tree_destroy_widget (GncPluginPage *plugin_page);
104 static void gnc_plugin_page_owner_tree_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
105 static GncPluginPage *gnc_plugin_page_owner_tree_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
106 static void set_menu_and_toolbar_qualifier (GncPluginPage *plugin_page);
107 
108 /* Callbacks */
109 static gboolean gnc_plugin_page_owner_tree_button_press_cb (GtkWidget *widget,
110  GdkEventButton *event,
111  GncPluginPage *page);
112 static void gnc_plugin_page_owner_tree_double_click_cb (GtkTreeView *treeview,
113  GtkTreePath *path,
114  GtkTreeViewColumn *col,
115  GncPluginPageOwnerTree *page);
116 
117 static void gnc_plugin_page_owner_tree_selection_changed_cb (GtkTreeSelection *selection,
118  GncPluginPageOwnerTree *page);
119 
120 /* Command callbacks */
121 static void gnc_plugin_page_owner_tree_cmd_new_owner (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
122 static void gnc_plugin_page_owner_tree_cmd_edit_owner (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
123 #if 0 /* Disabled due to crash */
124 static void gnc_plugin_page_owner_tree_cmd_delete_owner (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
125 #endif
126 static void gnc_plugin_page_owner_tree_cmd_view_filter_by (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
127 static void gnc_plugin_page_owner_tree_cmd_refresh (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
128 static void gnc_plugin_page_owner_tree_cmd_new_invoice (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
129 static void gnc_plugin_page_owner_tree_cmd_owners_report (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
130 static void gnc_plugin_page_owner_tree_cmd_owner_report (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
131 static void gnc_plugin_page_owner_tree_cmd_process_payment (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
132 static void gnc_plugin_page_owner_tree_cmd_edit_tax (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
133 static void gnc_plugin_page_owner_tree_cmd_search_invoices (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
134 
135 static guint plugin_page_signals[LAST_SIGNAL] = { 0 };
136 
137 
138 static GActionEntry gnc_plugin_page_owner_tree_actions [] =
139 {
140  { "OTEditVendorAction", gnc_plugin_page_owner_tree_cmd_edit_owner, NULL, NULL, NULL },
141  { "OTEditCustomerAction", gnc_plugin_page_owner_tree_cmd_edit_owner, NULL, NULL, NULL },
142  { "OTEditEmployeeAction", gnc_plugin_page_owner_tree_cmd_edit_owner, NULL, NULL, NULL },
143  { "OTNewVendorAction", gnc_plugin_page_owner_tree_cmd_new_owner, NULL, NULL, NULL },
144  { "OTNewCustomerAction", gnc_plugin_page_owner_tree_cmd_new_owner, NULL, NULL, NULL },
145  { "OTNewEmployeeAction", gnc_plugin_page_owner_tree_cmd_new_owner, NULL, NULL, NULL },
146 
147 #if 0 /* Disabled due to crash */
148  { "EditDeleteOwnerAction", gnc_plugin_page_owner_tree_cmd_delete_owner, NULL, NULL, NULL },
149 #endif /* Disabled due to crash */
150 
151  { "ViewFilterByAction", gnc_plugin_page_owner_tree_cmd_view_filter_by, NULL, NULL, NULL },
152  { "ViewRefreshAction", gnc_plugin_page_owner_tree_cmd_refresh, NULL, NULL, NULL },
153  { "EditTaxOptionsAction", gnc_plugin_page_owner_tree_cmd_edit_tax, NULL, NULL, NULL },
154  { "OTNewBillAction", gnc_plugin_page_owner_tree_cmd_new_invoice, NULL, NULL, NULL },
155  { "OTNewInvoiceAction", gnc_plugin_page_owner_tree_cmd_new_invoice, NULL, NULL, NULL },
156  { "OTNewVoucherAction", gnc_plugin_page_owner_tree_cmd_new_invoice, NULL, NULL, NULL },
157  { "OTVendorListingReportAction", gnc_plugin_page_owner_tree_cmd_owners_report, NULL, NULL, NULL },
158  { "OTCustomerListingReportAction", gnc_plugin_page_owner_tree_cmd_owners_report, NULL, NULL, NULL },
159  { "OTVendorReportAction", gnc_plugin_page_owner_tree_cmd_owner_report, NULL, NULL, NULL },
160  { "OTCustomerReportAction", gnc_plugin_page_owner_tree_cmd_owner_report, NULL, NULL, NULL },
161  { "OTEmployeeReportAction", gnc_plugin_page_owner_tree_cmd_owner_report, NULL, NULL, NULL },
162  { "OTProcessPaymentAction", gnc_plugin_page_owner_tree_cmd_process_payment, NULL, NULL, NULL },
163  { "OTSearchInvoicesAction", gnc_plugin_page_owner_tree_cmd_search_invoices, NULL, NULL, NULL },
164 };
166 static guint gnc_plugin_page_owner_tree_n_actions = G_N_ELEMENTS(gnc_plugin_page_owner_tree_actions);
167 
169 static const gchar *gnc_plugin_load_ui_items [] =
170 {
171  "FilePlaceholder3",
172  "EditPlaceholder2",
173  "EditPlaceholder3",
174  "EditPlaceholder5",
175  "ViewPlaceholder1",
176  "ViewPlaceholder4",
177  "ReportsPlaceholder1",
178  NULL,
179 };
180 
183 static const gchar *actions_requiring_owner_rw[] =
184 {
185  "OTEditVendorAction",
186  "OTEditCustomerAction",
187  "OTEditEmployeeAction",
188  "OTProcessPaymentAction",
189 /* FIXME disabled due to crash "EditDeleteOwnerAction", */
190  NULL
191 };
192 
195 static const gchar *actions_requiring_owner_always[] =
196 {
197  "OTVendorReportAction",
198  "OTCustomerReportAction",
199  "OTEmployeeReportAction",
200  "OTProcessPaymentAction",
201  NULL
202 };
203 
204 /* This is the list of actions which are switched inactive in a read-only book. */
205 static const gchar* readonly_inactive_actions[] =
206 {
207  "OTNewVendorAction",
208  "OTNewCustomerAction",
209  "OTNewEmployeeAction",
210  "OTNewBillAction",
211  "OTNewInvoiceAction",
212  "OTNewVoucherAction",
213  "OTProcessPaymentAction",
214  NULL
215 };
216 
217 
219 static GncToolBarShortNames toolbar_labels[] =
220 {
221  { "OTEditVendorAction", N_("Edit") },
222  { "OTEditCustomerAction", N_("Edit") },
223  { "OTEditEmployeeAction", N_("Edit") },
224  { "OTNewVendorAction", N_("New") },
225  { "OTNewCustomerAction", N_("New") },
226  { "OTNewEmployeeAction", N_("New") },
227  { "OTNewBillAction", N_("New Bill") },
228  { "OTNewInvoiceAction", N_("New Invoice") },
229  { "OTNewVoucherAction", N_("New Voucher") },
230  { "OTVendorListingReportAction", N_("Vendor Listing") },
231  { "OTCustomerListingReportAction", N_("Customer Listing") },
232  { "OTProcessPaymentAction", N_("Process Payment") },
233 /* FIXME disable due to crash { "EditDeleteOwnerAction", N_("Delete") },*/
234  { NULL, NULL },
235 };
236 
240 typedef struct
241 {
243  const char *action_name;
245  GncOwnerType owner_type;
247 
249 gnc_plugin_page_owner_tree_new (GncOwnerType owner_type)
250 {
251  GncPluginPageOwnerTree *plugin_page;
253  const GList *item;
254 
255  g_return_val_if_fail( (owner_type != GNC_OWNER_UNDEFINED)
256  && (owner_type != GNC_OWNER_NONE), NULL);
257  ENTER(" ");
258 
259  /* Is there an existing page? */
260  item = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_OWNER_TREE_NAME);
261  for ( ; item; item = g_list_next(item))
262  {
263  plugin_page = (GncPluginPageOwnerTree *)item->data;
264  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
265  if (priv->owner_type == owner_type)
266  {
267  LEAVE("existing %s tree page %p", gncOwnerTypeToQofIdType(owner_type), plugin_page);
268  return GNC_PLUGIN_PAGE(plugin_page);
269  }
270  }
271 
272  plugin_page = GNC_PLUGIN_PAGE_OWNER_TREE(g_object_new(GNC_TYPE_PLUGIN_PAGE_OWNER_TREE, nullptr));
273 
274  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
275  priv->owner_type = owner_type;
276 
277  LEAVE("new %s tree page %p", gncOwnerTypeToQofIdType(owner_type), plugin_page);
278  return GNC_PLUGIN_PAGE(plugin_page);
279 }
280 
285 static gboolean
286 gnc_plugin_page_owner_focus_widget (GncPluginPage *owner_plugin_page)
287 {
288  if (GNC_IS_PLUGIN_PAGE_OWNER_TREE(owner_plugin_page))
289  {
290  GncPluginPageOwnerTreePrivate *priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(owner_plugin_page);
291  GtkTreeView *tree_view = priv->tree_view;
292 
293  /* Disable the Transaction Menu */
294  GAction *action = gnc_main_window_find_action (GNC_MAIN_WINDOW(owner_plugin_page->window), "TransactionAction");
295  g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
296  /* Disable the Schedule menu */
297  action = gnc_main_window_find_action (GNC_MAIN_WINDOW(owner_plugin_page->window), "ScheduledAction");
298  g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
299  /* Disable the FilePrintAction */
300  action = gnc_main_window_find_action (GNC_MAIN_WINDOW(owner_plugin_page->window), "FilePrintAction");
301  g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
302 
303  set_menu_and_toolbar_qualifier (owner_plugin_page);
304 
305  gnc_main_window_update_menu_and_toolbar (GNC_MAIN_WINDOW(owner_plugin_page->window),
306  owner_plugin_page,
307  gnc_plugin_load_ui_items);
308 
309  // setup any short toolbar names
310  gnc_main_window_init_short_names (GNC_MAIN_WINDOW(owner_plugin_page->window), toolbar_labels);
311 
312  if (GTK_IS_TREE_VIEW(tree_view))
313  {
314  if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
315  gtk_widget_grab_focus (GTK_WIDGET(tree_view));
316  }
317  }
318  return FALSE;
319 }
320 
321 static void
322 gnc_plugin_page_owner_tree_class_init (GncPluginPageOwnerTreeClass *klass)
323 {
324  GObjectClass *object_class = G_OBJECT_CLASS (klass);
325  GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
326 
327  object_class->finalize = gnc_plugin_page_owner_tree_finalize;
328 
329  gnc_plugin_class->tab_icon = GNC_ICON_ACCOUNT;
330  gnc_plugin_class->plugin_name = GNC_PLUGIN_PAGE_OWNER_TREE_NAME;
331  gnc_plugin_class->create_widget = gnc_plugin_page_owner_tree_create_widget;
332  gnc_plugin_class->destroy_widget = gnc_plugin_page_owner_tree_destroy_widget;
333  gnc_plugin_class->save_page = gnc_plugin_page_owner_tree_save_page;
334  gnc_plugin_class->recreate_page = gnc_plugin_page_owner_tree_recreate_page;
335  gnc_plugin_class->focus_page_function = gnc_plugin_page_owner_focus_widget;
336 
337  plugin_page_signals[OWNER_SELECTED] =
338  g_signal_new ("owner_selected",
339  G_OBJECT_CLASS_TYPE (object_class),
340  G_SIGNAL_RUN_FIRST,
341  G_STRUCT_OFFSET (GncPluginPageOwnerTreeClass, owner_selected),
342  NULL, NULL,
343  g_cclosure_marshal_VOID__POINTER,
344  G_TYPE_NONE, 1,
345  G_TYPE_POINTER);
346 }
347 
348 static void
349 gnc_plugin_page_owner_tree_init (GncPluginPageOwnerTree *plugin_page)
350 {
351  GSimpleActionGroup *simple_action_group;
353  GncPluginPage *parent;
354 
355  ENTER("page %p", plugin_page);
356  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
357 
358  /* Init parent declared variables */
359  parent = GNC_PLUGIN_PAGE(plugin_page);
360  g_object_set(G_OBJECT(plugin_page),
361  "page-name", _("Owners"),
362  "ui-description", "gnc-plugin-page-owner-tree.ui",
363  NULL);
364  g_signal_connect (G_OBJECT (plugin_page), "selected",
365  G_CALLBACK (gnc_plugin_page_owner_tree_selected), plugin_page);
366 
367  /* change me when the system supports multiple books */
368  gnc_plugin_page_add_book (parent, gnc_get_current_book());
369 
370  /* Create menu and toolbar information */
371  simple_action_group = gnc_plugin_page_create_action_group (parent, "GncPluginPageOwnerTreeActions");
372  g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
373  gnc_plugin_page_owner_tree_actions,
374  gnc_plugin_page_owner_tree_n_actions,
375  plugin_page);
376 
377  /* Init filter */
378  priv->fd.show_inactive = TRUE;
379  priv->fd.show_zero_total = TRUE;
380 
381  LEAVE("page %p, priv %p, action group %p",
382  plugin_page, priv, simple_action_group);
383 }
384 
385 static void
386 gnc_plugin_page_owner_tree_finalize (GObject *object)
387 {
390 
391  ENTER("object %p", object);
392  page = GNC_PLUGIN_PAGE_OWNER_TREE (object);
393  g_return_if_fail (GNC_IS_PLUGIN_PAGE_OWNER_TREE (page));
394  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
395  g_return_if_fail (priv != NULL);
396 
397  G_OBJECT_CLASS (gnc_plugin_page_owner_tree_parent_class)->finalize (object);
398  LEAVE(" ");
399 }
400 
401 static void
402 update_inactive_actions(GncPluginPage *plugin_page)
403 {
404  GSimpleActionGroup *simple_action_group;
405  gboolean is_sensitive = !qof_book_is_readonly(gnc_get_current_book());
406 
407  // We are readonly - so we have to switch particular actions to inactive.
408  g_return_if_fail(plugin_page);
409  g_return_if_fail(GNC_IS_PLUGIN_PAGE(plugin_page));
410 
411  /* Get the action group */
412  simple_action_group = gnc_plugin_page_get_action_group (plugin_page);
413  g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP(simple_action_group));
414 
415  /* Set the action's sensitivity */
416  gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group), readonly_inactive_actions,
417  is_sensitive);
418 }
419 
420 static void
421 set_menu_and_toolbar_qualifier (GncPluginPage *plugin_page)
422 {
423  GncPluginPageOwnerTree *page = GNC_PLUGIN_PAGE_OWNER_TREE(plugin_page);
425 
426  g_return_if_fail (GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
427 
428  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
429 
430  if (priv->owner_type == GNC_OWNER_CUSTOMER)
431  gnc_plugin_page_set_menu_qualifier (plugin_page, "c");
432  else if (priv->owner_type == GNC_OWNER_VENDOR)
433  gnc_plugin_page_set_menu_qualifier (plugin_page, "v");
434  else if (priv->owner_type == GNC_OWNER_EMPLOYEE)
435  gnc_plugin_page_set_menu_qualifier (plugin_page, "e");
436  else
437  gnc_plugin_page_set_menu_qualifier (plugin_page, NULL);
438 }
439 
440 static void
441 gnc_plugin_page_owner_tree_selected (GObject *object, gpointer user_data)
442 {
443  GncPluginPage *page = GNC_PLUGIN_PAGE (object);
444  g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
445  update_inactive_actions(page);
446 }
447 
448 
449 GncOwner *
451 {
453  GncOwner *owner;
454 
455  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
456  ENTER("page %p (tree view %p)", page, priv->tree_view);
457  owner = gnc_tree_view_owner_get_selected_owner (GNC_TREE_VIEW_OWNER(priv->tree_view));
458  if (owner == NULL)
459  {
460  LEAVE("no owner");
461  return NULL;
462  }
463 
464  LEAVE("owner %p", owner);
465  return owner;
466 }
467 
468 
469 /* Virtual Functions */
470 
471 static void
472 gnc_plugin_page_owner_refresh_cb (GHashTable *changes, gpointer user_data)
473 {
474  auto page = GNC_PLUGIN_PAGE_OWNER_TREE(user_data);
476 
477  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
478 
479  /* We're only looking for forced updates here. */
480  if (changes)
481  return;
482 
483  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
484  gtk_widget_queue_draw(priv->widget);
485 }
486 
487 static void
488 gnc_plugin_page_owner_tree_close_cb (gpointer user_data)
489 {
490  GncPluginPage *plugin_page;
491 
492  plugin_page = GNC_PLUGIN_PAGE(user_data);
493  gnc_main_window_close_page(plugin_page);
494 }
495 
496 static GtkWidget *
497 gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page)
498 {
501  GtkTreeSelection *selection;
502  GtkTreeView *tree_view;
503  GtkWidget *scrolled_window;
504  GtkTreeViewColumn *col;
505  const gchar *state_section = NULL;
506  const gchar* label = "";
507  const gchar *style_label = NULL;
508 
509  ENTER("page %p", plugin_page);
510  page = GNC_PLUGIN_PAGE_OWNER_TREE (plugin_page);
511  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
512  if (priv->widget != NULL)
513  {
514  LEAVE("widget = %p", priv->widget);
515  return priv->widget;
516  }
517 
518  priv->widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
519  gtk_box_set_homogeneous (GTK_BOX (priv->widget), FALSE);
520  gtk_widget_show (priv->widget);
521 
522  // Set the name for this widget so it can be easily manipulated with css
523  gtk_widget_set_name (GTK_WIDGET(priv->widget), "gnc-id-owner-page");
524 
525  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
526  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
527  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
528  gtk_widget_show (scrolled_window);
529  gtk_box_pack_start (GTK_BOX (priv->widget), scrolled_window,
530  TRUE, TRUE, 0);
531 
532  tree_view = gnc_tree_view_owner_new(priv->owner_type);
533 
534  /* Show default columns */
536  GNC_TREE_VIEW(tree_view), GNC_OWNER_TREE_ID_COL);
537  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
539  GNC_TREE_VIEW(tree_view), GNC_OWNER_TREE_ADDRESS_1_COL);
540  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
542  GNC_TREE_VIEW(tree_view), GNC_OWNER_TREE_ADDRESS_2_COL);
543  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
545  GNC_TREE_VIEW(tree_view), GNC_OWNER_TREE_PHONE_COL);
546  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
547  gnc_tree_view_configure_columns(GNC_TREE_VIEW(tree_view));
548 
549  switch (priv->owner_type)
550  {
551  case GNC_OWNER_NONE :
552  case GNC_OWNER_UNDEFINED :
553  PWARN("missing owner_type");
554  label = _("Unknown");
555  style_label = "gnc-class-unknown";
556  break;
557  case GNC_OWNER_CUSTOMER :
558  label = _("Customers");
559  state_section = "Customers Overview";
560  style_label = "gnc-class-customers";
561  break;
562  case GNC_OWNER_JOB :
563  label = _("Jobs");
564  state_section = "Jobs Overview";
565  style_label = "gnc-class-jobs";
566  break;
567  case GNC_OWNER_VENDOR :
568  label = _("Vendors");
569  state_section = "Vendors Overview";
570  style_label = "gnc-class-vendors";
571  break;
572  case GNC_OWNER_EMPLOYEE :
573  label = _("Employees");
574  state_section = "Employees Overview";
575  style_label = "gnc-class-employees";
576  break;
577  }
578 
579  // Set a secondary style context for this page so it can be easily manipulated with css
580  gnc_widget_style_context_add_class (GTK_WIDGET(priv->widget), style_label);
581 
582  g_object_set(G_OBJECT(tree_view), "state-section", state_section,
583  "show-column-menu", TRUE,
584  NULL);
585 
586  g_object_set(G_OBJECT(plugin_page), "page-name", label, NULL);
587 
588  priv->tree_view = tree_view;
589  selection = gtk_tree_view_get_selection(tree_view);
590  g_signal_connect (G_OBJECT (selection), "changed",
591  G_CALLBACK (gnc_plugin_page_owner_tree_selection_changed_cb), page);
592  g_signal_connect (G_OBJECT (tree_view), "button-press-event",
593  G_CALLBACK (gnc_plugin_page_owner_tree_button_press_cb), page);
594  g_signal_connect (G_OBJECT (tree_view), "row-activated",
595  G_CALLBACK (gnc_plugin_page_owner_tree_double_click_cb), page);
596 
597  gtk_tree_view_set_headers_visible(tree_view, TRUE);
598  gnc_plugin_page_owner_tree_selection_changed_cb (NULL, page);
599  gtk_widget_show (GTK_WIDGET (tree_view));
600  gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET(tree_view));
601 
602  priv->fd.tree_view = GNC_TREE_VIEW_OWNER(priv->tree_view);
604  GNC_TREE_VIEW_OWNER(tree_view),
606 
607  priv->component_id =
608  gnc_register_gui_component(PLUGIN_PAGE_ACCT_TREE_CM_CLASS,
609  gnc_plugin_page_owner_refresh_cb,
610  gnc_plugin_page_owner_tree_close_cb,
611  page);
612  gnc_gui_component_set_session (priv->component_id,
613  gnc_get_current_session());
614 
615  g_signal_connect (G_OBJECT(plugin_page), "inserted",
616  G_CALLBACK(gnc_plugin_page_inserted_cb),
617  NULL);
618 
619  set_menu_and_toolbar_qualifier (plugin_page);
620 
621  LEAVE("widget = %p", priv->widget);
622  return priv->widget;
623 }
624 
625 static void
626 gnc_plugin_page_owner_tree_destroy_widget (GncPluginPage *plugin_page)
627 {
630 
631  ENTER("page %p", plugin_page);
632  page = GNC_PLUGIN_PAGE_OWNER_TREE (plugin_page);
633  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
634 
635  // Remove the page_changed signal callback
636  gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
637 
638  // Remove the page focus idle function if present
639  g_idle_remove_by_data (plugin_page);
640 
641  if (priv->widget)
642  {
643  g_object_unref(G_OBJECT(priv->widget));
644  priv->widget = NULL;
645  }
646 
647  if (priv->component_id)
648  {
649  gnc_unregister_gui_component(priv->component_id);
650  priv->component_id = 0;
651  }
652 
653  LEAVE("widget destroyed");
654 }
655 
656 #define OWNER_TYPE_LABEL "OwnerType"
657 
667 static void
668 gnc_plugin_page_owner_tree_save_page (GncPluginPage *plugin_page,
669  GKeyFile *key_file,
670  const gchar *group_name)
671 {
672  GncPluginPageOwnerTree *owner_page;
674 
675  g_return_if_fail (GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
676  g_return_if_fail (key_file != NULL);
677  g_return_if_fail (group_name != NULL);
678 
679  ENTER("page %p, key_file %p, group_name %s", plugin_page, key_file,
680  group_name);
681 
682  owner_page = GNC_PLUGIN_PAGE_OWNER_TREE(plugin_page);
683  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(owner_page);
684 
685  g_key_file_set_integer(key_file, group_name, OWNER_TYPE_LABEL,
686  priv->owner_type);
687 
688  gnc_tree_view_owner_save(GNC_TREE_VIEW_OWNER(priv->tree_view),
689  &priv->fd, key_file, group_name);
690  LEAVE(" ");
691 }
692 
693 
694 
704 static GncPluginPage *
705 gnc_plugin_page_owner_tree_recreate_page (GtkWidget *window,
706  GKeyFile *key_file,
707  const gchar *group_name)
708 {
709  GncPluginPageOwnerTree *owner_page;
711  GncPluginPage *page;
712  GncOwnerType owner_type;
713 
714  g_return_val_if_fail(key_file, NULL);
715  g_return_val_if_fail(group_name, NULL);
716  ENTER("key_file %p, group_name %s", key_file, group_name);
717 
718  /* Create the new page. */
719  owner_type = static_cast<GncOwnerType>(g_key_file_get_integer(key_file, group_name, OWNER_TYPE_LABEL, NULL));
720  page = gnc_plugin_page_owner_tree_new(owner_type);
721  owner_page = GNC_PLUGIN_PAGE_OWNER_TREE(page);
722  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(owner_page);
723 
724  /* Install it now so we can then manipulate the created widget */
725  gnc_main_window_open_page(GNC_MAIN_WINDOW(window), page);
726 
727  gnc_tree_view_owner_restore(GNC_TREE_VIEW_OWNER(priv->tree_view),
728  &priv->fd, key_file, group_name, owner_type);
729  LEAVE(" ");
730  return page;
731 }
732 
733 /* Wrapper function to open the proper edit dialog, depending on the owner type */
734 static void gnc_ui_owner_edit (GtkWindow *parent, GncOwner *owner)
735 {
736  if (NULL == owner) return;
737 
738  switch (owner->type)
739  {
740  case GNC_OWNER_NONE :
741  case GNC_OWNER_UNDEFINED :
742  break;
743  case GNC_OWNER_CUSTOMER :
744  {
745  gnc_ui_customer_edit (parent, owner->owner.customer);
746  break;
747  }
748  case GNC_OWNER_JOB :
749  {
750  gnc_ui_job_edit (parent, owner->owner.job);
751  break;
752  }
753  case GNC_OWNER_VENDOR :
754  {
755  gnc_ui_vendor_edit (parent, owner->owner.vendor);
756  break;
757  }
758  case GNC_OWNER_EMPLOYEE :
759  {
760  gnc_ui_employee_edit (parent, owner->owner.employee);
761  break;
762  }
763  }
764 }
765 
766 
767 /* Callbacks */
768 
776 static gboolean
777 gnc_plugin_page_owner_tree_button_press_cb (GtkWidget *widget,
778  GdkEventButton *event,
779  GncPluginPage *page)
780 {
781  g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
782 
783  ENTER("widget %p, event %p, page %p", widget, event, page);
784  gnc_main_window_button_press_cb(widget, event, page);
785  LEAVE(" ");
786 
787  /* Always return FALSE. This will let the tree view callback run as
788  * well which will select the item under the cursor. By the time
789  * the user sees the menu both callbacks will have run and the menu
790  * actions will operate on the just-selected owner. */
791  return FALSE;
792 }
793 
794 static void
795 gnc_plugin_page_owner_tree_double_click_cb (GtkTreeView *treeview,
796  GtkTreePath *path,
797  GtkTreeViewColumn *col,
799 {
800  gnc_plugin_page_owner_tree_cmd_owner_report (NULL, NULL, (gpointer*)page);
801 }
802 
803 static void
804 gnc_plugin_page_owner_tree_selection_changed_cb (GtkTreeSelection *selection,
806 {
807  GSimpleActionGroup *simple_action_group;
808  GtkTreeView *view;
809  GncOwner *owner = NULL;
810  gboolean sensitive;
811  gboolean is_readwrite = !qof_book_is_readonly(gnc_get_current_book());
812 
813  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
814 
815  if (!selection)
816  {
817  sensitive = FALSE;
818  }
819  else
820  {
821  g_return_if_fail(GTK_IS_TREE_SELECTION(selection));
822  view = gtk_tree_selection_get_tree_view (selection);
823  owner = gnc_tree_view_owner_get_selected_owner (GNC_TREE_VIEW_OWNER(view));
824  sensitive = (owner != NULL);
825  }
826 
827  simple_action_group = gnc_plugin_page_get_action_group (GNC_PLUGIN_PAGE(page));
828  gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group), actions_requiring_owner_always,
829  sensitive);
830  gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group), actions_requiring_owner_rw,
831  sensitive && is_readwrite);
832  g_signal_emit (page, plugin_page_signals[OWNER_SELECTED], 0, owner);
833 }
834 
835 /******************************************************************/
836 /* Report helper functions */
837 /******************************************************************/
838 
839 static int
840 build_aging_report (GncOwnerType owner_type)
841 {
842  const gchar *report_name = NULL;
843  const gchar *report_title = NULL;
844  SCM args;
845  SCM func;
846  SCM arg;
847 
848  args = SCM_EOL;
849 
850  switch (owner_type)
851  {
852  case GNC_OWNER_NONE :
853  case GNC_OWNER_UNDEFINED :
854  case GNC_OWNER_EMPLOYEE :
855  case GNC_OWNER_JOB :
856  {
857  return -1;
858  }
859  case GNC_OWNER_VENDOR :
860  {
861  report_name = "gnc:payables-report-create";
862  report_title = _("Vendor Listing");
863  break;
864  }
865  case GNC_OWNER_CUSTOMER :
866  {
867  report_name = "gnc:receivables-report-create";
868  report_title = _("Customer Listing");
869  break;
870  }
871  }
872 
873  /* Find report generator function in guile */
874  func = scm_c_eval_string (report_name);
875  g_return_val_if_fail (scm_is_procedure (func), -1);
876 
877  /* Option Show zero's ? - Yes for the listing report */
878  arg = SCM_BOOL_T;
879  args = scm_cons (arg, args);
880  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
881 
882  /* Option Report title */
883  arg = scm_from_utf8_string (report_title);
884  args = scm_cons (arg, args);
885 
886  /* Option Account - Using False to select default account
887  *
888  * XXX I'm not sure if it would make sense to use another
889  * account than default */
890  arg = SCM_BOOL_F;
891  args = scm_cons (arg, args);
892  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
893 
894 
895  /* Apply the function to the args */
896  arg = scm_apply (func, args, SCM_EOL);
897  g_return_val_if_fail (scm_is_exact (arg), -1);
898 
899  return scm_to_int (arg);
900 }
901 
902 static int build_owner_report (GncOwner *owner, Account *acc)
903 {
904  SCM args;
905  SCM func;
906  SCM arg;
907 
908  g_return_val_if_fail (owner, -1);
909 
910  args = SCM_EOL;
911 
912  func = scm_c_eval_string ("gnc:owner-report-create-with-enddate");
913  g_return_val_if_fail (scm_is_procedure (func), -1);
914 
915  args = scm_cons (SCM_BOOL_F, args); /* enddate is #f */
916 
917  if (acc)
918  {
919  swig_type_info * qtype = SWIG_TypeQuery("_p_Account");
920  g_return_val_if_fail (qtype, -1);
921 
922  arg = SWIG_NewPointerObj(acc, qtype, 0);
923  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
924  args = scm_cons (arg, args);
925  }
926  else
927  {
928  args = scm_cons (SCM_BOOL_F, args);
929  }
930 
931  swig_type_info * qtype = SWIG_TypeQuery("_p__gncOwner");
932  g_return_val_if_fail (qtype, -1);
933 
934  arg = SWIG_NewPointerObj(owner, qtype, 0);
935 
936  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
937  args = scm_cons (arg, args);
938 
939  /* Apply the function to the args */
940  arg = scm_apply (func, args, SCM_EOL);
941  g_return_val_if_fail (scm_is_exact (arg), -1);
942  return scm_to_int (arg);
943 }
944 
945 
946 /************************************************************/
947 /* Command callbacks */
948 /************************************************************/
949 
950 static void
951 gnc_plugin_page_owner_tree_cmd_new_owner (GSimpleAction *simple,
952  GVariant *parameter,
953  gpointer user_data)
954 
955 {
956  auto page = GNC_PLUGIN_PAGE_OWNER_TREE (user_data);
958  GtkWindow *parent;
959 
960  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(page));
961 
962  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE (page);
963  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page)));
964 
965  switch (priv->owner_type)
966  {
967  case GNC_OWNER_NONE :
968  case GNC_OWNER_UNDEFINED :
969  break;
970  case GNC_OWNER_CUSTOMER :
971  {
972  gnc_ui_customer_new (parent, gnc_get_current_book ());
973  break;
974  }
975  case GNC_OWNER_JOB :
976  {
977  /* XXX currently not properly implemented, so disabled for now
978  gnc_ui_job_new (owner, gnc_get_current_book ()); */
979  break;
980  }
981  case GNC_OWNER_VENDOR :
982  {
983  gnc_ui_vendor_new (parent, gnc_get_current_book ());
984  break;
985  }
986  case GNC_OWNER_EMPLOYEE :
987  {
988  gnc_ui_employee_new (parent, gnc_get_current_book ());
989  break;
990  }
991  }
992 }
993 
994 static void
995 gnc_plugin_page_owner_tree_cmd_edit_owner (GSimpleAction *simple,
996  GVariant *parameter,
997  gpointer user_data)
998 
999 {
1000  auto page = GNC_PLUGIN_PAGE_OWNER_TREE (user_data);
1001  GtkWindow *parent;
1003  if (NULL == owner) return;
1004 
1005  ENTER("action %p, page %p", simple, page);
1006 
1007  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page)));
1008  gnc_ui_owner_edit (parent, owner);
1009 
1010  LEAVE(" ");
1011 }
1012 
1013 static void
1014 gnc_plugin_page_owner_tree_cmd_search_invoices (GSimpleAction *simple,
1015  GVariant *parameter,
1016  gpointer user_data)
1017 
1018 {
1019  auto page = GNC_PLUGIN_PAGE_OWNER_TREE (user_data);
1020  GtkWindow *parent;
1022  if (NULL == owner) return;
1023 
1024  ENTER("action %p, page %p", simple, page);
1025 
1026  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page)));
1027 
1028  gnc_invoice_search (parent, NULL, owner, gnc_get_current_book ());
1029 
1030  LEAVE(" ");
1031 }
1032 
1033 
1034 #if 0 /* Disabled due to crash */
1035 static void
1036 gnc_plugin_page_owner_tree_cmd_delete_owner (GSimpleAction *simple,
1037  GVariant *parameter,
1038  gpointer user_data)
1039 
1040 {
1041  auto page = GNC_PLUGIN_PAGE_OWNER_TREE (user_data);
1043  gchar *owner_name;
1044  GtkWidget *window;
1045  GtkWidget *dialog = NULL;
1046  gint response;
1047  GList* list;
1048 
1049  if (NULL == owner) return;
1050 
1051  /* If the owner has objects referring to it, show the list - the owner can't be deleted until these
1052  references are dealt with. */
1053  list = qof_instance_get_referring_object_list(QOF_INSTANCE(gncOwnerGetUndefined(owner)));
1054  if (list != NULL)
1055  {
1056 #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"
1057 
1058  gnc_ui_object_references_show( _(EXPLANATION), list);
1059  g_list_free(list);
1060  return;
1061  }
1062 
1063  window = gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(page));
1064  owner_name = g_strdup (gncOwnerGetName(owner));
1065  if (!owner_name)
1066  {
1067  owner_name = g_strdup (_("(no name)"));
1068  }
1069 
1070  /*
1071  * Present a message to the user which specifies what will be
1072  * deleted, then ask for verification.
1073  */
1074  {
1075  char *message = g_strdup_printf(_("The owner %s will be deleted.\nAre you sure you want to do this?"), owner_name);
1076 
1077  dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1078  GTK_DIALOG_DESTROY_WITH_PARENT,
1079  GTK_MESSAGE_QUESTION,
1080  GTK_BUTTONS_NONE,
1081  "%s", message);
1082  g_free(message);
1083  gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1084  _("_Cancel"), GTK_RESPONSE_CANCEL,
1085  _("_Delete"), GTK_RESPONSE_ACCEPT,
1086  (gchar *)NULL);
1087  gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
1088  response = gtk_dialog_run(GTK_DIALOG(dialog));
1089  gtk_widget_destroy(dialog);
1090 
1091  if (GTK_RESPONSE_ACCEPT == response)
1092  {
1093  /* FIXME The code below results in a crash.
1094  * The corresponding menu item/toolbar button is disabled until this is fixed. */
1095  gnc_set_busy_cursor(NULL, TRUE);
1096  gnc_suspend_gui_refresh ();
1097  gncOwnerBeginEdit (owner);
1098  gncOwnerDestroy (owner);
1099  gnc_resume_gui_refresh ();
1100  gnc_unset_busy_cursor(NULL);
1101  }
1102  }
1103  g_free(owner_name);
1104 }
1105 #endif /* Disabled due to crash */
1106 
1107 /*********************/
1108 
1109 static void
1110 gnc_plugin_page_owner_tree_cmd_view_filter_by (GSimpleAction *simple,
1111  GVariant *parameter,
1112  gpointer user_data)
1113 
1114 {
1115  auto plugin_page = GNC_PLUGIN_PAGE_OWNER_TREE(user_data);
1117 
1118  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1119  ENTER("(action %p, page %p)", simple, plugin_page);
1120 
1121  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
1122  owner_filter_dialog_create(&priv->fd, GNC_PLUGIN_PAGE(plugin_page));
1123  LEAVE(" ");
1124 }
1125 
1126 static void
1127 gnc_plugin_page_owner_tree_cmd_refresh (GSimpleAction *simple,
1128  GVariant *parameter,
1129  gpointer user_data)
1130 
1131 {
1132  auto plugin_page = GNC_PLUGIN_PAGE_OWNER_TREE(user_data);
1134 
1135  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1136 
1137  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
1138  gtk_widget_queue_draw (priv->widget);
1139 }
1140 
1141 static void
1142 gnc_plugin_page_owner_tree_cmd_edit_tax (GSimpleAction *simple,
1143  GVariant *parameter,
1144  gpointer user_data)
1145 {
1146  auto plugin_page = GNC_PLUGIN_PAGE_OWNER_TREE(user_data);
1147  GtkWidget *parent;
1148 
1149  g_return_if_fail (GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1150 
1151  parent = GTK_WIDGET(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
1152 
1153  gnc_tax_info_dialog (parent, NULL);
1154 }
1155 
1156 static void
1157 gnc_plugin_page_owner_tree_cmd_new_invoice (GSimpleAction *simple,
1158  GVariant *parameter,
1159  gpointer user_data)
1160 
1161 {
1162  auto plugin_page = GNC_PLUGIN_PAGE_OWNER_TREE(user_data);
1164  GncOwner current_owner;
1165  GtkWindow *parent;
1166 
1167  ENTER("action %p, plugin_page %p", simple, plugin_page);
1168 
1169  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
1170  switch (priv->owner_type)
1171  {
1172  case GNC_OWNER_NONE :
1173  case GNC_OWNER_UNDEFINED :
1174  gncOwnerInitUndefined(&current_owner, NULL);
1175  break;
1176  case GNC_OWNER_CUSTOMER :
1177  {
1178  gncOwnerInitCustomer(&current_owner,
1180  break;
1181  }
1182  case GNC_OWNER_JOB :
1183  {
1184  gncOwnerInitJob(&current_owner,
1186  break;
1187  }
1188  case GNC_OWNER_VENDOR :
1189  {
1190  gncOwnerInitVendor(&current_owner,
1192  break;
1193  }
1194  case GNC_OWNER_EMPLOYEE :
1195  {
1196  gncOwnerInitEmployee(&current_owner,
1198  break;
1199  }
1200  }
1201 
1202  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
1203  if (gncOwnerGetType(&current_owner) != GNC_OWNER_UNDEFINED)
1204  gnc_ui_invoice_new (parent, &current_owner, gnc_get_current_book ());
1205 
1206  LEAVE(" ");
1207 }
1208 
1209 static void
1210 gnc_plugin_page_owner_tree_cmd_owners_report (GSimpleAction *simple,
1211  GVariant *parameter,
1212  gpointer user_data)
1213 
1214 {
1215  auto plugin_page = GNC_PLUGIN_PAGE_OWNER_TREE(user_data);
1217  int id;
1218 
1219  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1220 
1221  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1222 
1223  priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(plugin_page);
1224  id = build_aging_report (priv->owner_type);
1225  if (id >= 0)
1226  {
1227  GncMainWindow *window;
1228  window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
1229  gnc_main_window_open_report(id, window);
1230  }
1231 
1232  LEAVE(" ");
1233 }
1234 
1235 static void
1236 gnc_plugin_page_owner_tree_cmd_owner_report (GSimpleAction *simple,
1237  GVariant *parameter,
1238  gpointer user_data)
1239 
1240 {
1241  auto plugin_page = GNC_PLUGIN_PAGE_OWNER_TREE(user_data);
1242  GncOwner *current_owner;
1243  int id;
1244 
1245  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1246 
1247  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1248 
1249  current_owner = gnc_plugin_page_owner_tree_get_current_owner (plugin_page);
1250  id = build_owner_report (current_owner, NULL);
1251  if (id >= 0)
1252  {
1253  GncMainWindow *window;
1254  window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
1255  gnc_main_window_open_report(id, window);
1256  }
1257 
1258  LEAVE(" ");
1259 }
1260 
1261 
1262 static void
1263 gnc_plugin_page_owner_tree_cmd_process_payment (GSimpleAction *simple,
1264  GVariant *parameter,
1265  gpointer user_data)
1266 
1267 {
1268  auto plugin_page = GNC_PLUGIN_PAGE_OWNER_TREE(user_data);
1269  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1270 
1271  g_return_if_fail(GNC_IS_PLUGIN_PAGE_OWNER_TREE(plugin_page));
1272 
1273  gnc_ui_payment_new (GTK_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window),
1275  gnc_get_current_book ());
1276 
1277  LEAVE(" ");
1278 }
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.
void gnc_plugin_page_set_menu_qualifier(GncPluginPage *page, const char *menu_qualifier)
Set a qualifier string 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.
void gnc_main_window_update_menu_and_toolbar(GncMainWindow *window, GncPluginPage *page, const gchar **ui_updates)
Update the main window menu with the placeholders listed in ui_updates and load the page specific too...
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...
STRUCTS.
void gnc_main_window_init_short_names(GncMainWindow *window, GncToolBarShortNames *toolbar_labels)
Update the labels of the toolbar items with short names.
Functions that are supported by all types of windows.
GSimpleActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
Retrieve the GSimpleActionGroup object associated with this page.
GtkWidget * window
The window that contains the display widget for this plugin.
GncOwnerType owner_type
The owner type to show this action for.
GSimpleActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
Create the GSimpleActionGroup 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:72
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.
GAction * gnc_main_window_find_action(GncMainWindow *window, const gchar *action_name)
Find the GAction in the main window.
void gnc_plugin_page_disconnect_page_changed(GncPluginPage *page)
Disconnect the page_changed_id signal callback.
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:235
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:362
void gnc_plugin_set_actions_enabled(GActionMap *action_map, const gchar **action_names, gboolean enable)
This function sets the sensitivity of a GAction in a specific group.
Definition: gnc-plugin.c:250
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:200
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:376
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
Definition: qofbook.cpp:497
A structure for defining alternate action names for use in the toolbar.
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:383
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:369
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...
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:390
GncPluginPage * gnc_plugin_page_owner_tree_new(GncOwnerType owner_type)
Create a new "owner tree" plugin page.