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