GnuCash  5.6-150-g038405b370+
gnc-plugin-page-invoice.cpp
1 /*
2  * gnc-plugin-page-invoice.c --
3  *
4  * Copyright (C) 2005,2006 David Hampton <hampton@employees.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, contact:
18  *
19  * Free Software Foundation Voice: +1-617-542-5942
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21  * Boston, MA 02110-1301, USA gnu@gnu.org
22  */
23 
24 #include <config.h>
25 
26 #include <gtk/gtk.h>
27 #include <glib/gi18n.h>
28 
29 #include "gnc-plugin.h"
30 #include "business-gnome-utils.h"
31 #include "dialog-invoice.h"
32 #include "gnc-ledger-display.h"
34 
35 #include "dialog-account.h"
36 #include "gnc-component-manager.h"
37 #include "gnc-gobject-utils.h"
38 #include "gnc-gnome-utils.h"
39 #include "gnc-icons.h"
40 #include "gnucash-register.h"
41 #include "gnc-prefs.h"
42 #include "gnc-ui-util.h"
43 #include "gnc-uri-utils.h"
44 #include "gnc-window.h"
45 #include "dialog-utils.h"
46 #include "dialog-doclink.h"
47 #include "dialog-doclink-utils.h"
48 #include "gncInvoice.h"
49 #include "gnc-ui.h"
50 #include "gnc-gtk-utils.h"
51 
52 /* This static indicates the debugging module that this .o belongs to. */
53 static QofLogModule log_module = GNC_MOD_GUI;
54 
55 static void gnc_plugin_page_invoice_finalize (GObject *object);
56 
57 static GtkWidget *gnc_plugin_page_invoice_create_widget (GncPluginPage *plugin_page);
58 static gboolean gnc_plugin_page_invoice_focus_widget (GncPluginPage *plugin_page);
59 static void gnc_plugin_page_invoice_destroy_widget (GncPluginPage *plugin_page);
60 static void gnc_plugin_page_invoice_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
61 static GncPluginPage *gnc_plugin_page_invoice_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
62 static void gnc_plugin_page_invoice_window_changed (GncPluginPage *plugin_page, GtkWidget *window);
63 
64 static void gnc_plugin_page_invoice_summarybar_position_changed (gpointer prefs, gchar* pref, gpointer user_data);
65 
66 /* Command callbacks */
67 static void gnc_plugin_page_invoice_cmd_new_invoice (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
68 static void gnc_plugin_page_invoice_cmd_new_account (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
69 static void gnc_plugin_page_invoice_cmd_print (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
70 static void gnc_plugin_page_invoice_cmd_cut (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
71 static void gnc_plugin_page_invoice_cmd_copy (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
72 static void gnc_plugin_page_invoice_cmd_paste (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
73 static void gnc_plugin_page_invoice_cmd_edit (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
74 static void gnc_plugin_page_invoice_cmd_duplicateInvoice (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
75 static void gnc_plugin_page_invoice_cmd_post (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
76 static void gnc_plugin_page_invoice_cmd_unpost (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
77 static void gnc_plugin_page_invoice_cmd_refresh (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
78 static void gnc_plugin_page_invoice_cmd_sort_changed (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
79 static void gnc_plugin_page_invoice_cmd_enter (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
80 static void gnc_plugin_page_invoice_cmd_cancel (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
81 static void gnc_plugin_page_invoice_cmd_delete (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
82 static void gnc_plugin_page_invoice_cmd_blank (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
83 static void gnc_plugin_page_invoice_cmd_duplicateEntry (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
84 static void gnc_plugin_page_invoice_cmd_pay_invoice (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
85 static void gnc_plugin_page_invoice_cmd_save_layout (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
86 static void gnc_plugin_page_invoice_cmd_reset_layout (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
87 static void gnc_plugin_page_invoice_cmd_link (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
88 static void gnc_plugin_page_invoice_cmd_link_open (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
89 static void gnc_plugin_page_invoice_cmd_company_report (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
90 static void gnc_plugin_page_invoice_cmd_entryUp (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
91 static void gnc_plugin_page_invoice_cmd_entryDown (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
92 static void gnc_plugin_page_invoice_cmd_edit_tax (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
93 
94 static void gnc_plugin_page_redraw_help_cb (GnucashRegister *gsr, GncPluginPageInvoice *invoice_page);
95 static void gnc_plugin_page_show_popup_cb (GnucashRegister *gsr, GncPluginPageInvoice *invoice_page);
96 static void gnc_plugin_page_invoice_refresh_cb (GHashTable *changes, gpointer user_data);
97 
98 /************************************************************
99  * Actions *
100  ************************************************************/
101 static GActionEntry gnc_plugin_page_invoice_actions [] =
102 {
103  { "FileNewAccountAction", gnc_plugin_page_invoice_cmd_new_account, NULL, NULL, NULL },
104  { "FilePrintAction", gnc_plugin_page_invoice_cmd_print, NULL, NULL, NULL },
105  { "EditCutAction", gnc_plugin_page_invoice_cmd_cut, NULL, NULL, NULL },
106  { "EditCopyAction", gnc_plugin_page_invoice_cmd_copy, NULL, NULL, NULL },
107  { "EditPasteAction", gnc_plugin_page_invoice_cmd_paste, NULL, NULL, NULL },
108  { "EditEditInvoiceAction", gnc_plugin_page_invoice_cmd_edit, NULL, NULL, NULL },
109  { "EditDuplicateInvoiceAction", gnc_plugin_page_invoice_cmd_duplicateInvoice, NULL, NULL, NULL },
110  { "EditPostInvoiceAction", gnc_plugin_page_invoice_cmd_post, NULL, NULL, NULL },
111  { "EditUnpostInvoiceAction", gnc_plugin_page_invoice_cmd_unpost, NULL, NULL, NULL },
112  { "EditTaxOptionsAction", gnc_plugin_page_invoice_cmd_edit_tax, NULL, NULL, NULL },
113  { "ViewRefreshAction", gnc_plugin_page_invoice_cmd_refresh, NULL, NULL, NULL },
114  { "ViewSaveLayoutAction", gnc_plugin_page_invoice_cmd_save_layout, NULL, NULL, NULL },
115  { "ViewResetLayoutAction", gnc_plugin_page_invoice_cmd_reset_layout, NULL, NULL, NULL },
116  { "RecordEntryAction", gnc_plugin_page_invoice_cmd_enter, NULL, NULL, NULL },
117  { "CancelEntryAction", gnc_plugin_page_invoice_cmd_cancel, NULL, NULL, NULL },
118  { "DeleteEntryAction", gnc_plugin_page_invoice_cmd_delete, NULL, NULL, NULL },
119  { "BlankEntryAction", gnc_plugin_page_invoice_cmd_blank, NULL, NULL, NULL },
120  { "DuplicateEntryAction", gnc_plugin_page_invoice_cmd_duplicateEntry, NULL, NULL, NULL },
121  { "EntryUpAction", gnc_plugin_page_invoice_cmd_entryUp, NULL, NULL, NULL },
122  { "EntryDownAction", gnc_plugin_page_invoice_cmd_entryDown, NULL, NULL, NULL },
123  { "BusinessNewInvoiceAction", gnc_plugin_page_invoice_cmd_new_invoice, NULL, NULL, NULL },
124  { "BusinessLinkAction", gnc_plugin_page_invoice_cmd_link, NULL, NULL, NULL },
125  { "BusinessLinkOpenAction", gnc_plugin_page_invoice_cmd_link_open, NULL, NULL, NULL },
126  { "ToolsProcessPaymentAction", gnc_plugin_page_invoice_cmd_pay_invoice, NULL, NULL, NULL },
127  { "ReportsCompanyReportAction", gnc_plugin_page_invoice_cmd_company_report, NULL, NULL, NULL },
128  { "SortOrderRadioAction", gnc_plugin_page_invoice_cmd_sort_changed, "i", "@i 0", NULL },
129 };
130 static guint gnc_plugin_page_invoice_n_actions = G_N_ELEMENTS(gnc_plugin_page_invoice_actions);
131 
133 static const gchar *gnc_plugin_load_ui_items [] =
134 {
135  "FilePlaceholder3",
136  "EditPlaceholder1",
137  "EditPlaceholder3",
138  "EditPlaceholder5",
139  "ViewPlaceholder1",
140  "ViewPlaceholder2",
141  "ViewPlaceholder4",
142  "ActionsPlaceholder4",
143  "ActionsPlaceholder5",
144  "BusinessPlaceholder2",
145  "BusinessPlaceholder3",
146  "ReportsPlaceholder1",
147  NULL,
148 };
149 
150 static const gchar *invoice_book_readwrite_actions[] =
151 {
152  // Only insert actions here which are not yet in posted_actions and unposted_actions!
153  "FileNewAccountAction",
154  "EditDuplicateInvoiceAction",
155  "BusinessNewInvoiceAction",
156  "ToolsProcessPaymentAction",
157  "BusinessLinkAction",
158  NULL
159 };
160 
161 static const gchar *posted_actions[] =
162 {
163  NULL
164 };
165 
166 static const gchar *unposted_actions[] =
167 {
168  "EditCutAction",
169  "EditPasteAction",
170  "EditEditInvoiceAction",
171  "EditPostInvoiceAction",
172  "RecordEntryAction",
173  "CancelEntryAction",
174  "DeleteEntryAction",
175  "DuplicateEntryAction",
176  "EntryUpAction",
177  "EntryDownAction",
178  "BlankEntryAction",
179  NULL
180 };
181 
182 static const gchar *can_unpost_actions[] =
183 {
184  "EditUnpostInvoiceAction",
185  NULL
186 };
187 
188 static action_toolbar_labels invoice_action_labels[] =
189 {
190  {"FilePrintAction", N_("_Print Invoice"), N_("Make a printable invoice")},
191  {"EditEditInvoiceAction", N_("_Edit Invoice"), N_("Edit this invoice")},
192  {"EditDuplicateInvoiceAction", N_("_Duplicate Invoice"), N_("Create a new invoice as a duplicate of the current one")},
193  {"EditPostInvoiceAction", N_("_Post Invoice"), N_("Post this invoice to your Chart of Accounts")},
194  {"EditUnpostInvoiceAction", N_("_Unpost Invoice"), N_("Unpost this invoice and make it editable")},
195  {"BusinessNewInvoiceAction", N_("New _Invoice"), N_("Create a new invoice for the same owner as the current one")},
196  {"BlankEntryAction", N_("Blank"), N_("Move to the blank entry at the bottom of the invoice")},
197  {"ToolsProcessPaymentAction", N_("_Pay Invoice"), N_("Enter a payment for the owner of this invoice") },
198  {"ReportsCompanyReportAction", N_("_Company Report"), N_("Open a customer report window for the owner of this invoice") },
199  {"BusinessLinkAction", N_("_Manage Document Link…"), N_("Manage Document Link")},
200  {"BusinessLinkOpenAction", N_("_Open Linked Document"), N_("Open Linked Document")},
201  {NULL, NULL, NULL},
202 };
203 
204 static action_toolbar_labels invoice_action_layout_labels[] =
205 {
206  {"ViewSaveLayoutAction", N_("_Use as Default Layout for Customer Documents"),
207  N_("Use the current layout as default for all customer invoices and credit notes")},
208  {"ViewResetLayoutAction", N_("_Reset Default Layout for Customer Documents"),
209  N_("Reset default layout for all customer invoices and credit notes back to built-in defaults and update the current page accordingly")},
210  {NULL, NULL, NULL},
211 };
212 
213 static action_toolbar_labels bill_action_labels[] =
214 {
215  {"FilePrintAction", N_("_Print Bill"), N_("Make a printable bill")},
216  {"EditEditInvoiceAction", N_("_Edit Bill"), N_("Edit this bill")},
217  {"EditDuplicateInvoiceAction", N_("_Duplicate Bill"), N_("Create a new bill as a duplicate of the current one")},
218  {"EditPostInvoiceAction", N_("_Post Bill"), N_("Post this bill to your Chart of Accounts")},
219  {"EditUnpostInvoiceAction", N_("_Unpost Bill"), N_("Unpost this bill and make it editable")},
220  {"BusinessNewInvoiceAction", N_("New _Bill"), N_("Create a new bill for the same owner as the current one")},
221  {"BlankEntryAction", N_("Blank"), N_("Move to the blank entry at the bottom of the bill")},
222  {"ToolsProcessPaymentAction", N_("_Pay Bill"), N_("Enter a payment for the owner of this bill") },
223  {"ReportsCompanyReportAction", N_("_Company Report"), N_("Open a vendor report window for the owner of this bill") },
224  {"BusinessLinkAction", N_("_Manage Document Link…"), N_("Manage Document Link")},
225  {"BusinessLinkOpenAction", N_("_Open Linked Document"), N_("Open Linked Document")},
226  {NULL, NULL, NULL},
227 };
228 
229 static action_toolbar_labels bill_action_layout_labels[] =
230 {
231  {"ViewSaveLayoutAction", N_("_Use as Default Layout for Vendor Documents"),
232  N_("Use the current layout as default for all vendor bills and credit notes")},
233  {"ViewResetLayoutAction", N_("_Reset Default Layout for Vendor Documents"),
234  N_("Reset default layout for all vendor bills and credit notes back to built-in defaults and update the current page accordingly")},
235  {NULL, NULL, NULL},
236 };
237 
238 static action_toolbar_labels voucher_action_labels[] =
239 {
240  {"FilePrintAction", N_("_Print Voucher"), N_("Make a printable voucher")},
241  {"EditEditInvoiceAction", N_("_Edit Voucher"), N_("Edit this voucher")},
242  {"EditDuplicateInvoiceAction", N_("_Duplicate Voucher"), N_("Create a new voucher as a duplicate of the current one")},
243  {"EditPostInvoiceAction", N_("_Post Voucher"), N_("Post this voucher to your Chart of Accounts")},
244  {"EditUnpostInvoiceAction", N_("_Unpost Voucher"), N_("Unpost this voucher and make it editable")},
245  {"BusinessNewInvoiceAction", N_("New _Voucher"), N_("Create a new voucher for the same owner as the current one")},
246  {"BlankEntryAction", N_("Blank"), N_("Move to the blank entry at the bottom of the voucher")},
247  {"ToolsProcessPaymentAction", N_("_Pay Voucher"), N_("Enter a payment for the owner of this voucher") },
248  {"ReportsCompanyReportAction", N_("_Company Report"), N_("Open a employee report window for the owner of this voucher") },
249  {"BusinessLinkAction", N_("_Manage Document Link…"), N_("Manage Document Link")},
250  {"BusinessLinkOpenAction", N_("_Open Linked Document"), N_("Open Linked Document")},
251  {NULL, NULL, NULL},
252 };
253 
254 static action_toolbar_labels voucher_action_layout_labels[] =
255 {
256  {"ViewSaveLayoutAction", N_("_Use as Default Layout for Employee Documents"),
257  N_("Use the current layout as default for all employee vouchers and credit notes")},
258  {"ViewResetLayoutAction", N_("_Reset Default Layout for Employee Documents"),
259  N_("Reset default layout for all employee vouchers and credit notes back to built-in defaults and update the current page accordingly")},
260  {NULL, NULL, NULL},
261 };
262 
263 static action_toolbar_labels creditnote_action_labels[] =
264 {
265  {"FilePrintAction", N_("_Print Credit Note"), N_("Make a printable credit note")},
266  {"EditEditInvoiceAction", N_("_Edit Credit Note"), N_("Edit this credit note")},
267  {"EditDuplicateInvoiceAction", N_("_Duplicate Credit Note"), N_("Create a new credit note as a duplicate of the current one")},
268  {"EditPostInvoiceAction", N_("_Post Credit Note"), N_("Post this credit note to your Chart of Accounts")},
269  {"EditUnpostInvoiceAction", N_("_Unpost Credit Note"), N_("Unpost this credit note and make it editable")},
270  {"BusinessNewInvoiceAction", N_("New _Credit Note"), N_("Create a new credit note for the same owner as the current one")},
271  {"BlankEntryAction", N_("Blank"), N_("Move to the blank entry at the bottom of the credit note")},
272  {"ToolsProcessPaymentAction", N_("_Pay Credit Note"), N_("Enter a payment for the owner of this credit note") },
273  {"ReportsCompanyReportAction", N_("_Company Report"), N_("Open a company report window for the owner of this credit note") },
274  {"BusinessLinkAction", N_("_Manage Document Link…"), N_("Manage Document Link…")},
275  {"BusinessLinkOpenAction", N_("_Open Linked Document"), N_("Open Linked Document")},
276  {NULL, NULL, NULL},
277 };
278 
280 static GncToolBarShortNames toolbar_labels[] =
281 {
282  {"RecordEntryAction", N_("Enter")},
283  {"CancelEntryAction", N_("Cancel")},
284  {"DeleteEntryAction", N_("Delete")},
285  {"DuplicateEntryAction", N_("Duplicate")},
286  {"EntryUpAction", N_("Up")},
287  {"EntryDownAction", N_("Down")},
288  {"BlankEntryAction", N_("Blank")},
289  {"EditPostInvoiceAction", N_("Post")},
290  {"EditUnpostInvoiceAction", N_("Unpost")},
291  {"ToolsProcessPaymentAction", N_("Pay")},
292  {NULL, NULL},
293 };
294 
295 /************************************************************/
296 /* Data Structures */
297 /************************************************************/
298 
300 {
301  InvoiceWindow *iw;
302 
303  GtkWidget *widget;
304  gboolean is_posted;
305  gboolean can_unpost;
306 
307  gint component_manager_id;
309 
310 G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageInvoice, gnc_plugin_page_invoice, GNC_TYPE_PLUGIN_PAGE)
311 
312 #define GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(o) \
313  ((GncPluginPageInvoicePrivate*)gnc_plugin_page_invoice_get_instance_private((GncPluginPageInvoice*)o))
314 
315 /************************************************************/
316 /* Implementation */
317 /************************************************************/
318 
319 InvoiceWindow *
321 {
323  GncPluginPageInvoice *invoice_page;
324  const GList *item;
325 
326  /* Is there an existing page? */
327  item = gnc_gobject_tracking_get_list (GNC_PLUGIN_PAGE_INVOICE_NAME);
328  for ( ; item; item = g_list_next(item))
329  {
330  invoice_page = (GncPluginPageInvoice *)item->data;
331  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(invoice_page);
332 
333  if (gnc_invoice_window_get_invoice (priv->iw) == invoice)
334  return priv->iw;
335  }
336  return NULL;
337 }
338 
340 gnc_plugin_page_invoice_new (InvoiceWindow *iw)
341 {
343  GncPluginPageInvoice *invoice_page;
344  GncPluginPage *plugin_page;
345  const GList *item;
346 
347  /* Is there an existing page? */
348  item = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_INVOICE_NAME);
349  for ( ; item; item = g_list_next(item))
350  {
351  invoice_page = (GncPluginPageInvoice *)item->data;
352  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(invoice_page);
353  if (priv->iw == iw)
354  return GNC_PLUGIN_PAGE(invoice_page);
355  }
356 
357  invoice_page = GNC_PLUGIN_PAGE_INVOICE (g_object_new (GNC_TYPE_PLUGIN_PAGE_INVOICE, nullptr));
358  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(invoice_page);
359  priv->iw = iw;
360 
361  plugin_page = GNC_PLUGIN_PAGE(invoice_page);
363 
364  priv->component_manager_id = 0;
365  return plugin_page;
366 }
367 
368 static void
369 gnc_plugin_page_invoice_class_init (GncPluginPageInvoiceClass *klass)
370 {
371  GObjectClass *object_class = G_OBJECT_CLASS (klass);
372  GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
373 
374  object_class->finalize = gnc_plugin_page_invoice_finalize;
375 
376  gnc_plugin_class->tab_icon = NULL;
377  gnc_plugin_class->plugin_name = GNC_PLUGIN_PAGE_INVOICE_NAME;
378  gnc_plugin_class->create_widget = gnc_plugin_page_invoice_create_widget;
379  gnc_plugin_class->destroy_widget = gnc_plugin_page_invoice_destroy_widget;
380  gnc_plugin_class->save_page = gnc_plugin_page_invoice_save_page;
381  gnc_plugin_class->recreate_page = gnc_plugin_page_invoice_recreate_page;
382  gnc_plugin_class->window_changed = gnc_plugin_page_invoice_window_changed;
383  gnc_plugin_class->focus_page_function = gnc_plugin_page_invoice_focus_widget;
384 }
385 
386 static void
387 gnc_plugin_page_invoice_init (GncPluginPageInvoice *plugin_page)
388 {
389  GncPluginPage *parent;
390  GSimpleActionGroup *simple_action_group;
391  gboolean use_new;
392 
393  /* Init parent declared variables */
394  parent = GNC_PLUGIN_PAGE(plugin_page);
395  use_new = gnc_prefs_get_bool (GNC_PREFS_GROUP_INVOICE, GNC_PREF_USE_NEW);
396  g_object_set(G_OBJECT(plugin_page),
397  "page-name", _("Invoice"),
398  "ui-description", "gnc-plugin-page-invoice.ui",
399  "use-new-window", use_new,
400  (char *)NULL);
401 
402  /* change me when the system supports multiple books */
403  gnc_plugin_page_add_book (parent, gnc_get_current_book());
404 
405  /* Create menu and toolbar information */
406  simple_action_group = gnc_plugin_page_create_action_group (parent,"GncPluginPageInvoiceActions");
407  g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
408  gnc_plugin_page_invoice_actions,
409  gnc_plugin_page_invoice_n_actions,
410  plugin_page);
411 }
412 
413 static void
414 gnc_plugin_page_invoice_finalize (GObject *object)
415 {
416  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE (object));
417 
418  ENTER("object %p", object);
419  G_OBJECT_CLASS (gnc_plugin_page_invoice_parent_class)->finalize (object);
420  LEAVE(" ");
421 }
422 
423 static void
424 update_doclink_actions (GncPluginPage *plugin_page, gboolean has_uri)
425 {
426  GAction *uri_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(plugin_page),
427  "BusinessLinkOpenAction");
428  g_simple_action_set_enabled (G_SIMPLE_ACTION(uri_action), has_uri);
429 }
430 
431 static void
432 gnc_plugin_page_invoice_action_update (GncPluginPage *plugin_page,
433  action_toolbar_labels *action_list)
434 {
435  GncMainWindow *window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
436  GtkWidget *tool_item;
437 
438  for (gint i = 0; (action_list[i].action_name != NULL); i++)
439  {
441  action_list[i].action_name,
442  _(action_list[i].label),
443  _(action_list[i].tooltip));
444 
445  tool_item = gnc_main_window_toolbar_find_tool_item (window,
446  action_list[i].action_name);
447 
448  if (tool_item)
449  {
450  gtk_tool_button_set_label (GTK_TOOL_BUTTON(tool_item), _(action_list[i].label));
451  gtk_widget_set_tooltip_text (GTK_WIDGET(tool_item), _(action_list[i].tooltip));
452  g_object_set (G_OBJECT(tool_item), "has-tooltip", FALSE, NULL);
453  }
454  }
455  // need to add the accelerator keys for the updated menu items
457 }
458 
459 static void
460 gnc_plugin_page_update_reset_layout_action (GncPluginPage *page)
461 {
463  GAction *layout_action;
464  gboolean has_default = FALSE;
465 
466  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(page));
467 
468  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(page);
469 
470  layout_action = gnc_plugin_page_get_action (page, "ViewResetLayoutAction");
471  if (gnc_invoice_window_document_has_user_state (priv->iw))
472  has_default = TRUE;
473  g_simple_action_set_enabled (G_SIMPLE_ACTION(layout_action), has_default);
474 }
475 
476 void
477 gnc_plugin_page_invoice_update_menus (GncPluginPage *page, gboolean is_posted, gboolean can_unpost)
478 {
479  GncMainWindow *window;
480  GSimpleActionGroup *simple_action_group;
481  GAction *action;
483  GncInvoiceType invoice_type;
484  GncInvoice *invoice;
485  action_toolbar_labels *label_list;
486  action_toolbar_labels *label_layout_list;
487  gboolean has_uri = FALSE;
488 
489  gboolean is_readonly = qof_book_is_readonly(gnc_get_current_book());
490 
491  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(page));
492 
493  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(page);
494 
495  // lets remember these settings
496  priv->is_posted = is_posted;
497  priv->can_unpost = can_unpost;
498 
499  window = (GncMainWindow*)gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(page));
500  if (gnc_main_window_get_current_page (window) != page)
501  return;
502 
503  invoice_type = gnc_invoice_get_type_from_window(priv->iw);
504 
505  switch (invoice_type) {
506  case GNC_INVOICE_CUST_INVOICE:
507  label_list = invoice_action_labels;
508  break;
509  case GNC_INVOICE_VEND_INVOICE:
510  label_list = bill_action_labels;
511  break;
512  case GNC_INVOICE_EMPL_INVOICE:
513  label_list = voucher_action_labels;
514  break;
515  case GNC_INVOICE_CUST_CREDIT_NOTE: // fallthrough
516  case GNC_INVOICE_VEND_CREDIT_NOTE: // fallthrough
517  case GNC_INVOICE_EMPL_CREDIT_NOTE: // fallthrough
518  label_list = creditnote_action_labels;
519  break;
520  default: // catches GNC_INVOICE_UNDEFINED, use invoice by default
521  label_list = invoice_action_labels;
522  }
523 
524  // layout actions
525  switch (invoice_type) {
526  case GNC_INVOICE_CUST_INVOICE:
527  case GNC_INVOICE_CUST_CREDIT_NOTE:
528  label_layout_list = invoice_action_layout_labels;
529  break;
530  case GNC_INVOICE_VEND_INVOICE:
531  case GNC_INVOICE_VEND_CREDIT_NOTE:
532  label_layout_list = bill_action_layout_labels;
533  break;
534  case GNC_INVOICE_EMPL_INVOICE:
535  case GNC_INVOICE_EMPL_CREDIT_NOTE:
536  label_layout_list = voucher_action_layout_labels;
537  break;
538  default: // catches GNC_INVOICE_UNDEFINED, use invoice by default
539  label_layout_list = invoice_action_layout_labels;
540  }
541 
542  if (is_readonly)
543  {
544  // Are we readonly? Then don't allow any actions.
545  is_posted = TRUE;
546  can_unpost = FALSE;
547  }
548 
549  /* Enable the FilePrintAction */
550  action = gnc_main_window_find_action (window, "FilePrintAction");
551  g_simple_action_set_enabled (G_SIMPLE_ACTION(action), TRUE);
552 
553  simple_action_group = gnc_plugin_page_get_action_group (page);
554  gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group), posted_actions,
555  is_posted);
556  gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group), unposted_actions,
557  !is_posted);
558  gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group), can_unpost_actions,
559  can_unpost);
560  gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group), invoice_book_readwrite_actions,
561  !is_readonly);
562 
563  /* update the action labels and tooltips */
564  gnc_plugin_page_invoice_action_update (page, label_list);
565 
566  // if there is no default layout do not enable reset action
567  gnc_plugin_page_update_reset_layout_action (page);
568 
569  /* update the layout action labels and tooltips */
570  gnc_plugin_page_invoice_action_update (page, label_layout_list);
571 
572  // update doclink buttons
573  invoice = gnc_invoice_window_get_invoice (priv->iw);
574  if (gncInvoiceGetDocLink (invoice))
575  has_uri = TRUE;
576 
577  update_doclink_actions (page, has_uri);
578 }
579 
580 
585 static gboolean
586 gnc_plugin_page_invoice_focus_widget (GncPluginPage *invoice_plugin_page)
587 {
588  if (GNC_IS_PLUGIN_PAGE_INVOICE(invoice_plugin_page))
589  {
590  GncPluginPageInvoicePrivate *priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(invoice_plugin_page);
591 
592  GtkWidget *regWidget = gnc_invoice_get_register(priv->iw);
593  GtkWidget *notes = gnc_invoice_get_notes(priv->iw);
594  GnucashSheet *sheet;
595 
596  /* Disable the Transaction Menu */
597  GAction *action = gnc_main_window_find_action (GNC_MAIN_WINDOW(invoice_plugin_page->window), "TransactionAction");
598  g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
599  /* Disable the Schedule menu */
600  action = gnc_main_window_find_action (GNC_MAIN_WINDOW(invoice_plugin_page->window), "ScheduledAction");
601  g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
602 
603  gnc_main_window_update_menu_and_toolbar (GNC_MAIN_WINDOW(invoice_plugin_page->window),
604  invoice_plugin_page,
605  gnc_plugin_load_ui_items);
606 
607  gnc_plugin_page_invoice_update_menus (invoice_plugin_page, priv->is_posted, priv->can_unpost);
608 
609  // setup any short toolbar names
610  gnc_main_window_init_short_names (GNC_MAIN_WINDOW(invoice_plugin_page->window), toolbar_labels);
611 
612  // if there is no default layout do not enable reset action
613  gnc_plugin_page_update_reset_layout_action (invoice_plugin_page);
614 
615  if (!GNUCASH_IS_REGISTER(regWidget))
616  return FALSE;
617 
618  sheet = gnucash_register_get_sheet (GNUCASH_REGISTER(regWidget));
619 
620  // Test for the sheet being read only
621  if (!gnucash_sheet_is_read_only (sheet))
622  {
623  if (!gtk_widget_is_focus (GTK_WIDGET(sheet)))
624  gtk_widget_grab_focus (GTK_WIDGET(sheet));
625  }
626  else // set focus to the notes field
627  {
628  if (!gtk_widget_is_focus (GTK_WIDGET(notes)))
629  gtk_widget_grab_focus (GTK_WIDGET(notes));
630  }
631  }
632  return FALSE;
633 }
634 
635 
636 /* Virtual Functions */
637 
638 static GtkWidget *
639 gnc_plugin_page_invoice_create_widget (GncPluginPage *plugin_page)
640 {
641  GncPluginPageInvoice *page;
643  GtkWidget *regWidget, *widget;
644 
645  ENTER("page %p", plugin_page);
646  page = GNC_PLUGIN_PAGE_INVOICE (plugin_page);
647  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(page);
648  if (priv->widget != NULL)
649  {
650  LEAVE("");
651  return priv->widget;
652  }
653 
654  priv->widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
655  gtk_box_set_homogeneous (GTK_BOX (priv->widget), FALSE);
656 
657  // Set the name for this widget so it can be easily manipulated with css
658  gtk_widget_set_name (GTK_WIDGET(priv->widget), "gnc-id-invoice-page");
659 
660  gtk_widget_show (priv->widget);
661 
662  widget = gnc_invoice_create_page(priv->iw, page);
663  gtk_widget_show (widget);
664  gtk_box_pack_start(GTK_BOX (priv->widget), widget, TRUE, TRUE, 0);
665 
666  plugin_page->summarybar = gnc_invoice_window_create_summary_bar(priv->iw);
667  gtk_box_pack_start(GTK_BOX (priv->widget), plugin_page->summarybar, FALSE, FALSE, 0);
668  gnc_plugin_page_invoice_summarybar_position_changed(NULL, NULL, page);
669  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
670  GNC_PREF_SUMMARYBAR_POSITION_TOP,
671  (gpointer)gnc_plugin_page_invoice_summarybar_position_changed,
672  page);
673  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
674  GNC_PREF_SUMMARYBAR_POSITION_BOTTOM,
675  (gpointer)gnc_plugin_page_invoice_summarybar_position_changed,
676  page);
677 
678  regWidget = gnc_invoice_get_register(priv->iw);
679  if (regWidget)
680  {
681  g_signal_connect (G_OBJECT (regWidget), "redraw-help",
682  G_CALLBACK (gnc_plugin_page_redraw_help_cb), page);
683 
684  g_signal_connect (G_OBJECT(regWidget), "show-popup-menu",
685  G_CALLBACK(gnc_plugin_page_show_popup_cb), page);
686  }
687 
688  priv->component_manager_id =
689  gnc_register_gui_component(GNC_PLUGIN_PAGE_INVOICE_NAME,
690  gnc_plugin_page_invoice_refresh_cb,
691  NULL, page);
692 
693  g_signal_connect (G_OBJECT(plugin_page), "inserted",
694  G_CALLBACK(gnc_plugin_page_inserted_cb),
695  NULL);
696 
697  LEAVE("");
698  return priv->widget;
699 }
700 
701 static void
702 gnc_plugin_page_invoice_destroy_widget (GncPluginPage *plugin_page)
703 {
704  GncPluginPageInvoice *page;
706 
707  ENTER("page %p", plugin_page);
708  page = GNC_PLUGIN_PAGE_INVOICE (plugin_page);
709  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(page);
710 
711  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
712  GNC_PREF_SUMMARYBAR_POSITION_TOP,
713  (gpointer)gnc_plugin_page_invoice_summarybar_position_changed,
714  page);
715  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
716  GNC_PREF_SUMMARYBAR_POSITION_BOTTOM,
717  (gpointer)gnc_plugin_page_invoice_summarybar_position_changed,
718  page);
719 
720  // Remove the page_changed signal callback
721  gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
722 
723  // Remove the page focus idle function if present
724  g_idle_remove_by_data (plugin_page);
725 
726  if (priv->widget == NULL)
727  {
728  LEAVE("");
729  return;
730  }
731 
732  if (priv->component_manager_id)
733  {
734  gnc_unregister_gui_component(priv->component_manager_id);
735  priv->component_manager_id = 0;
736  }
737 
738  gtk_widget_hide(priv->widget);
739  gnc_invoice_window_destroy_cb(priv->widget, priv->iw);
740  priv->widget = NULL;
741  LEAVE("");
742 }
743 
753 static void
754 gnc_plugin_page_invoice_save_page (GncPluginPage *plugin_page,
755  GKeyFile *key_file,
756  const gchar *group_name)
757 {
758  GncPluginPageInvoice *invoice;
760 
761  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
762  g_return_if_fail (key_file != NULL);
763  g_return_if_fail (group_name != NULL);
764 
765  ENTER("page %p, key_file %p, group_name %s", plugin_page, key_file,
766  group_name);
767 
768  invoice = GNC_PLUGIN_PAGE_INVOICE(plugin_page);
769  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(invoice);
770 
771  gnc_invoice_save_page(priv->iw, key_file, group_name);
772  LEAVE(" ");
773 }
774 
775 
776 
786 static GncPluginPage *
787 gnc_plugin_page_invoice_recreate_page (GtkWidget *window,
788  GKeyFile *key_file,
789  const gchar *group_name)
790 {
791  GncPluginPage *page;
792 
793  g_return_val_if_fail(GNC_IS_MAIN_WINDOW(window), NULL);
794  g_return_val_if_fail(key_file, NULL);
795  g_return_val_if_fail(group_name, NULL);
796  ENTER("key_file %p, group_name %s", key_file, group_name);
797 
798  /* Create the new page. */
799  page = gnc_invoice_recreate_page(GNC_MAIN_WINDOW(window),
800  key_file, group_name);
801 
802  LEAVE(" ");
803  return page;
804 }
805 
806 
807 static void
808 gnc_plugin_page_invoice_window_changed (GncPluginPage *plugin_page,
809  GtkWidget *window)
810 {
811  GncPluginPageInvoice *page;
813 
814  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE (plugin_page));
815 
816  page = GNC_PLUGIN_PAGE_INVOICE(plugin_page);
817  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(page);
818  gnc_invoice_window_changed (priv->iw, window);
819 }
820 
821 
822 static void
823 gnc_plugin_page_invoice_summarybar_position_changed (gpointer prefs,
824  gchar *pref,
825  gpointer user_data)
826 {
827  GncPluginPage *plugin_page;
828  GncPluginPageInvoice *page;
830  GtkPositionType position = GTK_POS_BOTTOM;
831 
832  g_return_if_fail(user_data != NULL);
833 
834  plugin_page = GNC_PLUGIN_PAGE(user_data);
835  page = GNC_PLUGIN_PAGE_INVOICE (user_data);
836  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(page);
837 
838  if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SUMMARYBAR_POSITION_TOP))
839  position = GTK_POS_TOP;
840 
841  gtk_box_reorder_child(GTK_BOX(priv->widget),
842  plugin_page->summarybar,
843  (position == GTK_POS_TOP ? 0 : -1) );
844 }
845 
846 
847 /************************************************************/
848 /* Command callbacks */
849 /************************************************************/
850 
851 static void
852 gnc_plugin_page_invoice_cmd_new_invoice (GSimpleAction *simple,
853  GVariant *paramter,
854  gpointer user_data)
855 {
856  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
858  GtkWindow *parent;
859 
860  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
861 
862  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
863  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
864  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page)));
865  gnc_invoice_window_new_invoice_cb(parent, priv->iw);
866  LEAVE(" ");
867 }
868 
869 static void
870 gnc_plugin_page_invoice_cmd_new_account (GSimpleAction *simple,
871  GVariant *paramter,
872  gpointer user_data)
873 {
874  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
875  GtkWindow *parent = NULL;
876  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
877  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page)));
878  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
879  gnc_ui_new_account_window (parent, gnc_get_current_book(), NULL);
880  LEAVE(" ");
881 }
882 
883 static void
884 gnc_plugin_page_invoice_cmd_print (GSimpleAction *simple,
885  GVariant *paramter,
886  gpointer user_data)
887 {
888  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
890  GtkWindow *parent;
891 
892  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
893 
894  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
895  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
896  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page)));
897  gnc_invoice_window_printCB (parent, priv->iw);
898  LEAVE(" ");
899 }
900 
901 static void
902 gnc_plugin_page_invoice_cmd_cut (GSimpleAction *simple,
903  GVariant *paramter,
904  gpointer user_data)
905 {
906  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
908 
909  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
910 
911  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
912  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
913  gnc_invoice_window_cut_cb(NULL, priv->iw);
914  LEAVE(" ");
915 }
916 
917 static void
918 gnc_plugin_page_invoice_cmd_copy (GSimpleAction *simple,
919  GVariant *paramter,
920  gpointer user_data)
921 {
922  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
924 
925  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
926 
927  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
928  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
929  gnc_invoice_window_copy_cb(NULL, priv->iw);
930  LEAVE(" ");
931 }
932 
933 static void
934 gnc_plugin_page_invoice_cmd_paste (GSimpleAction *simple,
935  GVariant *paramter,
936  gpointer user_data)
937 {
938  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
940 
941  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
942 
943  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
944  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
945  gnc_invoice_window_paste_cb(NULL, priv->iw);
946  LEAVE(" ");
947 }
948 
949 static void
950 gnc_plugin_page_invoice_cmd_edit (GSimpleAction *simple,
951  GVariant *paramter,
952  gpointer user_data)
953 {
954  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
956  GtkWindow *parent;
957 
958  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
959 
960  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
961  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
962  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page)));
963  gnc_invoice_window_editCB (parent, priv->iw);
964  LEAVE(" ");
965 }
966 
967 static void
968 gnc_plugin_page_invoice_cmd_edit_tax (GSimpleAction *simple,
969  GVariant *paramter,
970  gpointer user_data)
971 {
972  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
973  GtkWidget *parent;
974 
975  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
976 
977  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
978  parent = GTK_WIDGET(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
979  gnc_tax_info_dialog (parent, NULL);
980  LEAVE(" ");
981 }
982 
983 static void
984 gnc_plugin_page_invoice_cmd_duplicateInvoice (GSimpleAction *simple,
985  GVariant *paramter,
986  gpointer user_data)
987 {
988  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
990  GtkWindow *parent;
991 
992  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
993 
994  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
995  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
996  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page)));
997  gnc_invoice_window_duplicateInvoiceCB(parent, priv->iw);
998  LEAVE(" ");
999 }
1000 
1001 static void
1002 gnc_plugin_page_invoice_cmd_post (GSimpleAction *simple,
1003  GVariant *paramter,
1004  gpointer user_data)
1005 {
1006  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1008 
1009  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1010 
1011  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1012  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1013  gnc_invoice_window_postCB(NULL, priv->iw);
1014  LEAVE(" ");
1015 }
1016 
1017 static void
1018 gnc_plugin_page_invoice_cmd_unpost (GSimpleAction *simple,
1019  GVariant *paramter,
1020  gpointer user_data)
1021 {
1022  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1024 
1025  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1026 
1027  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1028  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1029  gnc_invoice_window_unpostCB(NULL, priv->iw);
1030  LEAVE(" ");
1031 }
1032 
1033 static void
1034 gnc_plugin_page_invoice_cmd_sort_changed (GSimpleAction *simple,
1035  GVariant *parameter,
1036  gpointer user_data)
1037 {
1039  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1040  gint item;
1041 
1042  g_return_if_fail (G_IS_SIMPLE_ACTION(simple));
1043  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1044 
1045  ENTER("action %p, plugin_page (%p), item is %d",
1046  simple, plugin_page, g_variant_get_int32 (parameter));
1047 
1048  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1049  item = g_variant_get_int32 (parameter);
1050  g_action_change_state (G_ACTION(simple), parameter);
1051  gnc_invoice_window_sort (priv->iw, (invoice_sort_type_t)item);
1052  LEAVE(" ");
1053 }
1054 
1055 static void
1056 gnc_plugin_page_invoice_cmd_refresh (GSimpleAction *simple,
1057  GVariant *paramter,
1058  gpointer user_data)
1059 {
1060  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1062 
1063  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1064 
1065  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1066  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1067 
1068  gtk_widget_queue_draw (priv->widget);
1069  LEAVE(" ");
1070 }
1071 
1072 static void
1073 gnc_plugin_page_invoice_cmd_enter (GSimpleAction *simple,
1074  GVariant *paramter,
1075  gpointer user_data)
1076 {
1077  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1079 
1080  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1081 
1082  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1083  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1084  gnc_invoice_window_recordCB(NULL, priv->iw);
1085  LEAVE(" ");
1086 }
1087 
1088 static void
1089 gnc_plugin_page_invoice_cmd_cancel (GSimpleAction *simple,
1090  GVariant *paramter,
1091  gpointer user_data)
1092 {
1093  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1095 
1096  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1097 
1098  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1099  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1100  gnc_invoice_window_cancelCB(NULL, priv->iw);
1101  LEAVE(" ");
1102 }
1103 
1104 static void
1105 gnc_plugin_page_invoice_cmd_delete (GSimpleAction *simple,
1106  GVariant *paramter,
1107  gpointer user_data)
1108 {
1109  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1111 
1112  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1113 
1114  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1115  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1116  gnc_invoice_window_deleteCB(NULL, priv->iw);
1117  LEAVE(" ");
1118 }
1119 
1120 static void
1121 gnc_plugin_page_invoice_cmd_blank (GSimpleAction *simple,
1122  GVariant *paramter,
1123  gpointer user_data)
1124 {
1125  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1127 
1128  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1129 
1130  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1131  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1132  gnc_invoice_window_blankCB(NULL, priv->iw);
1133  LEAVE(" ");
1134 }
1135 
1136 static void
1137 gnc_plugin_page_invoice_cmd_duplicateEntry (GSimpleAction *simple,
1138  GVariant *paramter,
1139  gpointer user_data)
1140 {
1141  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1143 
1144  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1145 
1146  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1147  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1148  gnc_invoice_window_duplicateCB(NULL, priv->iw);
1149  LEAVE(" ");
1150 }
1151 
1152 static void
1153 gnc_plugin_page_invoice_cmd_entryUp (GSimpleAction *simple,
1154  GVariant *paramter,
1155  gpointer user_data)
1156 {
1157  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1159  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1160 
1161  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1162  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1163  gnc_invoice_window_entryUpCB(NULL, priv->iw);
1164  LEAVE(" ");
1165 }
1166 
1167 static void
1168 gnc_plugin_page_invoice_cmd_entryDown (GSimpleAction *simple,
1169  GVariant *paramter,
1170  gpointer user_data)
1171 {
1172  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1174  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1175 
1176  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1177  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1178  gnc_invoice_window_entryDownCB(NULL, priv->iw);
1179  LEAVE(" ");
1180 }
1181 
1182 static void
1183 gnc_plugin_page_invoice_cmd_pay_invoice (GSimpleAction *simple,
1184  GVariant *paramter,
1185  gpointer user_data)
1186 {
1187  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1189  GtkWindow *parent;
1190 
1191  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1192 
1193  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1194  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1195  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page)));
1196  gnc_invoice_window_payment_cb (parent, priv->iw);
1197  LEAVE(" ");
1198 }
1199 
1200 static void
1201 gnc_plugin_page_invoice_cmd_save_layout (GSimpleAction *simple,
1202  GVariant *paramter,
1203  gpointer user_data)
1204 {
1205  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1207  GAction *layout_action;
1208 
1209  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1210 
1211  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1212  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1213  gnc_invoice_window_save_document_layout_to_user_state (priv->iw);
1214 
1215  layout_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(plugin_page),
1216  "ViewResetLayoutAction");
1217  g_simple_action_set_enabled (G_SIMPLE_ACTION(layout_action), TRUE);
1218 
1219  LEAVE(" ");
1220 }
1221 
1222 static void
1223 gnc_plugin_page_invoice_cmd_reset_layout (GSimpleAction *simple,
1224  GVariant *paramter,
1225  gpointer user_data)
1226 {
1227  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1229  GAction *layout_action;
1230 
1231  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1232 
1233  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1234  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1235  gnc_invoice_window_reset_document_layout_and_clear_user_state (priv->iw);
1236 
1237  layout_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(plugin_page),
1238  "ViewResetLayoutAction");
1239  g_simple_action_set_enabled (G_SIMPLE_ACTION(layout_action), FALSE);
1240 
1241  LEAVE(" ");
1242 }
1243 
1244 static void
1245 gnc_plugin_page_invoice_cmd_link (GSimpleAction *simple,
1246  GVariant *paramter,
1247  gpointer user_data)
1248 {
1249  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1251  GtkWindow *parent;
1252  GncInvoice *invoice;
1253  const gchar *uri;
1254  gchar *ret_uri;
1255  gboolean has_uri = FALSE;
1256 
1257  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1258  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1259  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1260  parent = GTK_WINDOW(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
1261 
1262  invoice = gnc_invoice_window_get_invoice (priv->iw);
1263  uri = gncInvoiceGetDocLink (invoice);
1264 
1265  ret_uri = gnc_doclink_get_uri_dialog (parent, _("Manage Document Link"), uri);
1266 
1267  if (ret_uri)
1268  has_uri = TRUE;
1269 
1270  if (ret_uri && g_strcmp0 (uri, ret_uri) != 0)
1271  {
1272  GtkWidget *doclink_button =
1273  gnc_invoice_window_get_doclink_button (priv->iw);
1274 
1275  if (g_strcmp0 (ret_uri, "") == 0)
1276  {
1277  has_uri = FALSE;
1278  if (doclink_button)
1279  gtk_widget_hide (GTK_WIDGET(doclink_button));
1280  }
1281  else
1282  {
1283  if (doclink_button)
1284  {
1285  gchar *display_uri =
1286  gnc_doclink_get_unescaped_just_uri (ret_uri);
1287  gtk_link_button_set_uri (GTK_LINK_BUTTON(doclink_button),
1288  display_uri);
1289  gtk_widget_show (GTK_WIDGET(doclink_button));
1290  g_free (display_uri);
1291  }
1292  }
1293  gncInvoiceSetDocLink (invoice, ret_uri);
1294  }
1295  // update the menu actions
1296  update_doclink_actions (GNC_PLUGIN_PAGE(plugin_page), has_uri);
1297 
1298  g_free (ret_uri);
1299  LEAVE(" ");
1300 }
1301 
1302 static void
1303 gnc_plugin_page_invoice_cmd_link_open (GSimpleAction *simple,
1304  GVariant *paramter,
1305  gpointer user_data)
1306 {
1307  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1309  GtkWindow *parent;
1310  GncInvoice *invoice;
1311  const gchar *uri = NULL;
1312 
1313  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1314  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1315  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1316  parent = GTK_WINDOW(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
1317 
1318  invoice = gnc_invoice_window_get_invoice (priv->iw);
1319  uri = gncInvoiceGetDocLink (invoice);
1320 
1321  if (uri)
1322  gnc_doclink_open_uri (parent, uri);
1323 
1324  LEAVE(" ");
1325 }
1326 
1327 static void
1328 gnc_plugin_page_invoice_cmd_company_report (GSimpleAction *simple,
1329  GVariant *paramter,
1330  gpointer user_data)
1331 {
1332  auto plugin_page = GNC_PLUGIN_PAGE_INVOICE (user_data);
1334  GtkWindow *parent;
1335 
1336  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1337 
1338  ENTER("(action %p, plugin_page %p)", simple, plugin_page);
1339  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
1340  parent = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page)));
1341  gnc_invoice_window_report_owner_cb (parent, priv->iw);
1342  LEAVE(" ");
1343 }
1344 
1345 /************************************************************/
1346 /* Auxiliary functions */
1347 /************************************************************/
1348 
1349 static void
1350 gnc_plugin_page_redraw_help_cb (GnucashRegister *g_reg,
1351  GncPluginPageInvoice *invoice_page)
1352 {
1354  GncWindow *window;
1355  const char *status;
1356  char *help;
1357 
1358  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(invoice_page));
1359 
1360  window = GNC_WINDOW(GNC_PLUGIN_PAGE(invoice_page)->window);
1361 
1362  /* Get the text from the ledger */
1363  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(invoice_page);
1364  help = gnc_invoice_get_help(priv->iw);
1365  status = help ? help : g_strdup("");
1366  gnc_window_set_status(window, GNC_PLUGIN_PAGE(invoice_page), status);
1367  g_free(help);
1368 }
1369 
1370 static void
1371 gnc_plugin_page_show_popup_cb (GnucashRegister *g_reg,
1372  GncPluginPageInvoice *invoice_page)
1373 {
1374  GncWindow *window;
1375 
1376  g_return_if_fail (GNC_IS_PLUGIN_PAGE_INVOICE(invoice_page));
1377 
1378  window = GNC_WINDOW(GNC_PLUGIN_PAGE(invoice_page)->window);
1379 
1380  if (!window)
1381  {
1382  // This routine can be called before the page is added to a
1383  // window.
1384  return;
1385  }
1386  gnc_main_window_popup_menu_cb (GTK_WIDGET(window),
1387  GNC_PLUGIN_PAGE(invoice_page));
1388 }
1389 
1390 void
1392 {
1393  GncPluginPageInvoice *page;
1395  gchar *title;
1396 
1397  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
1398 
1399  page = GNC_PLUGIN_PAGE_INVOICE(plugin_page);
1400  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(page);
1401  title = gnc_invoice_get_title(priv->iw);
1402  main_window_update_page_name(plugin_page, title);
1403  g_free(title);
1404 }
1405 
1406 static void
1407 gnc_plugin_page_invoice_refresh_cb (GHashTable *changes, gpointer user_data)
1408 {
1409  auto page = GNC_PLUGIN_PAGE_INVOICE(user_data);
1411  GtkWidget *reg;
1412 
1413  g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(page));
1414 
1415  /* We're only looking for forced updates here. */
1416  if (changes)
1417  return;
1418 
1419  priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(page);
1420  reg = gnc_invoice_get_register(priv->iw);
1421  gnucash_register_refresh_from_prefs(GNUCASH_REGISTER(reg));
1422  gtk_widget_queue_draw(priv->widget);
1423 }
Public declarations for GncLedgerDisplay class.
utility functions for the GnuCash UI
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.
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...
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.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
Definition: gnc-prefs.c:128
This file contains the functions to present a gui to the user for creating a new account or editing a...
utility functions for the GnuCash UI
gtk helper routines.
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_menu_add_accelerator_keys(GncMainWindow *window)
Scan the main window menu and add accelerator keys to main window accelerator group.
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.
A structure for defining alternate action names for use in the toolbar.
Definition: gnc-plugin.h:204
GtkWidget * window
The window that contains the display widget for this plugin.
GSimpleActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
Create the GSimpleActionGroup object associated with this page.
gboolean gnc_main_window_update_menu_for_action(GncMainWindow *window, const gchar *action_name, const gchar *label, const gchar *tooltip)
Find the GMenuModel item given the action name for the window specified.
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
void gnc_plugin_page_invoice_update_menus(GncPluginPage *page, gboolean is_posted, gboolean can_unpost)
Update the menu items associated with this invoice page.
GncPluginPage * gnc_main_window_get_current_page(GncMainWindow *window)
Retrieve a pointer to the page that is currently at the front of the specified window.
void(* destroy_widget)(GncPluginPage *plugin_page)
Function called to destroy the display widget for a particular type of plugin.
The class data structure for a content plugin.
Gobject helper routines.
GAction * gnc_main_window_find_action(GncMainWindow *window, const gchar *action_name)
Find the GAction in the main window.
GncPluginPage * gnc_plugin_page_invoice_new(InvoiceWindow *iw)
Create a new "invoice" plugin page, given a pointer to an InvoiceWindow data structure.
void gnc_plugin_page_disconnect_page_changed(GncPluginPage *page)
Disconnect the page_changed_id signal callback.
void(* window_changed)(GncPluginPage *plugin_page, GtkWidget *window)
Perform plugin specific actions when a page is added to a window (or has been removed from one window...
gboolean gnc_main_window_popup_menu_cb(GtkWidget *widget, GncPluginPage *page)
Callback function invoked when the user requests that Gnucash popup the contextual menu via the keybo...
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.
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.
void gnc_ui_new_account_window(GtkWindow *parent, QofBook *book, Account *parent_acct)
Display a window for creating a new account.
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...
Generic api to store and retrieve preferences.
Business Invoice Interface.
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.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
void gnc_plugin_page_inserted_cb(GncPluginPage *page, gpointer user_data)
Set up the page_changed callback for when the current page is changed.
Functions for adding plugins to a GnuCash window.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
void gnc_plugin_page_add_book(GncPluginPage *page, QofBook *book)
Add a book reference to the specified page.
Utility functions for convert uri in separate components and back.
The instance data structure for a main window object.
void main_window_update_page_name(GncPluginPage *page, const gchar *name_in)
Update the name of the page in the main window.
GAction * gnc_plugin_page_get_action(GncPluginPage *page, const gchar *name)
Retrieve a GAction object associated with this page.
GtkWidget * gnc_main_window_toolbar_find_tool_item(GncMainWindow *window, const gchar *action_name)
Find the toolbar item with the given action name for the window specified.
InvoiceWindow * gnc_plugin_page_invoice_get_window(GncInvoice *invoice)
Find the Invoice Window amongst the plugin pages for an Invoice, if not present return NULL...
GtkWidget * summarybar
The summary bar widget (if any) that is associated with this plugin.
void gnc_plugin_page_invoice_update_title(GncPluginPage *plugin_page)
Update the title associated with this invoice page.
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Remove a function that was registered for a callback when the given preference changed.
Definition: gnc-prefs.c:143
const char * action_name
The name of the action.
Definition: gnc-plugin.h:207