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