GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-plugin-page-register.c
Go to the documentation of this file.
1 /**********************************************************************
2  * gnc-plugin-page-register.c -- register page functions *
3  * *
4  * Copyright (C) 2003 Jan Arne Petersen <[email protected]> *
5  * Copyright (C) 2003,2005,2006 David Hampton <[email protected]> *
6  * Copyright (C) 2011, Robert Fewell *
7  * *
8  * This program is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU General Public License as *
10  * published by the Free Software Foundation; either version 2 of *
11  * the License, or (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, contact: *
20  * *
21  * Free Software Foundation Voice: +1-617-542-5942 *
22  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
23  * Boston, MA 02110-1301, USA [email protected] *
24  **********************************************************************/
25 
36 #include "config.h"
37 
38 #include <libguile.h>
39 #include "guile-mappings.h"
40 #include <gtk/gtk.h>
41 #include <glib/gi18n.h>
42 #include "swig-runtime.h"
43 
45 /*################## Added for Reg2 #################*/
46 #include "gnc-plugin-page-register2.h"
47 /*################## Added for Reg2 #################*/
48 #include "gnc-plugin-register.h"
50 #include "gnc-plugin-page-report.h"
51 
52 #include "dialog-account.h"
53 #include "dialog-find-transactions.h"
54 #include "dialog-print-check.h"
55 #include "dialog-transfer.h"
56 #include "dialog-utils.h"
57 #include "assistant-stock-split.h"
58 #include "gnc-component-manager.h"
59 #include "gnc-date.h"
60 #include "gnc-date-edit.h"
61 #include "gnc-engine.h"
62 #include "gnc-event.h"
63 #include "gnc-gnome-utils.h"
64 #include "gnc-gobject-utils.h"
65 #include "gnc-gui-query.h"
66 #include "gnc-icons.h"
67 #include "gnc-split-reg.h"
68 #include "gnc-prefs.h"
69 #include "gnc-ui-util.h"
70 #include "gnc-window.h"
71 #include "gnc-main-window.h"
72 #include "gnc-session.h"
73 #include "gnome-utils/gnc-warnings.h"
74 #include "gnucash-sheet.h"
75 #include "dialog-lot-viewer.h"
76 #include "Scrub.h"
77 #include "ScrubBusiness.h"
78 #include "qof.h"
79 #include "window-reconcile.h"
80 #include "window-autoclear.h"
81 #include "window-report.h"
82 #include "engine-helpers.h"
83 #include "qofbookslots.h"
84 
85 /* This static indicates the debugging module that this .o belongs to. */
86 static QofLogModule log_module = GNC_MOD_GUI;
87 
88 #define DEFAULT_LINES_AMOUNT 50
89 
90 static void gnc_plugin_page_register_class_init (GncPluginPageRegisterClass *klass);
91 static void gnc_plugin_page_register_init (GncPluginPageRegister *plugin_page);
92 static void gnc_plugin_page_register_finalize (GObject *object);
93 
94 /* static Account *gnc_plugin_page_register_get_current_account (GncPluginPageRegister *page); */
95 
96 static GtkWidget *gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page);
97 static void gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page);
98 static void gnc_plugin_page_register_window_changed (GncPluginPage *plugin_page, GtkWidget *window);
99 static void gnc_plugin_page_register_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
100 static GncPluginPage *gnc_plugin_page_register_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
101 static void gnc_plugin_page_register_update_edit_menu (GncPluginPage *page, gboolean hide);
102 static gboolean gnc_plugin_page_register_finish_pending (GncPluginPage *page);
103 
104 static gchar *gnc_plugin_page_register_get_tab_name (GncPluginPage *plugin_page);
105 static gchar *gnc_plugin_page_register_get_tab_color (GncPluginPage *plugin_page);
106 static gchar *gnc_plugin_page_register_get_long_name (GncPluginPage *plugin_page);
107 
108 static void gnc_plugin_page_register_summarybar_position_changed(gpointer prefs, gchar* pref, gpointer user_data);
109 
110 /* Callbacks for the "Sort By" dialog */
111 void gnc_plugin_page_register_sort_button_cb(GtkToggleButton *button, GncPluginPageRegister *page);
112 void gnc_plugin_page_register_sort_response_cb(GtkDialog *dialog, gint response, GncPluginPageRegister *plugin_page);
113 void gnc_plugin_page_register_sort_order_save_cb(GtkToggleButton *button, GncPluginPageRegister *page);
114 void gnc_plugin_page_register_sort_order_reverse_cb(GtkToggleButton *button, GncPluginPageRegister *page);
115 
116 static gchar *gnc_plugin_page_register_get_sort_order (GncPluginPage *plugin_page);
117 void gnc_plugin_page_register_set_sort_order (GncPluginPage *plugin_page, const gchar *sort_order);
118 
119 /* Callbacks for the "Filter By" dialog */
123 void gnc_plugin_page_register_filter_response_cb(GtkDialog *dialog, gint response, GncPluginPageRegister *plugin_page);
124 void gnc_plugin_page_register_filter_status_all_cb(GtkButton *button, GncPluginPageRegister *plugin_page);
125 void gnc_plugin_page_register_filter_status_one_cb(GtkToggleButton *button, GncPluginPageRegister *page);
126 void gnc_plugin_page_register_filter_save_cb(GtkToggleButton *button, GncPluginPageRegister *page);
127 
128 static time64 gnc_plugin_page_register_filter_dmy2time (char *date_string);
129 static gchar *gnc_plugin_page_register_filter_time2dmy (time64 raw_time);
130 static gchar *gnc_plugin_page_register_get_filter (GncPluginPage *plugin_page);
131 void gnc_plugin_page_register_set_filter (GncPluginPage *plugin_page, const gchar *filter);
132 
133 static void gnc_ppr_update_status_query (GncPluginPageRegister *page);
134 static void gnc_ppr_update_date_query (GncPluginPageRegister *page);
135 
136 /* Command callbacks */
137 static void gnc_plugin_page_register_cmd_print_check (GtkAction *action, GncPluginPageRegister *plugin_page);
138 static void gnc_plugin_page_register_cmd_cut (GtkAction *action, GncPluginPageRegister *plugin_page);
139 static void gnc_plugin_page_register_cmd_copy (GtkAction *action, GncPluginPageRegister *plugin_page);
140 static void gnc_plugin_page_register_cmd_paste (GtkAction *action, GncPluginPageRegister *plugin_page);
141 static void gnc_plugin_page_register_cmd_edit_account (GtkAction *action, GncPluginPageRegister *plugin_page);
142 static void gnc_plugin_page_register_cmd_find_transactions (GtkAction *action, GncPluginPageRegister *plugin_page);
143 static void gnc_plugin_page_register_cmd_cut_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
144 static void gnc_plugin_page_register_cmd_copy_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
145 static void gnc_plugin_page_register_cmd_paste_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
146 static void gnc_plugin_page_register_cmd_void_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
147 static void gnc_plugin_page_register_cmd_unvoid_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
148 static void gnc_plugin_page_register_cmd_reverse_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
149 static void gnc_plugin_page_register_cmd_view_sort_by (GtkAction *action, GncPluginPageRegister *plugin_page);
150 static void gnc_plugin_page_register_cmd_view_filter_by (GtkAction *action, GncPluginPageRegister *plugin_page);
151 static void gnc_plugin_page_register_cmd_style_changed (GtkAction *action, GtkRadioAction *current, GncPluginPageRegister *plugin_page);
152 static void gnc_plugin_page_register_cmd_style_double_line (GtkToggleAction *action, GncPluginPageRegister *plugin_page);
153 
154 static void gnc_plugin_page_register_cmd_reconcile (GtkAction *action, GncPluginPageRegister *plugin_page);
155 static void gnc_plugin_page_register_cmd_autoclear (GtkAction *action, GncPluginPageRegister *plugin_page);
156 static void gnc_plugin_page_register_cmd_transfer (GtkAction *action, GncPluginPageRegister *plugin_page);
157 static void gnc_plugin_page_register_cmd_stock_split (GtkAction *action, GncPluginPageRegister *plugin_page);
158 static void gnc_plugin_page_register_cmd_lots (GtkAction *action, GncPluginPageRegister *plugin_page);
159 static void gnc_plugin_page_register_cmd_enter_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
160 static void gnc_plugin_page_register_cmd_cancel_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
161 static void gnc_plugin_page_register_cmd_delete_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
162 static void gnc_plugin_page_register_cmd_blank_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
163 static void gnc_plugin_page_register_cmd_duplicate_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
164 static void gnc_plugin_page_register_cmd_reinitialize_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
165 static void gnc_plugin_page_register_cmd_expand_transaction (GtkToggleAction *action, GncPluginPageRegister *plugin_page);
166 static void gnc_plugin_page_register_cmd_exchange_rate (GtkAction *action, GncPluginPageRegister *plugin_page);
167 static void gnc_plugin_page_register_cmd_jump (GtkAction *action, GncPluginPageRegister *plugin_page);
168 static void gnc_plugin_page_register_cmd_schedule (GtkAction *action, GncPluginPageRegister *plugin_page);
169 static void gnc_plugin_page_register_cmd_scrub_all (GtkAction *action, GncPluginPageRegister *plugin_page);
170 static void gnc_plugin_page_register_cmd_scrub_current (GtkAction *action, GncPluginPageRegister *plugin_page);
171 static void gnc_plugin_page_register_cmd_account_report (GtkAction *action, GncPluginPageRegister *plugin_page);
172 static void gnc_plugin_page_register_cmd_transaction_report (GtkAction *action, GncPluginPageRegister *plugin_page);
173 static void gnc_plugin_page_register_cmd_associate_file_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
174 static void gnc_plugin_page_register_cmd_associate_location_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
175 static void gnc_plugin_page_register_cmd_execassociated_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
176 
177 static void gnc_plugin_page_help_changed_cb( GNCSplitReg *gsr, GncPluginPageRegister *register_page );
178 static void gnc_plugin_page_register_refresh_cb (GHashTable *changes, gpointer user_data);
179 static void gnc_plugin_page_register_close_cb (gpointer user_data);
180 
181 static void gnc_plugin_page_register_ui_update (gpointer various, GncPluginPageRegister *page);
182 static void gppr_account_destroy_cb (Account *account);
183 static void gnc_plugin_page_register_event_handler (QofInstance *entity,
184  QofEventId event_type,
185  GncPluginPageRegister *page,
186  GncEventData *ed);
187 
188 /************************************************************/
189 /* Actions */
190 /************************************************************/
191 
192 #define CUT_TRANSACTION_LABEL N_("Cu_t Transaction")
193 #define COPY_TRANSACTION_LABEL N_("_Copy Transaction")
194 #define PASTE_TRANSACTION_LABEL N_("_Paste Transaction")
195 #define DUPLICATE_TRANSACTION_LABEL N_("Dup_licate Transaction")
196 #define DELETE_TRANSACTION_LABEL N_("_Delete Transaction")
197 #define ASSOCIATE_TRANSACTION_FILE_LABEL N_("_Associate File with Transaction")
198 #define ASSOCIATE_TRANSACTION_LOCATION_LABEL N_("_Associate Location with Transaction")
199 #define EXECASSOCIATED_TRANSACTION_LABEL N_("_Open Associated File/Location")
200 #define CUT_SPLIT_LABEL N_("Cu_t Split")
201 #define COPY_SPLIT_LABEL N_("_Copy Split")
202 #define PASTE_SPLIT_LABEL N_("_Paste Split")
203 #define DUPLICATE_SPLIT_LABEL N_("Dup_licate Split")
204 #define DELETE_SPLIT_LABEL N_("_Delete Split")
205 #define CUT_TRANSACTION_TIP N_("Cut the selected transaction into clipboard")
206 #define COPY_TRANSACTION_TIP N_("Copy the selected transaction into clipboard")
207 #define PASTE_TRANSACTION_TIP N_("Paste the transaction from the clipboard")
208 #define DUPLICATE_TRANSACTION_TIP N_("Make a copy of the current transaction")
209 #define DELETE_TRANSACTION_TIP N_("Delete the current transaction")
210 #define ASSOCIATE_TRANSACTION_FILE_TIP N_("Associate a file with the current transaction")
211 #define ASSOCIATE_TRANSACTION_LOCATION_TIP N_("Associate a location with the current transaction")
212 #define EXECASSOCIATED_TRANSACTION_TIP N_("Open the associated file or location with the current transaction")
213 #define CUT_SPLIT_TIP N_("Cut the selected split into clipboard")
214 #define COPY_SPLIT_TIP N_("Copy the selected split into clipboard")
215 #define PASTE_SPLIT_TIP N_("Paste the split from the clipboard")
216 #define DUPLICATE_SPLIT_TIP N_("Make a copy of the current split")
217 #define DELETE_SPLIT_TIP N_("Delete the current split")
218 
219 static GtkActionEntry gnc_plugin_page_register_actions [] =
220 {
221  /* File menu */
222 
223  {
224  "FilePrintAction", GTK_STOCK_PRINT, N_("_Print Checks..."), "<control>p", NULL,
225  G_CALLBACK (gnc_plugin_page_register_cmd_print_check)
226  },
227 
228  /* Edit menu */
229 
230  {
231  "EditCutAction", GTK_STOCK_CUT, N_("Cu_t"), NULL,
232  N_("Cut the current selection and copy it to clipboard"),
233  G_CALLBACK (gnc_plugin_page_register_cmd_cut)
234  },
235  {
236  "EditCopyAction", GTK_STOCK_COPY, N_("_Copy"), NULL,
237  N_("Copy the current selection to clipboard"),
238  G_CALLBACK (gnc_plugin_page_register_cmd_copy)
239  },
240  {
241  "EditPasteAction", GTK_STOCK_PASTE, N_("_Paste"), NULL,
242  N_("Paste the clipboard content at the cursor position"),
243  G_CALLBACK (gnc_plugin_page_register_cmd_paste)
244  },
245  {
246  "EditEditAccountAction", GNC_STOCK_EDIT_ACCOUNT, N_("Edit _Account"), "<control>e",
247  N_("Edit the selected account"),
248  G_CALLBACK (gnc_plugin_page_register_cmd_edit_account)
249  },
250  {
251  "EditFindTransactionsAction", GTK_STOCK_FIND, N_("_Find..."), "<control>f",
252  N_("Find transactions with a search"),
253  G_CALLBACK (gnc_plugin_page_register_cmd_find_transactions)
254  },
255 
256  /* Transaction menu */
257 
258  {
259  "CutTransactionAction", GTK_STOCK_CUT, CUT_TRANSACTION_LABEL, "",
260  CUT_TRANSACTION_TIP,
261  G_CALLBACK (gnc_plugin_page_register_cmd_cut_transaction)
262  },
263  {
264  "CopyTransactionAction", GTK_STOCK_COPY, COPY_TRANSACTION_LABEL, "",
265  COPY_TRANSACTION_TIP,
266  G_CALLBACK (gnc_plugin_page_register_cmd_copy_transaction)
267  },
268  {
269  "PasteTransactionAction", GTK_STOCK_PASTE, PASTE_TRANSACTION_LABEL, "",
270  PASTE_TRANSACTION_TIP,
271  G_CALLBACK (gnc_plugin_page_register_cmd_paste_transaction)
272  },
273  {
274  "DuplicateTransactionAction", GTK_STOCK_COPY, DUPLICATE_TRANSACTION_LABEL, "",
275  DUPLICATE_TRANSACTION_TIP,
276  G_CALLBACK (gnc_plugin_page_register_cmd_duplicate_transaction)
277  },
278  {
279  "DeleteTransactionAction", GTK_STOCK_DELETE, DELETE_TRANSACTION_LABEL, NULL,
280  DELETE_TRANSACTION_TIP,
281  G_CALLBACK (gnc_plugin_page_register_cmd_delete_transaction)
282  },
283  {
284  "RemoveTransactionSplitsAction", GTK_STOCK_CLEAR, N_("Remo_ve Other Splits"), NULL,
285  N_("Remove all splits in the current transaction"),
286  G_CALLBACK (gnc_plugin_page_register_cmd_reinitialize_transaction)
287  },
288  {
289  "RecordTransactionAction", GTK_STOCK_ADD, N_("_Enter Transaction"), NULL,
290  N_("Record the current transaction"),
291  G_CALLBACK (gnc_plugin_page_register_cmd_enter_transaction)
292  },
293  {
294  "CancelTransactionAction", GTK_STOCK_CANCEL, N_("Ca_ncel Transaction"), NULL,
295  N_("Cancel the current transaction"),
296  G_CALLBACK (gnc_plugin_page_register_cmd_cancel_transaction)
297  },
298  {
299  "VoidTransactionAction", NULL, N_("_Void Transaction"), NULL, NULL,
300  G_CALLBACK (gnc_plugin_page_register_cmd_void_transaction)
301  },
302  {
303  "UnvoidTransactionAction", NULL, N_("_Unvoid Transaction"), NULL, NULL,
304  G_CALLBACK (gnc_plugin_page_register_cmd_unvoid_transaction)
305  },
306  {
307  "ReverseTransactionAction", NULL, N_("Add _Reversing Transaction"), NULL, NULL,
308  G_CALLBACK (gnc_plugin_page_register_cmd_reverse_transaction)
309  },
310  {
311  "AssociateTransactionFileAction", NULL, ASSOCIATE_TRANSACTION_FILE_LABEL, NULL,
312  ASSOCIATE_TRANSACTION_FILE_TIP,
313  G_CALLBACK (gnc_plugin_page_register_cmd_associate_file_transaction)
314  },
315  {
316  "AssociateTransactionLocationAction", NULL, ASSOCIATE_TRANSACTION_LOCATION_LABEL, NULL,
317  ASSOCIATE_TRANSACTION_LOCATION_TIP,
318  G_CALLBACK (gnc_plugin_page_register_cmd_associate_location_transaction)
319  },
320  {
321  "ExecAssociatedTransactionAction", NULL, EXECASSOCIATED_TRANSACTION_LABEL, NULL,
322  EXECASSOCIATED_TRANSACTION_TIP,
323  G_CALLBACK (gnc_plugin_page_register_cmd_execassociated_transaction)
324  },
325 
326  /* View menu */
327 
328  {
329  "ViewSortByAction", NULL, N_("_Sort By..."), NULL, NULL,
330  G_CALLBACK (gnc_plugin_page_register_cmd_view_sort_by)
331  },
332  {
333  "ViewFilterByAction", NULL, N_("_Filter By..."), NULL, NULL,
334  G_CALLBACK (gnc_plugin_page_register_cmd_view_filter_by)
335  },
336 
337  /* Actions menu */
338 
339  {
340  "ActionsTransferAction", GNC_STOCK_TRANSFER, N_("_Transfer..."), "<control>t",
341  N_("Transfer funds from one account to another"),
342  G_CALLBACK (gnc_plugin_page_register_cmd_transfer)
343  },
344  {
345  "ActionsReconcileAction", GTK_STOCK_INDEX, N_("_Reconcile..."), NULL,
346  N_("Reconcile the selected account"),
347  G_CALLBACK (gnc_plugin_page_register_cmd_reconcile)
348  },
349  {
350  "ActionsAutoClearAction", GTK_STOCK_INDEX, N_("_Auto-clear..."), NULL,
351  N_("Automatically clear individual transactions, so as to reach a certain cleared amount"),
352  G_CALLBACK (gnc_plugin_page_register_cmd_autoclear)
353  },
354  {
355  "ActionsStockSplitAction", NULL, N_("Stoc_k Split..."), NULL,
356  N_("Record a stock split or a stock merger"),
357  G_CALLBACK (gnc_plugin_page_register_cmd_stock_split)
358  },
359  {
360  "ActionsLotsAction", NULL, N_("View _Lots..."), NULL,
361  N_("Bring up the lot viewer/editor window"),
362  G_CALLBACK (gnc_plugin_page_register_cmd_lots)
363  },
364  {
365  "BlankTransactionAction", GTK_STOCK_GOTO_BOTTOM, N_("_Blank Transaction"), "<control>Page_Down",
366  N_("Move to the blank transaction at the bottom of the register"),
367  G_CALLBACK (gnc_plugin_page_register_cmd_blank_transaction)
368  },
369  {
370  "EditExchangeRateAction", NULL, N_("Edit E_xchange Rate"), NULL,
371  N_("Edit the exchange rate for the current transaction"),
372  G_CALLBACK (gnc_plugin_page_register_cmd_exchange_rate)
373  },
374  {
375  "JumpTransactionAction", GNC_STOCK_JUMP_TO, N_("_Jump"), NULL,
376  N_("Jump to the corresponding transaction in the other account"),
377  G_CALLBACK (gnc_plugin_page_register_cmd_jump)
378  },
379  {
380  "ScheduleTransactionAction", GNC_STOCK_SCHEDULE, N_("Sche_dule..."), NULL,
381  N_("Create a Scheduled Transaction with the current transaction as a template"),
382  G_CALLBACK (gnc_plugin_page_register_cmd_schedule)
383  },
384  {
385  "ScrubAllAction", NULL, N_("_All transactions"), NULL, NULL,
386  G_CALLBACK (gnc_plugin_page_register_cmd_scrub_all)
387  },
388  {
389  "ScrubCurrentAction", NULL, N_("_This transaction"), NULL, NULL,
390  G_CALLBACK (gnc_plugin_page_register_cmd_scrub_current)
391  },
392 
393  /* Reports menu */
394 
395  {
396  "ReportsAccountReportAction", NULL, N_("Account Report"), NULL,
397  N_("Open a register report for this Account"),
398  G_CALLBACK (gnc_plugin_page_register_cmd_account_report)
399  },
400  {
401  "ReportsAcctTransReportAction", NULL, N_("Account Report - Single Transaction"), NULL,
402  N_("Open a register report for the selected Transaction"),
403  G_CALLBACK (gnc_plugin_page_register_cmd_transaction_report)
404  },
405 };
406 
407 static guint gnc_plugin_page_register_n_actions = G_N_ELEMENTS (gnc_plugin_page_register_actions);
408 
409 static GtkToggleActionEntry toggle_entries[] =
410 {
411  {
412  "ViewStyleDoubleLineAction", NULL, N_("_Double Line"), NULL,
413  N_("Show two lines of information for each transaction"),
414  G_CALLBACK (gnc_plugin_page_register_cmd_style_double_line), FALSE
415  },
416 
417  {
418  "SplitTransactionAction", GNC_STOCK_SPLIT_TRANS, N_("S_plit Transaction"), NULL,
419  N_("Show all splits in the current transaction"),
420  G_CALLBACK (gnc_plugin_page_register_cmd_expand_transaction), FALSE
421  },
422 };
423 
424 static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
425 
426 static GtkRadioActionEntry radio_entries_2 [] =
427 {
428  /* Translators: This is a menu item in the View menu */
429  {
430  "ViewStyleBasicAction", NULL, N_("_Basic Ledger"), NULL,
431  N_("Show transactions on one or two lines"), REG_STYLE_LEDGER
432  },
433  /* Translators: This is a menu item in the View menu */
434  {
435  "ViewStyleAutoSplitAction", NULL, N_("_Auto-Split Ledger"), NULL,
436  N_("Show transactions on one or two lines and expand the current transaction"), REG_STYLE_AUTO_LEDGER
437  },
438  /* Translators: This is a menu item in the View menu */
439  {
440  "ViewStyleJournalAction", NULL, N_("Transaction _Journal"), NULL,
441  N_("Show expanded transactions with all splits"), REG_STYLE_JOURNAL
442  }
443 };
444 
445 static guint n_radio_entries_2 = G_N_ELEMENTS (radio_entries_2);
446 
450 static const gchar *important_actions[] =
451 {
452  "SplitTransactionAction",
453  NULL,
454 };
455 
458 static const gchar *actions_requiring_account[] =
459 {
460  "EditEditAccountAction",
461  "ActionsReconcileAction",
462  "ActionsAutoClearAction",
463  "ActionsLotsAction",
464  NULL
465 };
466 
468 static const gchar *view_style_actions[] =
469 {
470  "ViewStyleBasicAction",
471  "ViewStyleAutoSplitAction",
472  "ViewStyleJournalAction",
473  NULL
474 };
475 
477 static action_toolbar_labels toolbar_labels[] =
478 {
479  { "ActionsTransferAction", N_("Transfer") },
480  { "RecordTransactionAction", N_("Enter") },
481  { "CancelTransactionAction", N_("Cancel") },
482  { "DeleteTransactionAction", N_("Delete") },
483  { "DuplicateTransactionAction", N_("Duplicate") },
484  { "SplitTransactionAction", N_("Split") },
485  { "ScheduleTransactionAction", N_("Schedule") },
486  { "BlankTransactionAction", N_("Blank") },
487  { "ActionsReconcileAction", N_("Reconcile") },
488  { "ActionsAutoClearAction", N_("Auto-clear") },
489  { "AssociateTransactionFileAction", N_("Associate File") },
490  { "AssociateTransactionLocationAction", N_("Associate Location") },
491  { "ExecAssociatedTransactionAction", N_("Open File/Location") },
492  { NULL, NULL },
493 };
494 
496 {
497  const char *action_name;
498  int value;
499  GtkWidget *widget;
500 };
501 
502 static struct status_action status_actions[] =
503 {
504  { "filter_status_reconciled", CLEARED_RECONCILED, NULL },
505  { "filter_status_cleared", CLEARED_CLEARED, NULL },
506  { "filter_status_voided", CLEARED_VOIDED, NULL },
507  { "filter_status_frozen", CLEARED_FROZEN, NULL },
508  { "filter_status_unreconciled", CLEARED_NO, NULL },
509  { NULL, 0, NULL },
510 };
511 
512 #define CLEARED_VALUE "cleared_value"
513 #define DEFAULT_FILTER "0x001f"
514 #define DEFAULT_SORT_ORDER "BY_STANDARD"
515 
516 /************************************************************/
517 /* Data Structures */
518 /************************************************************/
519 
521 {
522  GNCLedgerDisplay *ledger;
523  GNCSplitReg *gsr;
524 
525  GtkWidget *widget;
526 
527  gint event_handler_id;
528  gint component_manager_id;
529  GncGUID key; /* The guid of the Account we're watching */
530 
531  gint lines_default;
532  gboolean read_only;
533 
534  struct
535  {
536  GtkWidget *dialog;
537  GtkWidget *num_radio;
538  GtkWidget *act_radio;
539  SortType original_sort_type;
540  gboolean original_save_order;
541  gboolean save_order;
542  gboolean reverse_order;
543  } sd;
544 
545  struct
546  {
547  GtkWidget *dialog;
548  GtkWidget *table;
549  GtkWidget *start_date_choose;
550  GtkWidget *start_date_today;
551  GtkWidget *start_date;
552  GtkWidget *end_date_choose;
553  GtkWidget *end_date_today;
554  GtkWidget *end_date;
555  cleared_match_t original_cleared_match;
556  cleared_match_t cleared_match;
557  time64 original_start_time;
558  time64 original_end_time;
559  time64 start_time;
560  time64 end_time;
561  gboolean original_save_filter;
562  gboolean save_filter;
563  } fd;
565 
566 #define GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(o) \
567  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_PAGE_REGISTER, GncPluginPageRegisterPrivate))
568 
569 static GObjectClass *parent_class = NULL;
570 
571 /************************************************************/
572 /* Implementation */
573 /************************************************************/
574 
575 GType
577 {
578  static GType gnc_plugin_page_register_type = 0;
579 
580  if (gnc_plugin_page_register_type == 0)
581  {
582  static const GTypeInfo our_info =
583  {
585  NULL,
586  NULL,
587  (GClassInitFunc) gnc_plugin_page_register_class_init,
588  NULL,
589  NULL,
590  sizeof (GncPluginPageRegister),
591  0,
592  (GInstanceInitFunc) gnc_plugin_page_register_init
593  };
594 
595  gnc_plugin_page_register_type = g_type_register_static (GNC_TYPE_PLUGIN_PAGE,
596  GNC_PLUGIN_PAGE_REGISTER_NAME,
597  &our_info, 0);
598  }
599 
600  return gnc_plugin_page_register_type;
601 }
602 
603 static GncPluginPage *
604 gnc_plugin_page_register_new_common (GNCLedgerDisplay *ledger)
605 {
606  GncPluginPageRegister *register_page;
608  GncPluginPage *plugin_page;
609  GNCSplitReg *gsr;
610  const GList *item;
611  GList *book_list;
612  gchar *label;
613  gchar *label_color;
614  QofQuery *q;
615 
616  /* Is there an existing page? */
617  gsr = gnc_ledger_display_get_user_data (ledger);
618  if (gsr)
619  {
620  item = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_REGISTER_NAME);
621  for ( ; item; item = g_list_next(item))
622  {
623  register_page = (GncPluginPageRegister *)item->data;
624  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(register_page);
625  if (priv->gsr == gsr)
626  return GNC_PLUGIN_PAGE(register_page);
627  }
628  }
629 
630  register_page = g_object_new (GNC_TYPE_PLUGIN_PAGE_REGISTER, NULL);
631  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(register_page);
632  priv->ledger = ledger;
633  priv->key = *guid_null();
634 
635  plugin_page = GNC_PLUGIN_PAGE(register_page);
636  label = gnc_plugin_page_register_get_tab_name(plugin_page);
637  gnc_plugin_page_set_page_name(plugin_page, label);
638  g_free(label);
639 
640  label_color = gnc_plugin_page_register_get_tab_color(plugin_page);
641  gnc_plugin_page_set_page_color(plugin_page, label_color);
642  g_free(label_color);
643 
644  label = gnc_plugin_page_register_get_long_name(plugin_page);
645  gnc_plugin_page_set_page_long_name(plugin_page, label);
646  g_free(label);
647 
648  q = gnc_ledger_display_get_query (ledger);
649  book_list = qof_query_get_books (q);
650  for (item = book_list; item; item = g_list_next(item))
651  gnc_plugin_page_add_book (plugin_page, (QofBook *)item->data);
652  // Do not free the list. It is owned by the query.
653 
654  priv->component_manager_id = 0;
655  return plugin_page;
656 }
657 
659 gnc_plugin_page_register_new (Account *account, gboolean subaccounts)
660 {
661  GNCLedgerDisplay *ledger;
662  GncPluginPage *page;
664 
665 /*################## Added for Reg2 #################*/
666  const GList *item;
667  GncPluginPageRegister2 *new_register_page;
668 /*################## Added for Reg2 #################*/
669 
670  ENTER("account=%p, subaccounts=%s", account,
671  subaccounts ? "TRUE" : "FALSE");
672 
673 /*################## Added for Reg2 #################*/
674  // We test for the new register being open here, ie matching account guids
675  item = gnc_gobject_tracking_get_list (GNC_PLUGIN_PAGE_REGISTER2_NAME);
676  for ( ; item; item = g_list_next (item))
677  {
678  Account *new_account;
679  new_register_page = (GncPluginPageRegister2 *)item->data;
680  new_account = gnc_plugin_page_register2_get_account (new_register_page);
681 
682  if (guid_equal (xaccAccountGetGUID (account), xaccAccountGetGUID (new_account)))
683  {
684  gnc_error_dialog (NULL, "%s",
685  _("You have tried to open an account in the old register while it is open in the new register."));
686  return NULL;
687  }
688  }
689 /*################## Added for Reg2 #################*/
690 
691  if (subaccounts)
692  ledger = gnc_ledger_display_subaccounts (account);
693  else
694  ledger = gnc_ledger_display_simple (account);
695 
696  page = gnc_plugin_page_register_new_common(ledger);
697  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
698  priv->key = *xaccAccountGetGUID(account);
699 
700  LEAVE("%p", page);
701  return page;
702 }
703 
706 {
707  GNCLedgerDisplay *ledger;
708 
709  ledger = gnc_ledger_display_gl ();
710  return gnc_plugin_page_register_new_common(ledger);
711 }
712 
715 {
716  return gnc_plugin_page_register_new_common(ledger);
717 }
718 
719 static void
720 gnc_plugin_page_register_class_init (GncPluginPageRegisterClass *klass)
721 {
722  GObjectClass *object_class = G_OBJECT_CLASS (klass);
723  GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
724 
725  parent_class = g_type_class_peek_parent (klass);
726 
727  object_class->finalize = gnc_plugin_page_register_finalize;
728 
729  gnc_plugin_class->tab_icon = GNC_STOCK_ACCOUNT;
730  gnc_plugin_class->plugin_name = GNC_PLUGIN_PAGE_REGISTER_NAME;
731  gnc_plugin_class->create_widget = gnc_plugin_page_register_create_widget;
732  gnc_plugin_class->destroy_widget = gnc_plugin_page_register_destroy_widget;
733  gnc_plugin_class->window_changed = gnc_plugin_page_register_window_changed;
734  gnc_plugin_class->save_page = gnc_plugin_page_register_save_page;
735  gnc_plugin_class->recreate_page = gnc_plugin_page_register_recreate_page;
736  gnc_plugin_class->update_edit_menu_actions = gnc_plugin_page_register_update_edit_menu;
737  gnc_plugin_class->finish_pending = gnc_plugin_page_register_finish_pending;
738 
739  g_type_class_add_private(klass, sizeof(GncPluginPageRegisterPrivate));
740 
741  gnc_ui_register_account_destroy_callback (gppr_account_destroy_cb);
742 }
743 
744 static void
745 gnc_plugin_page_register_init (GncPluginPageRegister *plugin_page)
746 {
748  GncPluginPage *parent;
749  GtkActionGroup *action_group;
750  gboolean use_new;
751 
752  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
753 
754  /* Init parent declared variables */
755  parent = GNC_PLUGIN_PAGE(plugin_page);
756  use_new = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_USE_NEW);
757  g_object_set(G_OBJECT(plugin_page),
758  "page-name", _("General Ledger"),
759  "page-uri", "default:",
760  "ui-description", "gnc-plugin-page-register-ui.xml",
761  "use-new-window", use_new,
762  NULL);
763 
764  /* Create menu and toolbar information */
765  action_group =
767  "GncPluginPageRegisterActions");
768  gtk_action_group_add_actions (action_group, gnc_plugin_page_register_actions,
769  gnc_plugin_page_register_n_actions, plugin_page);
770  gtk_action_group_add_toggle_actions (action_group,
771  toggle_entries, n_toggle_entries,
772  plugin_page);
773  gtk_action_group_add_radio_actions (action_group,
774  radio_entries_2, n_radio_entries_2,
775  REG_STYLE_LEDGER,
776  G_CALLBACK(gnc_plugin_page_register_cmd_style_changed),
777  plugin_page);
778 
779  gnc_plugin_init_short_names (action_group, toolbar_labels);
780  gnc_plugin_set_important_actions (action_group, important_actions);
781 
782  priv->lines_default = DEFAULT_LINES_AMOUNT;
783  priv->read_only = FALSE;
784  priv->fd.cleared_match = CLEARED_ALL;
785 }
786 
787 static void
788 gnc_plugin_page_register_finalize (GObject *object)
789 {
790  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (object));
791 
792  ENTER("object %p", object);
793 
794  G_OBJECT_CLASS (parent_class)->finalize (object);
795  LEAVE(" ");
796 }
797 
798 Account *
800 {
802  GNCLedgerDisplayType ledger_type;
803  Account *leader;
804 
805  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
806  ledger_type = gnc_ledger_display_type (priv->ledger);
807  leader = gnc_ledger_display_leader (priv->ledger);
808 
809  if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
810  return leader;
811  return NULL;
812 }
813 
814 /* This is the list of actions which are switched inactive in a read-only book. */
815 static const char* readonly_inactive_actions[] =
816 {
817  "EditCutAction",
818  "EditPasteAction",
819  "CutTransactionAction",
820  "PasteTransactionAction",
821  "DuplicateTransactionAction",
822  "DeleteTransactionAction",
823  "RemoveTransactionSplitsAction",
824  "RecordTransactionAction",
825  "CancelTransactionAction",
826  "UnvoidTransactionAction",
827  "VoidTransactionAction",
828  "ReverseTransactionAction",
829  "ActionsTransferAction",
830  "ActionsReconcileAction",
831  "ActionsStockSplitAction",
832  "ScheduleTransactionAction",
833  "ScrubAllAction",
834  "ScrubCurrentAction",
835  "AssociateTransactionFileAction",
836  "AssociateTransactionLocationAction",
837  NULL
838 };
839 
840 /* This is the list of actions whose text needs to be changed based on whether */
841 /* the current cursor class is transaction or split. */
842 static const char* tran_vs_split_actions[] =
843 {
844  "CutTransactionAction",
845  "CopyTransactionAction",
846  "PasteTransactionAction",
847  "DuplicateTransactionAction",
848  "DeleteTransactionAction",
849  NULL
850 };
851 
852 /* This is the list of labels for when the current cursor class is transaction. */
853 static const char* tran_action_labels[] =
854 {
855  CUT_TRANSACTION_LABEL,
856  COPY_TRANSACTION_LABEL,
857  PASTE_TRANSACTION_LABEL,
858  DUPLICATE_TRANSACTION_LABEL,
859  DELETE_TRANSACTION_LABEL,
860  ASSOCIATE_TRANSACTION_FILE_LABEL,
861  ASSOCIATE_TRANSACTION_LOCATION_LABEL,
862  EXECASSOCIATED_TRANSACTION_LABEL,
863  NULL
864 };
865 
866 /* This is the list of tooltips for when the current cursor class is transaction. */
867 static const char* tran_action_tips[] =
868 {
869  CUT_TRANSACTION_TIP,
870  COPY_TRANSACTION_TIP,
871  PASTE_TRANSACTION_TIP,
872  DUPLICATE_TRANSACTION_TIP,
873  DELETE_TRANSACTION_TIP,
874  ASSOCIATE_TRANSACTION_FILE_TIP,
875  ASSOCIATE_TRANSACTION_LOCATION_TIP,
876  EXECASSOCIATED_TRANSACTION_TIP,
877  NULL
878 };
879 
880 /* This is the list of labels for when the current cursor class is split. */
881 static const char* split_action_labels[] =
882 {
883  CUT_SPLIT_LABEL,
884  COPY_SPLIT_LABEL,
885  PASTE_SPLIT_LABEL,
886  DUPLICATE_SPLIT_LABEL,
887  DELETE_SPLIT_LABEL,
888  NULL
889 };
890 
891 /* This is the list of tooltips for when the current cursor class is split. */
892 static const char* split_action_tips[] =
893 {
894  CUT_SPLIT_TIP,
895  COPY_SPLIT_TIP,
896  PASTE_SPLIT_TIP,
897  DUPLICATE_SPLIT_TIP,
898  DELETE_SPLIT_TIP,
899  NULL
900 };
901 
902 static void
903 gnc_plugin_page_register_ui_update (gpointer various, GncPluginPageRegister *page)
904 {
906  SplitRegister *reg;
907  GtkAction *action;
908  gboolean expanded, voided;
909  Transaction *trans;
910  const char *uri;
911 
912  /* Set 'Split Transaction' */
913  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
914  reg = gnc_ledger_display_get_split_register(priv->ledger);
916  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
917  "SplitTransactionAction");
918  gtk_action_set_sensitive (action, reg->style == REG_STYLE_LEDGER);
919  g_signal_handlers_block_by_func
920  (action, gnc_plugin_page_register_cmd_expand_transaction, page);
921  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action), expanded);
922  g_signal_handlers_unblock_by_func
923  (action, gnc_plugin_page_register_cmd_expand_transaction, page);
924 
925  /* Set 'Void' and 'Unvoid' */
927  voided = xaccTransHasSplitsInState(trans, VREC);
928  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
929  "VoidTransactionAction");
930  gtk_action_set_sensitive (GTK_ACTION(action), !voided);
931 
932  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
933  "UnvoidTransactionAction");
934  gtk_action_set_sensitive (GTK_ACTION(action), voided);
935 
936  /* Set 'ExecAssociated' */
937  uri = xaccTransGetAssociation(trans);
938  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
939  "ExecAssociatedTransactionAction");
940  gtk_action_set_sensitive (GTK_ACTION(action), uri ? TRUE:FALSE);
941 
942  /* If we are in a readonly book, make any modifying action inactive */
943  if (qof_book_is_readonly(gnc_get_current_book()))
944  {
945  const char **iter;
946  for (iter = readonly_inactive_actions; *iter; ++iter)
947  {
948  /* Set the action's sensitivity */
949  GtkAction *action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), *iter);
950  gtk_action_set_sensitive(action, FALSE);
951  }
952  }
953 
954  /* Modifying action descriptions based on cursor class */
955  {
956  const char **iter, **label_iter, **tooltip_iter;
957  gboolean curr_label_trans = FALSE;
959  iter = tran_vs_split_actions;
960  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), *iter);
961  label_iter = tran_action_labels;
962  if (g_strcmp0 (gtk_action_get_label(action), _(*label_iter)) == 0)
963  curr_label_trans = TRUE;
964  if ((cursor_class == CURSOR_CLASS_SPLIT) && curr_label_trans)
965  {
966  label_iter = split_action_labels;
967  tooltip_iter = split_action_tips;
968  for (iter = tran_vs_split_actions; *iter; ++iter)
969  {
970  /* Adjust the action's label and tooltip */
971  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), *iter);
972  gtk_action_set_label(action, _(*label_iter));
973  gtk_action_set_tooltip(action, _(*tooltip_iter));
974  ++label_iter;
975  ++tooltip_iter;
976  }
977  }
978  else if ((cursor_class == CURSOR_CLASS_TRANS) && !curr_label_trans)
979  {
980  label_iter = tran_action_labels;
981  tooltip_iter = tran_action_tips;
982  for (iter = tran_vs_split_actions; *iter; ++iter)
983  {
984  /* Adjust the action's label and tooltip */
985  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), *iter);
986  gtk_action_set_label(action, _(*label_iter));
987  gtk_action_set_tooltip(action, _(*tooltip_iter));
988  ++label_iter;
989  ++tooltip_iter;
990  }
991  }
992  }
993 }
994 
995 static void
996 gnc_plugin_page_register_ui_initial_state (GncPluginPageRegister *page)
997 {
999  GtkActionGroup *action_group;
1000  GtkAction *action;
1001  Account *account;
1002  SplitRegister *reg;
1003  GNCLedgerDisplayType ledger_type;
1004  int i;
1005  gboolean is_readwrite = !qof_book_is_readonly(gnc_get_current_book());
1006 
1007  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1008  account = gnc_plugin_page_register_get_account (page);
1009  action_group = gnc_plugin_page_get_action_group(GNC_PLUGIN_PAGE(page));
1010  gnc_plugin_update_actions(action_group, actions_requiring_account,
1011  "sensitive", is_readwrite && account != NULL);
1012 
1013  /* Set "style" radio button */
1014  ledger_type = gnc_ledger_display_type(priv->ledger);
1015  gnc_plugin_update_actions(action_group, view_style_actions,
1016  "sensitive", ledger_type == LD_SINGLE);
1017 
1018  reg = gnc_ledger_display_get_split_register(priv->ledger);
1019  for (i = n_radio_entries_2 - 1; i > 0; i--)
1020  {
1021  DEBUG(" index %d: comparing %x to %x", i, radio_entries_2[i].value,
1022  reg->style);
1023  if (radio_entries_2[i].value == reg->style)
1024  {
1025  DEBUG("match");
1026  break;
1027  }
1028  }
1029 
1030  /* Either a match was found, or fell out with i = 0 */
1031  action = gtk_action_group_get_action(action_group, radio_entries_2[i].name);
1032  g_signal_handlers_block_by_func(action, gnc_plugin_page_register_cmd_style_changed, page);
1033  gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
1034  g_signal_handlers_unblock_by_func(action, gnc_plugin_page_register_cmd_style_changed, page);
1035 
1036  /* Set "double line" toggle button */
1037  action = gtk_action_group_get_action (action_group,
1038  "ViewStyleDoubleLineAction");
1039  g_signal_handlers_block_by_func(action, gnc_plugin_page_register_cmd_style_double_line, page);
1040  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action), reg->use_double_line);
1041  g_signal_handlers_unblock_by_func(action, gnc_plugin_page_register_cmd_style_double_line, page);
1042 }
1043 
1044 /* Virtual Functions */
1045 
1046 static GtkWidget *
1047 gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page)
1048 {
1049  GncPluginPageRegister *page;
1051  GNCLedgerDisplayType ledger_type;
1052  GncWindow *gnc_window;
1053  guint numRows;
1054  GtkWidget *gsr;
1055  SplitRegister *reg;
1056  Account *acct;
1057  gchar **filter;
1058  gchar *order;
1059  int filter_changed = 0;
1060 
1061  ENTER("page %p", plugin_page);
1062  page = GNC_PLUGIN_PAGE_REGISTER (plugin_page);
1063  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1064 
1065  if (priv->widget != NULL)
1066  {
1067  LEAVE("existing widget %p", priv->widget);
1068  return priv->widget;
1069  }
1070 
1071  priv->widget = gtk_vbox_new (FALSE, 0);
1072  gtk_widget_show (priv->widget);
1073 
1074  numRows = priv->lines_default;
1075  numRows = MIN(numRows, DEFAULT_LINES_AMOUNT);
1076 
1077  gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window);
1078  gsr = gnc_split_reg_new(priv->ledger,
1079  gnc_window_get_gtk_window(gnc_window),
1080  numRows, priv->read_only);
1081  priv->gsr = (GNCSplitReg *)gsr;
1082  gtk_widget_show (gsr);
1083  gtk_box_pack_start (GTK_BOX (priv->widget), gsr, TRUE, TRUE, 0);
1084 
1085  g_signal_connect (G_OBJECT (gsr), "help-changed",
1086  G_CALLBACK ( gnc_plugin_page_help_changed_cb ),
1087  page );
1088 
1089  reg = gnc_ledger_display_get_split_register(priv->ledger);
1090  gnc_split_register_config(reg, reg->type, reg->style,
1091  reg->use_double_line);
1092  gnc_ledger_display_refresh(priv->ledger);
1093 
1094  gnc_plugin_page_register_ui_initial_state (page);
1095  gnc_plugin_page_register_ui_update (NULL, page);
1096 
1097  ledger_type = gnc_ledger_display_type (priv->ledger);
1098 
1099  if (ledger_type == LD_SINGLE || ledger_type == LD_SUBACCOUNT)
1100  {
1101  /* Set the sort order for the split register and status of save order button */
1102  priv->sd.save_order = FALSE;
1103  priv->sd.reverse_order = FALSE;
1104  order = gnc_plugin_page_register_get_sort_order(plugin_page);
1105 
1106  PINFO("Loaded Sort order is %s", order);
1107 
1108  gnc_split_reg_set_sort_type(priv->gsr, SortTypefromString(order));
1109 
1110  if (order && (g_strcmp0 (order, DEFAULT_SORT_ORDER) != 0))
1111  priv->sd.save_order = TRUE;
1112 
1113  priv->sd.original_save_order = priv->sd.save_order;
1114  g_free(order);
1115 
1116  /* Set the filter for the split register and status of save filter button */
1117  priv->fd.save_filter = FALSE;
1118 
1119  filter = g_strsplit(gnc_plugin_page_register_get_filter(plugin_page), ",", -1);
1120 
1121  PINFO("Loaded Filter Status is %s", filter[0]);
1122 
1123  priv->fd.cleared_match = (gint)g_ascii_strtoll( filter[0], NULL, 16 );
1124 
1125  if (filter[0] && (g_strcmp0 (filter[0], DEFAULT_FILTER) != 0))
1126  filter_changed = filter_changed + 1;
1127 
1128  if (filter[1] && (g_strcmp0 (filter[1], "0") != 0 ))
1129  {
1130  PINFO("Loaded Filter Start Date is %s", filter[1]);
1131 
1132  priv->fd.start_time = gnc_plugin_page_register_filter_dmy2time (filter[1] );
1133  priv->fd.start_time = gnc_time64_get_day_start(priv->fd.start_time);
1134  filter_changed = filter_changed + 1;
1135 
1136  if (filter[2] && (g_strcmp0 (filter[2], "0") != 0 ))
1137  {
1138  PINFO("Loaded Filter End Date is %s", filter[2]);
1139 
1140  priv->fd.end_time = gnc_plugin_page_register_filter_dmy2time (filter[2] );
1141  priv->fd.end_time = gnc_time64_get_day_end(priv->fd.end_time);
1142  filter_changed = filter_changed + 1;
1143  }
1144  }
1145 
1146  if (filter_changed != 0)
1147  priv->fd.save_filter = TRUE;
1148 
1149  priv->fd.original_save_filter = priv->fd.save_filter;
1150  g_strfreev(filter);
1151 
1152  /* Update Query with Filter Status and Dates */
1153  gnc_ppr_update_status_query (page);
1154  gnc_ppr_update_date_query(page);
1155  }
1156 
1157  plugin_page->summarybar = gsr_create_summary_bar(priv->gsr);
1158  if (plugin_page->summarybar)
1159  {
1160  gtk_widget_show_all(plugin_page->summarybar);
1161  gtk_box_pack_start(GTK_BOX (priv->widget), plugin_page->summarybar,
1162  FALSE, FALSE, 0);
1163 
1164  gnc_plugin_page_register_summarybar_position_changed (NULL, NULL, page);
1165  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
1166  GNC_PREF_SUMMARYBAR_POSITION_TOP,
1167  gnc_plugin_page_register_summarybar_position_changed,
1168  page);
1169  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
1170  GNC_PREF_SUMMARYBAR_POSITION_BOTTOM,
1171  gnc_plugin_page_register_summarybar_position_changed,
1172  page);
1173  }
1174 
1175  priv->event_handler_id = qof_event_register_handler
1176  ((QofEventHandler)gnc_plugin_page_register_event_handler, page);
1177  priv->component_manager_id =
1178  gnc_register_gui_component(GNC_PLUGIN_PAGE_REGISTER_NAME,
1179  gnc_plugin_page_register_refresh_cb,
1180  gnc_plugin_page_register_close_cb,
1181  page);
1182  gnc_gui_component_set_session (priv->component_manager_id,
1183  gnc_get_current_session());
1185  if (acct)
1186  gnc_gui_component_watch_entity (
1187  priv->component_manager_id, xaccAccountGetGUID(acct),
1188  QOF_EVENT_DESTROY | QOF_EVENT_MODIFY);
1189 
1190  gnc_split_reg_set_moved_cb
1191  (priv->gsr, (GFunc)gnc_plugin_page_register_ui_update, page);
1192 
1193  /* DRH - Probably lots of other stuff from regWindowLedger should end up here. */
1194  LEAVE(" ");
1195  return priv->widget;
1196 }
1197 
1198 static void
1199 gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page)
1200 {
1201  GncPluginPageRegister *page;
1203 
1204  ENTER("page %p", plugin_page);
1205  page = GNC_PLUGIN_PAGE_REGISTER (plugin_page);
1206  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
1207 
1208  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
1209  GNC_PREF_SUMMARYBAR_POSITION_TOP,
1210  gnc_plugin_page_register_summarybar_position_changed,
1211  page);
1212  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
1213  GNC_PREF_SUMMARYBAR_POSITION_BOTTOM,
1214  gnc_plugin_page_register_summarybar_position_changed,
1215  page);
1216  if (priv->widget == NULL)
1217  return;
1218 
1219  if (priv->component_manager_id)
1220  {
1221  gnc_unregister_gui_component(priv->component_manager_id);
1222  priv->component_manager_id = 0;
1223  }
1224 
1225  if (priv->event_handler_id)
1226  {
1227  qof_event_unregister_handler(priv->event_handler_id);
1228  priv->event_handler_id = 0;
1229  }
1230 
1231  if (priv->sd.dialog)
1232  {
1233  gtk_widget_destroy(priv->sd.dialog);
1234  memset(&priv->sd, 0, sizeof(priv->sd));
1235  }
1236 
1237  if (priv->fd.dialog)
1238  {
1239  gtk_widget_destroy(priv->fd.dialog);
1240  memset(&priv->fd, 0, sizeof(priv->fd));
1241  }
1242 
1243  gtk_widget_hide(priv->widget);
1244  gnc_ledger_display_close (priv->ledger);
1245  priv->ledger = NULL;
1246  LEAVE(" ");
1247 }
1248 
1249 static void
1250 gnc_plugin_page_register_window_changed (GncPluginPage *plugin_page,
1251  GtkWidget *window)
1252 {
1253  GncPluginPageRegister *page;
1255 
1256  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page));
1257 
1258  page = GNC_PLUGIN_PAGE_REGISTER(plugin_page);
1259  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1260  priv->gsr->window =
1261  GTK_WIDGET(gnc_window_get_gtk_window(GNC_WINDOW(window)));
1262 }
1263 
1264 static const gchar *style_names[] =
1265 {
1266  "Ledger",
1267  "Auto Ledger",
1268  "Journal",
1269  NULL
1270 };
1271 
1272 #define KEY_REGISTER_TYPE "RegisterType"
1273 #define KEY_ACCOUNT_NAME "AccountName"
1274 #define KEY_REGISTER_STYLE "RegisterStyle"
1275 #define KEY_DOUBLE_LINE "DoubleLineMode"
1276 
1277 #define LABEL_ACCOUNT "Account"
1278 #define LABEL_SUBACCOUNT "SubAccount"
1279 #define LABEL_GL "GL"
1280 #define LABEL_SEARCH "Search"
1281 
1282 
1292 static void
1293 gnc_plugin_page_register_save_page (GncPluginPage *plugin_page,
1294  GKeyFile *key_file,
1295  const gchar *group_name)
1296 {
1297  GncPluginPageRegister *page;
1299  GNCLedgerDisplayType ledger_type;
1300  SplitRegister *reg;
1301  Account *leader;
1302 
1303  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
1304  g_return_if_fail (key_file != NULL);
1305  g_return_if_fail (group_name != NULL);
1306 
1307  ENTER("page %p, key_file %p, group_name %s", plugin_page, key_file,
1308  group_name);
1309 
1310  page = GNC_PLUGIN_PAGE_REGISTER(plugin_page);
1311  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1312 
1313  reg = gnc_ledger_display_get_split_register(priv->ledger);
1314  ledger_type = gnc_ledger_display_type(priv->ledger);
1315  if (ledger_type > LD_GL)
1316  {
1317  LEAVE("Unsupported ledger type");
1318  return;
1319  }
1320  if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
1321  {
1322  const gchar *label;
1323  gchar* name;
1324  label = (ledger_type == LD_SINGLE) ? LABEL_ACCOUNT : LABEL_SUBACCOUNT;
1325  leader = gnc_ledger_display_leader(priv->ledger);
1326  g_key_file_set_string(key_file, group_name, KEY_REGISTER_TYPE, label);
1327  name = gnc_account_get_full_name(leader);
1328  g_key_file_set_string(key_file, group_name, KEY_ACCOUNT_NAME, name);
1329  g_free(name);
1330  }
1331  else if (reg->type == GENERAL_LEDGER)
1332  {
1333  g_key_file_set_string(key_file, group_name, KEY_REGISTER_TYPE,
1334  LABEL_GL);
1335  }
1336  else if (reg->type == SEARCH_LEDGER)
1337  {
1338  g_key_file_set_string(key_file, group_name, KEY_REGISTER_TYPE,
1339  LABEL_SEARCH);
1340  }
1341  else
1342  {
1343  LEAVE("Unsupported register type");
1344  return;
1345  }
1346 
1347  g_key_file_set_string(key_file, group_name, KEY_REGISTER_STYLE,
1348  style_names[reg->style]);
1349  g_key_file_set_boolean(key_file, group_name, KEY_DOUBLE_LINE,
1350  reg->use_double_line);
1351 
1352  LEAVE(" ");
1353 }
1354 
1355 
1368 static void
1369 gnc_plugin_page_register_restore_edit_menu (GncPluginPage *page,
1370  GKeyFile *key_file,
1371  const gchar *group_name)
1372 {
1373  GtkAction *action;
1374  GError *error = NULL;
1375  gchar *style_name;
1376  gint i;
1377  gboolean use_double_line;
1378 
1379  ENTER(" ");
1380 
1381  /* Convert the style name to an index */
1382  style_name = g_key_file_get_string(key_file, group_name,
1383  KEY_REGISTER_STYLE, &error);
1384  for (i = 0 ; style_names[i]; i++)
1385  {
1386  if (g_ascii_strcasecmp(style_name, style_names[i]) == 0)
1387  {
1388  DEBUG("Found match for style name: %s", style_name);
1389  break;
1390  }
1391  }
1392  g_free(style_name);
1393 
1394  /* Update the style menu action for this page */
1395  if (i <= REG_STYLE_JOURNAL)
1396  {
1397  DEBUG("Setting style: %d", i);
1398  action = gnc_plugin_page_get_action(page, radio_entries_2[i].name);
1399  gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
1400  }
1401 
1402  /* Update the double line action on this page */
1403  use_double_line =
1404  g_key_file_get_boolean(key_file, group_name, KEY_DOUBLE_LINE, &error);
1405  DEBUG("Setting double_line_mode: %d", use_double_line);
1406  action = gnc_plugin_page_get_action(page, "ViewStyleDoubleLineAction");
1407  gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), use_double_line);
1408 
1409  LEAVE(" ");
1410 }
1411 
1412 
1422 static GncPluginPage *
1423 gnc_plugin_page_register_recreate_page (GtkWidget *window,
1424  GKeyFile *key_file,
1425  const gchar *group_name)
1426 {
1427  GncPluginPage *page;
1428  GError *error = NULL;
1429  gchar *reg_type, *acct_name;
1430  Account *account;
1431  QofBook *book;
1432  gboolean include_subs;
1433 
1434  g_return_val_if_fail(key_file, NULL);
1435  g_return_val_if_fail(group_name, NULL);
1436  ENTER("key_file %p, group_name %s", key_file, group_name);
1437 
1438  /* Create the new page. */
1439  reg_type = g_key_file_get_string(key_file, group_name,
1440  KEY_REGISTER_TYPE, &error);
1441  DEBUG("Page type: %s", reg_type);
1442  if ((g_ascii_strcasecmp(reg_type, LABEL_ACCOUNT) == 0) ||
1443  (g_ascii_strcasecmp(reg_type, LABEL_SUBACCOUNT) == 0))
1444  {
1445  include_subs = (g_ascii_strcasecmp(reg_type, LABEL_SUBACCOUNT) == 0);
1446  DEBUG("Include subs: %d", include_subs);
1447  acct_name = g_key_file_get_string(key_file, group_name,
1448  KEY_ACCOUNT_NAME, &error);
1449  book = qof_session_get_book(gnc_get_current_session());
1450  account = gnc_account_lookup_by_full_name(gnc_book_get_root_account(book),
1451  acct_name);
1452  g_free(acct_name);
1453  if (account == NULL)
1454  {
1455  LEAVE("Bad account name");
1456  g_free(reg_type);
1457  return NULL;
1458  }
1459  page = gnc_plugin_page_register_new (account, include_subs);
1460  }
1461  else if (g_ascii_strcasecmp(reg_type, LABEL_GL) == 0)
1462  {
1464  }
1465  else
1466  {
1467  LEAVE("Bad ledger type");
1468  g_free(reg_type);
1469  return NULL;
1470  }
1471  g_free(reg_type);
1472 
1473  /* Recreate page in given window */
1475 
1476  /* Install it now so we can them manipulate the created widget */
1477  gnc_main_window_open_page(GNC_MAIN_WINDOW(window), page);
1478 
1479  /* Now update the page to the last state it was in */
1480  gnc_plugin_page_register_restore_edit_menu(page, key_file, group_name);
1481  LEAVE(" ");
1482  return page;
1483 }
1484 
1485 
1486 /*
1487  * Based on code from Epiphany (src/ephy-window.c)
1488  */
1489 static void
1490 gnc_plugin_page_register_update_edit_menu (GncPluginPage *page, gboolean hide)
1491 {
1493  GncPluginPageRegister *reg_page;
1494  GtkAction *action;
1495  gboolean can_copy = FALSE, can_cut = FALSE, can_paste = FALSE;
1496  gboolean has_selection;
1497  gboolean is_readwrite = !qof_book_is_readonly(gnc_get_current_book());
1498 
1499  reg_page = GNC_PLUGIN_PAGE_REGISTER(page);
1500  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(reg_page);
1501  has_selection = gnucash_register_has_selection (priv->gsr->reg);
1502 
1503  can_copy = has_selection;
1504  can_cut = is_readwrite && has_selection;
1505  can_paste = is_readwrite;
1506 
1507  action = gnc_plugin_page_get_action (page, "EditCopyAction");
1508  gtk_action_set_sensitive (action, can_copy);
1509  gtk_action_set_visible (action, !hide || can_copy);
1510  action = gnc_plugin_page_get_action (page, "EditCutAction");
1511  gtk_action_set_sensitive (action, can_cut);
1512  gtk_action_set_visible (action, !hide || can_cut);
1513  action = gnc_plugin_page_get_action (page, "EditPasteAction");
1514  gtk_action_set_sensitive (action, can_paste);
1515  gtk_action_set_visible (action, !hide || can_paste);
1516 }
1517 
1518 
1519 static gboolean
1520 gnc_plugin_page_register_finish_pending (GncPluginPage *page)
1521 {
1523  GncPluginPageRegister *reg_page;
1524  SplitRegister *reg;
1525  GtkWidget *dialog, *window;
1526  const gchar *name;
1527  gint response;
1528 
1529  reg_page = GNC_PLUGIN_PAGE_REGISTER(page);
1530  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(reg_page);
1531  reg = gnc_ledger_display_get_split_register(priv->ledger);
1532 
1533  if (!reg || !gnc_split_register_changed(reg))
1534  return TRUE;
1535 
1536  name = gnc_plugin_page_register_get_tab_name(page);
1537  window = gnc_plugin_page_get_window(page);
1538  dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1539  GTK_DIALOG_DESTROY_WITH_PARENT,
1540  GTK_MESSAGE_WARNING,
1541  GTK_BUTTONS_NONE,
1542  /* Translators: %s is the name
1543  of the tab page */
1544  _("Save changes to %s?"), name);
1545  gtk_message_dialog_format_secondary_text
1546  (GTK_MESSAGE_DIALOG(dialog),
1547  "%s",
1548  _("This register has pending changes to a transaction. "
1549  "Would you like to save the changes to this transaction, "
1550  "discard the transaction, or cancel the operation?"));
1551  gnc_gtk_dialog_add_button(dialog, _("_Discard Transaction"),
1552  GTK_STOCK_DELETE, GTK_RESPONSE_REJECT);
1553  gtk_dialog_add_button(GTK_DIALOG(dialog),
1554  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1555  gnc_gtk_dialog_add_button(dialog, _("_Save Transaction"),
1556  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT);
1557 
1558  response = gtk_dialog_run(GTK_DIALOG(dialog));
1559  gtk_widget_destroy(dialog);
1560 
1561  switch (response)
1562  {
1563  case GTK_RESPONSE_ACCEPT:
1564  gnc_split_register_save(reg, TRUE);
1565  return TRUE;
1566 
1567  case GTK_RESPONSE_REJECT:
1569  gnc_split_register_save (reg, TRUE);
1570  return TRUE;
1571 
1572  default:
1573  return FALSE;
1574  }
1575 }
1576 
1577 
1578 static gchar *
1579 gnc_plugin_page_register_get_tab_name (GncPluginPage *plugin_page)
1580 {
1582  GNCLedgerDisplayType ledger_type;
1583  GNCLedgerDisplay *ld;
1584  SplitRegister *reg;
1585  Account *leader;
1586 
1587  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page), _("unknown"));
1588 
1589  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
1590  ld = priv->ledger;
1591  reg = gnc_ledger_display_get_split_register (ld);
1592  ledger_type = gnc_ledger_display_type (ld);
1593  leader = gnc_ledger_display_leader (ld);
1594 
1595  switch (ledger_type)
1596  {
1597  case LD_SINGLE:
1598  return g_strdup(xaccAccountGetName (leader));
1599 
1600  case LD_SUBACCOUNT:
1601  return g_strdup_printf("%s+", xaccAccountGetName (leader));
1602 
1603  case LD_GL:
1604  switch (reg->type)
1605  {
1606  case GENERAL_LEDGER:
1607  case INCOME_LEDGER:
1608  return g_strdup(_("General Ledger"));
1609  case PORTFOLIO_LEDGER:
1610  return g_strdup(_("Portfolio"));
1611  case SEARCH_LEDGER:
1612  return g_strdup(_("Search Results"));
1613  default:
1614  break;
1615  }
1616  break;
1617 
1618  default:
1619  break;
1620  }
1621 
1622  return g_strdup(_("unknown"));
1623 }
1624 
1625 static gchar *
1626 gnc_plugin_page_register_get_tab_color (GncPluginPage *plugin_page)
1627 {
1629  GNCLedgerDisplayType ledger_type;
1630  GNCLedgerDisplay *ld;
1631  Account *leader;
1632  const char* color;
1633 
1634  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page), _("unknown"));
1635 
1636  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
1637  ld = priv->ledger;
1638  ledger_type = gnc_ledger_display_type (ld);
1639  leader = gnc_ledger_display_leader (ld);
1640  color = NULL;
1641 
1642  if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
1643  color = xaccAccountGetColor (leader);
1644 
1645  return g_strdup(color ? color : "Not Set");
1646 }
1647 
1648 static gchar *
1649 gnc_plugin_page_register_get_filter (GncPluginPage *plugin_page)
1650 {
1652  GNCLedgerDisplayType ledger_type;
1653  GNCLedgerDisplay *ld;
1654  Account *leader;
1655  const char* filter;
1656 
1657  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page), _("unknown"));
1658 
1659  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
1660  ld = priv->ledger;
1661  ledger_type = gnc_ledger_display_type (ld);
1662  leader = gnc_ledger_display_leader (ld);
1663  filter = NULL;
1664 
1665  if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
1666  filter = xaccAccountGetFilter (leader);
1667 
1668  return filter ? g_strdup(filter) : g_strdup_printf("%s,%s,%s", DEFAULT_FILTER, "0", "0");
1669 }
1670 
1671 void
1672 gnc_plugin_page_register_set_filter (GncPluginPage *plugin_page, const gchar *filter )
1673 {
1675  GNCLedgerDisplay *ld;
1676  Account *leader;
1677  gchar *default_filter;
1678 
1679  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
1680  ld = priv->ledger;
1681  leader = gnc_ledger_display_leader (ld);
1682 
1683  if (leader != NULL)
1684  {
1685  default_filter = g_strdup_printf("%s,%s,%s", DEFAULT_FILTER, "0", "0");
1686 
1687  if (!filter || (g_strcmp0 (filter, default_filter) == 0))
1688  xaccAccountSetFilter (leader, NULL);
1689  else
1690  xaccAccountSetFilter (leader, filter);
1691 
1692  g_free (default_filter);
1693  }
1694 
1695  return;
1696 }
1697 
1698 static gchar *
1699 gnc_plugin_page_register_get_sort_order (GncPluginPage *plugin_page)
1700 {
1702  GNCLedgerDisplayType ledger_type;
1703  GNCLedgerDisplay *ld;
1704  Account *leader;
1705  const char* sort_order;
1706 
1707  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page), _("unknown"));
1708 
1709  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
1710  ld = priv->ledger;
1711  ledger_type = gnc_ledger_display_type (ld);
1712  leader = gnc_ledger_display_leader (ld);
1713  sort_order = NULL;
1714 
1715  if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
1716  sort_order = xaccAccountGetSortOrder (leader);
1717 
1718  return g_strdup(sort_order ? sort_order : DEFAULT_SORT_ORDER);
1719 }
1720 
1721 void
1722 gnc_plugin_page_register_set_sort_order (GncPluginPage *plugin_page, const gchar *sort_order )
1723 {
1725  GNCLedgerDisplay *ld;
1726  Account *leader;
1727 
1728  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
1729  ld = priv->ledger;
1730  leader = gnc_ledger_display_leader (ld);
1731 
1732  if (leader != NULL)
1733  {
1734  if (!sort_order || (g_strcmp0 (sort_order, DEFAULT_SORT_ORDER) == 0))
1735  xaccAccountSetSortOrder (leader, NULL);
1736  else
1737  xaccAccountSetSortOrder (leader, sort_order);
1738  }
1739 
1740  return;
1741 }
1742 
1743 static gchar *
1744 gnc_plugin_page_register_get_long_name (GncPluginPage *plugin_page)
1745 {
1747  GNCLedgerDisplayType ledger_type;
1748  GNCLedgerDisplay *ld;
1749  Account *leader;
1750 
1751  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page), _("unknown"));
1752 
1753  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
1754  ld = priv->ledger;
1755  ledger_type = gnc_ledger_display_type (ld);
1756  leader = gnc_ledger_display_leader (ld);
1757 
1758  switch (ledger_type)
1759  {
1760  case LD_SINGLE:
1761  return gnc_account_get_full_name (leader);
1762 
1763  case LD_SUBACCOUNT:
1764  {
1765  gchar *account_full_name = gnc_account_get_full_name (leader);
1766  gchar *return_string = g_strdup_printf("%s+", account_full_name);
1767  g_free ((gpointer *) account_full_name);
1768  return return_string;
1769  }
1770 
1771  default:
1772  break;
1773  }
1774 
1775  return NULL;
1776 }
1777 
1778 static void
1779 gnc_plugin_page_register_summarybar_position_changed (gpointer prefs, gchar* pref, gpointer user_data)
1780 {
1781  GncPluginPage *plugin_page;
1782  GncPluginPageRegister *page;
1784  GtkPositionType position = GTK_POS_BOTTOM;
1785 
1786  g_return_if_fail (user_data != NULL);
1787 
1788  if (!GNC_IS_PLUGIN_PAGE (user_data))
1789  return;
1790 
1791  plugin_page = GNC_PLUGIN_PAGE (user_data);
1792  page = GNC_PLUGIN_PAGE_REGISTER (user_data);
1793  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE (page);
1794 
1795  if (priv == NULL)
1796  return;
1797 
1798  if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SUMMARYBAR_POSITION_TOP))
1799  position = GTK_POS_TOP;
1800 
1801  gtk_box_reorder_child (GTK_BOX (priv->widget),
1802  plugin_page->summarybar,
1803  (position == GTK_POS_TOP ? 0 : -1) );
1804 }
1805 
1806 /************************************************************/
1807 /* "Sort By" Dialog */
1808 /************************************************************/
1809 
1820 static void
1821 gnc_plugin_page_register_sort_book_option_changed (gpointer new_val,
1822  gpointer user_data)
1823 {
1825  GncPluginPageRegister *page = user_data;
1826  gboolean *new_data = (gboolean*)new_val;
1827 
1828  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
1829 
1830  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1831  if (*new_data)
1832  {
1833  gtk_button_set_label(GTK_BUTTON (priv->sd.num_radio), _("Transaction Number"));
1834  gtk_button_set_label(GTK_BUTTON (priv->sd.act_radio), _("Number/Action"));
1835  }
1836  else
1837  {
1838  gtk_button_set_label(GTK_BUTTON (priv->sd.num_radio), _("Number"));
1839  gtk_button_set_label(GTK_BUTTON (priv->sd.act_radio), _("Action"));
1840  }
1841  gnc_split_reg_set_sort_type_force (priv->gsr, priv->gsr->sort_type, TRUE);
1842 }
1843 
1855 void
1857  gint response,
1858  GncPluginPageRegister *page)
1859 {
1861  GncPluginPage *plugin_page;
1862  SortType type;
1863  const gchar *order;
1864 
1865  g_return_if_fail(GTK_IS_DIALOG(dialog));
1866  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
1867 
1868  ENTER(" ");
1869  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1870  plugin_page = GNC_PLUGIN_PAGE(page);
1871 
1872  if (response != GTK_RESPONSE_OK)
1873  {
1874  /* Restore the original sort order */
1875  gnc_split_reg_set_sort_type(priv->gsr, priv->sd.original_sort_type);
1876  priv->sd.save_order = priv->sd.original_save_order;
1877  }
1878  else
1879  {
1880  priv->sd.original_save_order = priv->sd.save_order;
1881 
1882  if (priv->sd.save_order)
1883  {
1884  type = gnc_split_reg_get_sort_type(priv->gsr);
1885  order = SortTypeasString(type);
1886  gnc_plugin_page_register_set_sort_order (plugin_page, order);
1887  }
1888  }
1889  gnc_book_option_remove_cb(OPTION_NAME_NUM_FIELD_SOURCE,
1890  gnc_plugin_page_register_sort_book_option_changed,
1891  page);
1892  priv->sd.dialog = NULL;
1893  priv->sd.num_radio = NULL;
1894  priv->sd.act_radio = NULL;
1895  gtk_widget_destroy(GTK_WIDGET(dialog));
1896  LEAVE(" ");
1897 }
1898 
1899 
1908 void
1910  GncPluginPageRegister *page)
1911 {
1913  const gchar *name;
1914  SortType type;
1915 
1916  g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button));
1917  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
1918 
1919  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1920  name = gtk_buildable_get_name(GTK_BUILDABLE(button));
1921  ENTER("button %s(%p), page %p", name, button, page);
1922  type = SortTypefromString(name);
1923  gnc_split_reg_set_sort_type(priv->gsr, type);
1924  LEAVE(" ");
1925 }
1926 
1927 
1936 void
1938  GncPluginPageRegister *page)
1939 {
1941 
1942  g_return_if_fail(GTK_IS_CHECK_BUTTON(button));
1943  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
1944 
1945  ENTER("Save toggle button (%p), plugin_page %p", button, page);
1946 
1947  /* Compute the new save sort order */
1948  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1949 
1950  if (gtk_toggle_button_get_active(button))
1951  priv->sd.save_order = TRUE;
1952  else
1953  priv->sd.save_order = FALSE;
1954  LEAVE(" ");
1955 }
1956 
1965 void
1967  GncPluginPageRegister *page)
1968 
1969 {
1971 
1972  g_return_if_fail(GTK_IS_CHECK_BUTTON(button));
1973  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
1974 
1975  ENTER("Reverse toggle button (%p), plugin_page %p", button, page);
1976 
1977  /* Compute the new save sort order */
1978  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
1979 
1980  if (gtk_toggle_button_get_active(button))
1981  {
1982  gnc_split_reg_set_sort_reversed(priv->gsr, FALSE);
1983  priv->sd.reverse_order = TRUE;
1984  }
1985  else
1986  {
1987  gnc_split_reg_set_sort_reversed(priv->gsr, TRUE);
1988  priv->sd.reverse_order = FALSE;
1989  }
1990  LEAVE(" ");
1991 }
1992 
1993 /************************************************************/
1994 /* "Filter By" Dialog */
1995 /************************************************************/
1996 
2009 static void
2010 gnc_ppr_update_status_query (GncPluginPageRegister *page)
2011 {
2013  GSList *param_list;
2014  Query *query;
2015 
2016  ENTER(" ");
2017  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2018  query = gnc_ledger_display_get_query( priv->ledger );
2019  if (!query)
2020  {
2021  LEAVE("no query found");
2022  return;
2023  }
2024 
2025  /* Remove the old status match */
2026  param_list = qof_query_build_param_list (SPLIT_RECONCILE, NULL);
2027  if (param_list)
2028  {
2029  qof_query_purge_terms (query, param_list);
2030  g_slist_free(param_list);
2031  }
2032 
2033  /* Install the new status match */
2034  if (priv->fd.cleared_match != CLEARED_ALL)
2035  xaccQueryAddClearedMatch(query, priv->fd.cleared_match, QOF_QUERY_AND);
2036 
2037  gnc_ledger_display_refresh (priv->ledger);
2038  LEAVE(" ");
2039 }
2040 
2041 
2054 static void
2055 gnc_ppr_update_date_query (GncPluginPageRegister *page)
2056 {
2058  GSList *param_list;
2059  Query *query;
2060 
2061  ENTER(" ");
2062  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2063  if (!priv->ledger)
2064  {
2065  LEAVE("no ledger");
2066  return;
2067  }
2068 
2069  query = gnc_ledger_display_get_query( priv->ledger );
2070  if (!query)
2071  {
2072  LEAVE("no query");
2073  return;
2074  }
2075 
2076  /* Delete any existing old date spec. */
2077  param_list = qof_query_build_param_list(SPLIT_TRANS, TRANS_DATE_POSTED, NULL);
2078  if (param_list)
2079  {
2080  qof_query_purge_terms (query, param_list);
2081  g_slist_free(param_list);
2082  }
2083 
2084  if (priv->fd.start_time || priv->fd.end_time)
2085  {
2086  /* Build a new spec */
2087  xaccQueryAddDateMatchTT(query,
2088  priv->fd.start_time != 0, priv->fd.start_time,
2089  priv->fd.end_time != 0, priv->fd.end_time,
2090  QOF_QUERY_AND);
2091  }
2092 
2093  gnc_ledger_display_refresh (priv->ledger);
2094  LEAVE(" ");
2095 }
2096 
2097 
2098 /* This function converts a time64 value date to a string */
2099 static gchar *
2100 gnc_plugin_page_register_filter_time2dmy ( time64 raw_time)
2101 {
2102  struct tm * timeinfo;
2103  gchar date_string[11];
2104 
2105  timeinfo = gnc_localtime (&raw_time);
2106  strftime (date_string, 11, "%d-%m-%Y", timeinfo);
2107  PINFO("Date string is %s", date_string);
2108  gnc_tm_free (timeinfo);
2109 
2110  return g_strdup(date_string);
2111 }
2112 
2113 
2114 /* This function converts a string date to a time64 value */
2115 static time64
2116 gnc_plugin_page_register_filter_dmy2time (char *date_string)
2117 {
2118  struct tm when;
2119 
2120  PINFO("Date string is %s", date_string);
2121  memset (&when, 0, sizeof (when));
2122 
2123  sscanf (date_string, "%d-%d-%d", &when.tm_mday,
2124  &when.tm_mon, &when.tm_year);
2125 
2126  when.tm_mon -= 1;
2127  when.tm_year -= 1900;
2128 
2129  return gnc_mktime (&when);
2130 }
2131 
2132 
2143 void
2145  GncPluginPageRegister *page)
2146 {
2148  const gchar *name;
2149  gint i, value;
2150 
2151  g_return_if_fail(GTK_IS_CHECK_BUTTON(button));
2152  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2153 
2154  name = gtk_buildable_get_name(GTK_BUILDABLE(button));
2155  ENTER("toggle button %s (%p), plugin_page %p", name, button, page);
2156 
2157  /* Determine what status bit to change */
2158  value = CLEARED_NONE;
2159  for (i = 0; status_actions[i].action_name; i++)
2160  {
2161  if (g_strcmp0(name, status_actions[i].action_name) == 0)
2162  {
2163  value = status_actions[i].value;
2164  break;
2165  }
2166  }
2167 
2168  /* Compute the new match status */
2169  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2170  if (gtk_toggle_button_get_active(button))
2171  priv->fd.cleared_match |= value;
2172  else
2173  priv->fd.cleared_match &= ~value;
2174  gnc_ppr_update_status_query(page);
2175  LEAVE(" ");
2176 }
2177 
2178 
2188 void
2190  GncPluginPageRegister *page)
2191 {
2193  GtkWidget *widget;
2194  gint i;
2195 
2196  g_return_if_fail(GTK_IS_BUTTON(button));
2197  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2198 
2199  ENTER("(button %p, page %p)", button, page);
2200 
2201  /* Turn on all the check menu items */
2202  for (i = 0; status_actions[i].action_name; i++)
2203  {
2204  widget = status_actions[i].widget;
2205  g_signal_handlers_block_by_func(widget, gnc_plugin_page_register_filter_status_one_cb, page);
2206  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget), TRUE);
2207  g_signal_handlers_unblock_by_func(widget, gnc_plugin_page_register_filter_status_one_cb, page);
2208  }
2209 
2210  /* Set the requested status */
2211  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2212  priv->fd.cleared_match = CLEARED_ALL;
2213  gnc_ppr_update_status_query(page);
2214  LEAVE(" ");
2215 }
2216 
2217 
2229 static void
2230 get_filter_times(GncPluginPageRegister *page)
2231 {
2233  time64 time_val;
2234 
2235  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2236  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.start_date_choose)))
2237  {
2238  time_val = gnc_date_edit_get_date(GNC_DATE_EDIT(priv->fd.start_date));
2239  time_val = gnc_time64_get_day_start(time_val);
2240  priv->fd.start_time = time_val;
2241  }
2242  else
2243  {
2244  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.start_date_today)))
2245  {
2246  priv->fd.start_time = gnc_time64_get_today_start();
2247  }
2248  else
2249  {
2250  priv->fd.start_time = 0;
2251  }
2252  }
2253 
2254  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.end_date_choose)))
2255  {
2256  time_val = gnc_date_edit_get_date(GNC_DATE_EDIT(priv->fd.end_date));
2257  time_val = gnc_time64_get_day_end(time_val);
2258  priv->fd.end_time = time_val;
2259  }
2260  else
2261  {
2262  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.start_date_today)))
2263  {
2264  priv->fd.end_time = gnc_time64_get_today_end();
2265  }
2266  else
2267  {
2268  priv->fd.end_time = 0;
2269  }
2270  }
2271 }
2272 
2273 
2289 void
2291  GncPluginPageRegister *page)
2292 {
2294  gboolean active;
2295 
2296  g_return_if_fail(GTK_IS_RADIO_BUTTON(button));
2297  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2298 
2299  ENTER("(button %p, page %p)", button, page);
2300  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2301  active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
2302  gtk_widget_set_sensitive(priv->fd.table, active);
2303  if (active)
2304  {
2305  get_filter_times(page);
2306  }
2307  else
2308  {
2309  priv->fd.start_time = 0;
2310  priv->fd.end_time = 0;
2311  }
2312  gnc_ppr_update_date_query(page);
2313  LEAVE(" ");
2314 }
2315 
2316 
2327 static void
2328 gnc_plugin_page_register_filter_gde_changed_cb (GtkWidget *unused,
2329  GncPluginPageRegister *page)
2330 {
2331  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2332 
2333  ENTER("(widget %s(%p), page %p)", gtk_buildable_get_name(GTK_BUILDABLE(unused)), unused, page);
2334  get_filter_times(page);
2335  gnc_ppr_update_date_query(page);
2336  LEAVE(" ");
2337 }
2338 
2339 
2359 void
2361  GncPluginPageRegister *page)
2362 {
2364  const gchar *name;
2365  gboolean active;
2366 
2367  g_return_if_fail(GTK_IS_RADIO_BUTTON(radio));
2368  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2369 
2370  ENTER("(radio %s(%p), page %p)", gtk_buildable_get_name(GTK_BUILDABLE(radio)), radio, page);
2371  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2372  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio)))
2373  {
2374  LEAVE("1st callback of pair. Defer to 2nd callback.");
2375  return;
2376  }
2377 
2378  name = gtk_buildable_get_name(GTK_BUILDABLE(radio));
2379  active = ( g_strcmp0(name, g_strdup("start_date_choose")) == 0 ? 1 : 0 );
2380  gtk_widget_set_sensitive(priv->fd.start_date, active);
2381  get_filter_times(page);
2382  gnc_ppr_update_date_query(page);
2383  LEAVE(" ");
2384 }
2385 
2386 
2406 void
2408  GncPluginPageRegister *page)
2409 {
2411  const gchar *name;
2412  gboolean active;
2413 
2414  g_return_if_fail(GTK_IS_RADIO_BUTTON(radio));
2415  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2416 
2417  ENTER("(radio %s(%p), page %p)", gtk_buildable_get_name(GTK_BUILDABLE(radio)), radio, page);
2418  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2419  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio)))
2420  {
2421  LEAVE("1st callback of pair. Defer to 2nd callback.");
2422  return;
2423  }
2424 
2425  name = gtk_buildable_get_name(GTK_BUILDABLE(radio));
2426  active = ( g_strcmp0(name, g_strdup("end_date_choose")) == 0 ? 1 : 0 );
2427  gtk_widget_set_sensitive(priv->fd.end_date, active);
2428  get_filter_times(page);
2429  gnc_ppr_update_date_query(page);
2430  LEAVE(" ");
2431 }
2432 
2433 
2442 void
2444  GncPluginPageRegister *page)
2445 {
2447 
2448  g_return_if_fail(GTK_IS_CHECK_BUTTON(button));
2449  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2450 
2451  ENTER("Save toggle button (%p), plugin_page %p", button, page);
2452 
2453  /* Compute the new save filter status */
2454  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2455  if (gtk_toggle_button_get_active(button))
2456  priv->fd.save_filter = TRUE;
2457  else
2458  priv->fd.save_filter = FALSE;
2459  LEAVE(" ");
2460 }
2461 
2462 
2474 void
2476  gint response,
2477  GncPluginPageRegister *page)
2478 {
2480  GncPluginPage *plugin_page;
2481 
2482  g_return_if_fail(GTK_IS_DIALOG(dialog));
2483  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2484 
2485  ENTER(" ");
2486  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2487  plugin_page = GNC_PLUGIN_PAGE(page);
2488 
2489  if (response != GTK_RESPONSE_OK)
2490  {
2491  /* Remove the old status match */
2492  priv->fd.cleared_match = priv->fd.original_cleared_match;
2493  gnc_ppr_update_status_query(page);
2494  priv->fd.start_time = priv->fd.original_start_time;
2495  priv->fd.end_time = priv->fd.original_end_time;
2496  priv->fd.save_filter = priv->fd.original_save_filter;
2497  gnc_ppr_update_date_query(page);
2498  }
2499  else
2500  {
2501  priv->fd.original_save_filter = priv->fd.save_filter;
2502 
2503  if (priv->fd.save_filter)
2504  {
2505  gchar* filter;
2506  filter = g_strdup_printf("0x%04x", priv->fd.cleared_match);
2507 
2508  if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.start_date_choose)) && priv->fd.start_time != 0 )
2509  {
2510  gchar *timeval = gnc_plugin_page_register_filter_time2dmy(priv->fd.start_time);
2511  filter = g_strconcat ( filter, ",", timeval, NULL);
2512  g_free (timeval);
2513  }
2514  else
2515  filter = g_strconcat ( filter, ",0", NULL);
2516 
2517  if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.end_date_choose)) && priv->fd.end_time != 0 )
2518  {
2519  gchar *timeval = gnc_plugin_page_register_filter_time2dmy(priv->fd.end_time);
2520  filter = g_strconcat ( filter, ",", timeval, NULL);
2521  g_free (timeval);
2522  }
2523  else
2524  filter = g_strconcat ( filter, ",0", NULL);
2525 
2526  PINFO("The filter to save is %s", filter);
2527 
2528  gnc_plugin_page_register_set_filter (plugin_page, filter);
2529  g_free (filter);
2530  }
2531  }
2532  priv->fd.dialog = NULL;
2533  gtk_widget_destroy(GTK_WIDGET(dialog));
2534  LEAVE(" ");
2535 }
2536 
2537 
2538 /************************************************************/
2539 /* Report Helper Functions */
2540 /************************************************************/
2541 
2542 static char *
2543 gnc_reg_get_name (GNCLedgerDisplay *ledger, gboolean for_window)
2544 {
2545  Account *leader;
2546  SplitRegister *reg;
2547  gchar *account_name;
2548  gchar *reg_name;
2549  gchar *name;
2550  GNCLedgerDisplayType ledger_type;
2551 
2552  if (ledger == NULL)
2553  return NULL;
2554 
2555  reg = gnc_ledger_display_get_split_register (ledger);
2556  ledger_type = gnc_ledger_display_type (ledger);
2557 
2558  switch (reg->type)
2559  {
2560  case GENERAL_LEDGER:
2561  case INCOME_LEDGER:
2562  if (for_window)
2563  reg_name = _("General Ledger");
2564  else
2565  reg_name = _("Transaction Report");
2566  break;
2567  case PORTFOLIO_LEDGER:
2568  if (for_window)
2569  reg_name = _("Portfolio");
2570  else
2571  reg_name = _("Portfolio Report");
2572  break;
2573  case SEARCH_LEDGER:
2574  if (for_window)
2575  reg_name = _("Search Results");
2576  else
2577  reg_name = _("Search Results Report");
2578  break;
2579  default:
2580  if (for_window)
2581  reg_name = _("Register");
2582  else
2583  reg_name = _("Transaction Report");
2584  break;
2585  }
2586 
2587  leader = gnc_ledger_display_leader (ledger);
2588 
2589  if ((leader != NULL) && (ledger_type != LD_GL))
2590  {
2591  account_name = gnc_account_get_full_name (leader);
2592 
2593  if (ledger_type == LD_SINGLE)
2594  {
2595  name = g_strconcat (account_name, " - ", reg_name, NULL);
2596  }
2597  else
2598  {
2599  name = g_strconcat (account_name, " ", _("and subaccounts"), " - ", reg_name, NULL);
2600  }
2601  g_free(account_name);
2602  }
2603  else
2604  name = g_strdup (reg_name);
2605 
2606  return name;
2607 }
2608 
2609 static int
2610 report_helper (GNCLedgerDisplay *ledger, Split *split, Query *query)
2611 {
2612  SplitRegister *reg = gnc_ledger_display_get_split_register (ledger);
2613  Account *account;
2614  char *str;
2615  const char *tmp;
2616  swig_type_info * qtype;
2617  SCM args;
2618  SCM func;
2619  SCM arg;
2620 
2621  args = SCM_EOL;
2622 
2623  func = scm_c_eval_string ("gnc:register-report-create");
2624  g_return_val_if_fail (scm_is_procedure (func), -1);
2625 
2627  arg = scm_from_utf8_string (tmp ? tmp : _("Credit"));
2628  args = scm_cons (arg, args);
2629 
2631  arg = scm_from_utf8_string (tmp ? tmp : _("Debit"));
2632  args = scm_cons (arg, args);
2633 
2634  str = gnc_reg_get_name (ledger, FALSE);
2635  arg = scm_from_utf8_string (str ? str : "");
2636  args = scm_cons (arg, args);
2637  g_free (str);
2638 
2639  arg = SCM_BOOL (reg->use_double_line);
2640  args = scm_cons (arg, args);
2641 
2642  arg = SCM_BOOL (reg->type == GENERAL_LEDGER || reg->type == INCOME_LEDGER
2643  || reg->type == SEARCH_LEDGER);
2644  args = scm_cons (arg, args);
2645 
2646  arg = SCM_BOOL (reg->style == REG_STYLE_JOURNAL);
2647  args = scm_cons (arg, args);
2648 
2649  if (!query)
2650  {
2651  query = gnc_ledger_display_get_query (ledger);
2652  g_return_val_if_fail (query != NULL, -1);
2653  }
2654 
2655  qtype = SWIG_TypeQuery ("_p__QofQuery");
2656  g_return_val_if_fail (qtype, -1);
2657 
2658  arg = SWIG_NewPointerObj (query, qtype, 0);
2659  args = scm_cons (arg, args);
2660  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
2661 
2662 
2663  if (split)
2664  {
2665  qtype = SWIG_TypeQuery ("_p_Split");
2666  g_return_val_if_fail (qtype, -1);
2667  arg = SWIG_NewPointerObj (split, qtype, 0);
2668  }
2669  else
2670  {
2671  arg = SCM_BOOL_F;
2672  }
2673  args = scm_cons (arg, args);
2674  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
2675 
2676 
2677  qtype = SWIG_TypeQuery ("_p_Account");
2678  g_return_val_if_fail (qtype, -1);
2679 
2680  account = gnc_ledger_display_leader (ledger);
2681  arg = SWIG_NewPointerObj (account, qtype, 0);
2682  args = scm_cons (arg, args);
2683  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
2684 
2685 
2686  /* Apply the function to the args */
2687  arg = scm_apply (func, args, SCM_EOL);
2688  g_return_val_if_fail (scm_is_exact (arg), -1);
2689 
2690  return scm_to_int (arg);
2691 }
2692 
2693 /************************************************************/
2694 /* Command callbacks */
2695 /************************************************************/
2696 
2697 static void
2698 gnc_plugin_page_register_cmd_print_check (GtkAction *action,
2699  GncPluginPageRegister *plugin_page)
2700 {
2702  SplitRegister * reg;
2703  Split * split;
2704  Transaction * trans;
2705  GList * splits = NULL, *item;
2706  GNCLedgerDisplayType ledger_type;
2707  Account * account;
2708 
2709  ENTER("(action %p, plugin_page %p)", action, plugin_page);
2710 
2711  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
2712 
2713  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
2714  reg = gnc_ledger_display_get_split_register (priv->ledger);
2715  ledger_type = gnc_ledger_display_type(priv->ledger);
2716  if (ledger_type == LD_SINGLE || ledger_type == LD_SUBACCOUNT)
2717  {
2718  account = gnc_plugin_page_register_get_account (plugin_page);
2720  trans = xaccSplitGetParent(split);
2721 
2722  if (split && trans)
2723  {
2724  if (xaccSplitGetAccount(split) == account)
2725  {
2726  splits = g_list_append(splits, split);
2727  gnc_ui_print_check_dialog_create(plugin_page, splits);
2728  g_list_free(splits);
2729  }
2730  else
2731  {
2732  /* This split is not for the account shown in this register. Get the
2733  split that anchors the transaction to the registor */
2734  split = gnc_split_register_get_current_trans_split(reg, NULL);
2735  if (split)
2736  {
2737  splits = g_list_append(splits, split);
2738  gnc_ui_print_check_dialog_create(plugin_page, splits);
2739  g_list_free(splits);
2740  }
2741  }
2742  }
2743  }
2744  else if (ledger_type == LD_GL && reg->type == SEARCH_LEDGER)
2745  {
2746  Account *common_acct = NULL;
2747  splits = qof_query_run(gnc_ledger_display_get_query(priv->ledger));
2748  /* Make sure each split is from the same account */
2749  for (item = splits; item; item = g_list_next(item))
2750  {
2751  split = (Split *) item->data;
2752  if (common_acct == NULL)
2753  {
2754  common_acct = xaccSplitGetAccount(split);
2755  }
2756  else
2757  {
2758  if (xaccSplitGetAccount(split) != common_acct)
2759  {
2760  GtkWidget *dialog, *window;
2761  gint response;
2762  const gchar *title = _("Print checks from multiple accounts?");
2763  const gchar *message =
2764  _("This search result contains splits from more than one account. "
2765  "Do you want to print the checks even though they are not all "
2766  "from the same account?");
2767  window = gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(plugin_page));
2768  dialog = gtk_message_dialog_new(GTK_WINDOW(window),
2769  GTK_DIALOG_DESTROY_WITH_PARENT,
2770  GTK_MESSAGE_WARNING,
2771  GTK_BUTTONS_CANCEL,
2772  "%s", title);
2773  gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
2774  "%s", message);
2775  gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Print checks"),
2776  GTK_RESPONSE_YES);
2777  response = gnc_dialog_run(GTK_DIALOG(dialog),
2778  GNC_PREF_WARN_CHECKPRINTING_MULTI_ACCT);
2779  gtk_widget_destroy(dialog);
2780  if (response != GTK_RESPONSE_YES)
2781  {
2782  LEAVE("Multiple accounts");
2783  return;
2784  }
2785  break;
2786  }
2787  }
2788  }
2789  gnc_ui_print_check_dialog_create(plugin_page, splits);
2790  }
2791  else
2792  {
2793  gnc_error_dialog(gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(plugin_page)), "%s",
2794  _("You can only print checks from a bank account register or search results."));
2795  LEAVE("Unsupported ledger type");
2796  return;
2797  }
2798  LEAVE(" ");
2799 }
2800 
2801 
2802 static void
2803 gnc_plugin_page_register_cmd_cut (GtkAction *action,
2804  GncPluginPageRegister *page)
2805 {
2807 
2808  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2809 
2810  ENTER("(action %p, page %p)", action, page);
2811  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2812  gnucash_register_cut_clipboard(priv->gsr->reg);
2813  LEAVE("");
2814 }
2815 
2816 
2817 static void
2818 gnc_plugin_page_register_cmd_copy (GtkAction *action,
2819  GncPluginPageRegister *page)
2820 {
2822 
2823  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2824 
2825  ENTER("(action %p, page %p)", action, page);
2826  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2827  gnucash_register_copy_clipboard(priv->gsr->reg);
2828  LEAVE("");
2829 }
2830 
2831 
2832 static void
2833 gnc_plugin_page_register_cmd_paste (GtkAction *action,
2834  GncPluginPageRegister *page)
2835 {
2837 
2838  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2839 
2840  ENTER("(action %p, page %p)", action, page);
2841  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2842  gnucash_register_paste_clipboard(priv->gsr->reg);
2843  LEAVE("");
2844 }
2845 
2846 
2847 static void
2848 gnc_plugin_page_register_cmd_edit_account (GtkAction *action,
2849  GncPluginPageRegister *page)
2850 {
2851  Account *account;
2852 
2853  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2854 
2855  ENTER("(action %p, page %p)", action, page);
2856  account = gnc_plugin_page_register_get_account (page);
2857  if (account)
2858  gnc_ui_edit_account_window (account);
2859  LEAVE(" ");
2860 }
2861 
2862 
2863 static void
2864 gnc_plugin_page_register_cmd_find_transactions (GtkAction *action,
2865  GncPluginPageRegister *page)
2866 {
2868 
2869  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2870 
2871  ENTER("(action %p, page %p)", action, page);
2872  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2873  gnc_ui_find_transactions_dialog_create(priv->ledger);
2874  LEAVE(" ");
2875 }
2876 
2877 
2878 static void
2879 gnc_plugin_page_register_cmd_cut_transaction (GtkAction *action,
2880  GncPluginPageRegister *page)
2881 {
2883  SplitRegister *reg;
2884 
2885  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2886 
2887  ENTER("(action %p, page %p)", action, page);
2888  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2889  reg = gnc_ledger_display_get_split_register(priv->ledger);
2891  LEAVE(" ");
2892 }
2893 
2894 
2895 static void
2896 gnc_plugin_page_register_cmd_copy_transaction (GtkAction *action,
2897  GncPluginPageRegister *page)
2898 {
2900  SplitRegister *reg;
2901 
2902  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2903 
2904  ENTER("(action %p, page %p)", action, page);
2905  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2906  reg = gnc_ledger_display_get_split_register(priv->ledger);
2908  LEAVE(" ");
2909 }
2910 
2911 
2912 static void
2913 gnc_plugin_page_register_cmd_paste_transaction (GtkAction *action,
2914  GncPluginPageRegister *page)
2915 {
2917  SplitRegister *reg;
2918 
2919  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2920 
2921  ENTER("(action %p, page %p)", action, page);
2922  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2923  reg = gnc_ledger_display_get_split_register(priv->ledger);
2925  LEAVE(" ");
2926 }
2927 
2928 
2929 static void
2930 gnc_plugin_page_register_cmd_void_transaction (GtkAction *action,
2931  GncPluginPageRegister *page)
2932 {
2934  GtkWidget *dialog, *entry;
2935  SplitRegister *reg;
2936  Transaction *trans;
2937  GtkBuilder *builder;
2938  const char *reason;
2939  gint result;
2940 
2941  ENTER("(action %p, page %p)", action, page);
2942 
2943  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2944 
2945  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2946  reg = gnc_ledger_display_get_split_register(priv->ledger);
2948  if (trans == NULL)
2949  return;
2950  if (xaccTransHasSplitsInState(trans, VREC))
2951  return;
2953  {
2954  gnc_error_dialog(NULL, "%s", _("You cannot void a transaction with reconciled or cleared splits."));
2955  return;
2956  }
2957 
2958  if (!gnc_plugin_page_register_finish_pending(GNC_PLUGIN_PAGE(page)))
2959  return;
2960 
2961  builder = gtk_builder_new();
2962  gnc_builder_add_from_file (builder , "gnc-plugin-page-register.glade", "Void Transaction");
2963  dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Void Transaction"));
2964  entry = GTK_WIDGET(gtk_builder_get_object (builder, "reason"));
2965 
2966  result = gtk_dialog_run(GTK_DIALOG(dialog));
2967  if (result == GTK_RESPONSE_OK)
2968  {
2969  reason = gtk_entry_get_text(GTK_ENTRY(entry));
2970  if (reason == NULL)
2971  reason = "";
2973  }
2974 
2975  /* All done. Get rid of it. */
2976  gtk_widget_destroy(dialog);
2977  g_object_unref(G_OBJECT(builder));
2978 }
2979 
2980 
2981 static void
2982 gnc_plugin_page_register_cmd_unvoid_transaction (GtkAction *action,
2983  GncPluginPageRegister *page)
2984 {
2986  SplitRegister *reg;
2987  Transaction *trans;
2988 
2989  ENTER("(action %p, page %p)", action, page);
2990 
2991  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
2992 
2993  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
2994  reg = gnc_ledger_display_get_split_register(priv->ledger);
2996  if (!xaccTransHasSplitsInState(trans, VREC))
2997  return;
2999  LEAVE(" ");
3000 }
3001 
3002 
3003 static void
3004 gnc_plugin_page_register_cmd_reverse_transaction (GtkAction *action,
3005  GncPluginPageRegister *page)
3006 {
3008  SplitRegister *reg;
3009  GNCSplitReg *gsr;
3010  Transaction *trans, *new_trans;
3011 
3012  ENTER("(action %p, page %p)", action, page);
3013 
3014  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3015 
3016  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
3017  reg = gnc_ledger_display_get_split_register(priv->ledger);
3019  if (trans == NULL)
3020  return;
3021 
3022  if (xaccTransGetReversedBy(trans))
3023  {
3024  gnc_error_dialog(gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(page)), "%s",
3025  _("A reversing entry has already been created for this transaction."));
3026  return;
3027  }
3028 
3030  new_trans = xaccTransReverse(trans);
3031 
3032  /* Clear transaction level info */
3033  xaccTransSetDatePostedSecsNormalized (new_trans, gnc_time (NULL));
3034  xaccTransSetDateEnteredSecs (new_trans, gnc_time (NULL));
3035 
3036  qof_event_resume();
3037 
3038  /* Now jump to new trans */
3039  gsr = gnc_plugin_page_register_get_gsr(GNC_PLUGIN_PAGE(page));
3040  gnc_split_reg_jump_to_split(gsr, xaccTransGetSplit(new_trans, 0));
3041  LEAVE(" ");
3042 }
3043 
3044 static void
3045 gnc_plugin_page_register_cmd_view_sort_by (GtkAction *action,
3046  GncPluginPageRegister *page)
3047 {
3049  SplitRegister *reg;
3050  GtkWidget *dialog, *button;
3051  GtkBuilder *builder;
3052  SortType sort;
3053  const gchar *name;
3054  gchar *title;
3055 
3056  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3057  ENTER("(action %p, page %p)", action, page);
3058 
3059  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
3060  if (priv->sd.dialog)
3061  {
3062  gtk_window_present(GTK_WINDOW(priv->sd.dialog));
3063  LEAVE("existing dialog");
3064  return;
3065  }
3066 
3067  /* Create the dialog */
3068 
3069  builder = gtk_builder_new();
3070  gnc_builder_add_from_file (builder, "gnc-plugin-page-register.glade", "Sort By");
3071  dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Sort By"));
3072  priv->sd.dialog = dialog;
3073  gtk_window_set_transient_for(GTK_WINDOW(dialog),
3074  gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window)));
3075  /* Translations: The %s is the name of the plugin page */
3076  title = g_strdup_printf(_("Sort %s by..."),
3077  gnc_plugin_page_get_page_name(GNC_PLUGIN_PAGE(page)));
3078  gtk_window_set_title(GTK_WINDOW(dialog), title);
3079  g_free(title);
3080 
3081  /* Set the button for the current sort order */
3082  sort = gnc_split_reg_get_sort_type(priv->gsr);
3083  name = SortTypeasString(sort);
3084  button = GTK_WIDGET(gtk_builder_get_object (builder, name));
3085  DEBUG("current sort %d, button %s(%p)", sort, name, button);
3086  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
3087  priv->sd.original_sort_type = sort;
3088 
3089  button = GTK_WIDGET(gtk_builder_get_object (builder, "sort_save"));
3090  if (priv->sd.save_order == TRUE)
3091  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
3092 
3093  /* Set the button for the current reverse_order order */
3094  button = GTK_WIDGET(gtk_builder_get_object (builder, "sort_reverse"));
3095  if(priv->sd.reverse_order == TRUE)
3096  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
3097 
3098  priv->sd.num_radio = GTK_WIDGET(gtk_builder_get_object (builder, "BY_NUM"));
3099  priv->sd.act_radio = GTK_WIDGET(gtk_builder_get_object (builder, "BY_ACTION"));
3100  /* Adjust labels related to Num/Action radio buttons based on book option */
3101  reg = gnc_ledger_display_get_split_register(priv->ledger);
3102  if (reg && !reg->use_tran_num_for_num_field)
3103  {
3104  gtk_button_set_label(GTK_BUTTON (priv->sd.num_radio), _("Transaction Number"));
3105  gtk_button_set_label(GTK_BUTTON (priv->sd.act_radio), _("Number/Action"));
3106  }
3107  gnc_book_option_register_cb(OPTION_NAME_NUM_FIELD_SOURCE,
3108  gnc_plugin_page_register_sort_book_option_changed,
3109  page);
3110 
3111  /* Wire it up */
3112  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, page);
3113 
3114  /* Show it */
3115  gtk_widget_show(dialog);
3116  g_object_unref(G_OBJECT(builder));
3117  LEAVE(" ");
3118 }
3119 
3120 static void
3121 gnc_plugin_page_register_cmd_view_filter_by (GtkAction *action,
3122  GncPluginPageRegister *page)
3123 {
3125  GtkWidget *dialog, *toggle, *button, *table, *hbox;
3126  time64 start_time, end_time, time_val;
3127  GtkBuilder *builder;
3128  gboolean sensitive, value;
3129  Query *query;
3130  gchar *title;
3131  int i;
3132 
3133  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3134  ENTER("(action %p, page %p)", action, page);
3135 
3136  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
3137  if (priv->fd.dialog)
3138  {
3139  gtk_window_present(GTK_WINDOW(priv->fd.dialog));
3140  LEAVE("existing dialog");
3141  return;
3142  }
3143 
3144  /* Create the dialog */
3145  builder = gtk_builder_new();
3146  gnc_builder_add_from_file (builder, "gnc-plugin-page-register.glade", "Filter By");
3147  dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Filter By"));
3148  priv->fd.dialog = dialog;
3149  gtk_window_set_transient_for(GTK_WINDOW(dialog),
3150  gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window)));
3151 
3152  /* Translators: The %s is the name of the plugin page */
3153  title = g_strdup_printf(_("Filter %s by..."),
3154  gnc_plugin_page_get_page_name(GNC_PLUGIN_PAGE(page)));
3155  gtk_window_set_title(GTK_WINDOW(dialog), title);
3156  g_free(title);
3157 
3158  /* Set the check buttons for the current status */
3159  for (i = 0; status_actions[i].action_name; i++)
3160  {
3161  toggle = GTK_WIDGET(gtk_builder_get_object (builder, status_actions[i].action_name));
3162  value = priv->fd.cleared_match & status_actions[i].value;
3163  status_actions[i].widget = toggle;
3164  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), value);
3165  }
3166  priv->fd.original_cleared_match = priv->fd.cleared_match;
3167 
3168  button = GTK_WIDGET(gtk_builder_get_object (builder, "filter_save"));
3169  if (priv->fd.save_filter == TRUE)
3170  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
3171 
3172 
3173  /* Set the date info */
3174  button = GTK_WIDGET(gtk_builder_get_object (builder, "filter_show_range"));
3175  query = gnc_ledger_display_get_query (priv->ledger);
3176  xaccQueryGetDateMatchTT(query, &start_time, &end_time);
3177  priv->fd.original_start_time = start_time;
3178  priv->fd.start_time = start_time;
3179  priv->fd.original_end_time = end_time;
3180  priv->fd.end_time = end_time;
3181 
3182  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), start_time || end_time);
3183  table = GTK_WIDGET(gtk_builder_get_object (builder, "select_range_table"));
3184  priv->fd.table = table;
3185  gtk_widget_set_sensitive(GTK_WIDGET(table), start_time || end_time);
3186 
3187  priv->fd.start_date_choose = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_choose"));
3188  priv->fd.start_date_today = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_today"));
3189  priv->fd.end_date_choose = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_choose"));
3190  priv->fd.end_date_today = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_today"));
3191 
3192  {
3193  /* Start date info */
3194  if (start_time == 0)
3195  {
3196  button = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_earliest"));
3197  time_val = xaccQueryGetEarliestDateFound (query);
3198  sensitive = FALSE;
3199  }
3200  else
3201  {
3202  time_val = start_time;
3203  if ((start_time >= gnc_time64_get_today_start()) &&
3204  (start_time <= gnc_time64_get_today_end()))
3205  {
3206  button = priv->fd.start_date_today;
3207  sensitive = FALSE;
3208  }
3209  else
3210  {
3211  button = priv->fd.start_date_choose;
3212  sensitive = TRUE;
3213  }
3214  }
3215  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
3216  priv->fd.start_date = gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE);
3217  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_hbox"));
3218  gtk_box_pack_start (GTK_BOX (hbox), priv->fd.start_date, TRUE, TRUE, 0);
3219  gtk_widget_show (priv->fd.start_date);
3220  gtk_widget_set_sensitive(GTK_WIDGET(priv->fd.start_date), sensitive);
3221  gnc_date_edit_set_time (GNC_DATE_EDIT(priv->fd.start_date), time_val);
3222  g_signal_connect (G_OBJECT (priv->fd.start_date), "date-changed",
3223  G_CALLBACK (gnc_plugin_page_register_filter_gde_changed_cb),
3224  page);
3225  }
3226 
3227  {
3228  /* End date info */
3229  if (end_time == 0)
3230  {
3231  button = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_latest"));
3232  time_val = xaccQueryGetLatestDateFound (query);
3233  sensitive = FALSE;
3234  }
3235  else
3236  {
3237  time_val = end_time;
3238  if ((end_time >= gnc_time64_get_today_start()) &&
3239  (end_time <= gnc_time64_get_today_end()))
3240  {
3241  button = priv->fd.end_date_today;
3242  sensitive = FALSE;
3243  }
3244  else
3245  {
3246  button = priv->fd.end_date_choose;
3247  sensitive = TRUE;
3248  }
3249  }
3250  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
3251  priv->fd.end_date = gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE);
3252  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_hbox"));
3253  gtk_box_pack_start (GTK_BOX (hbox), priv->fd.end_date, TRUE, TRUE, 0);
3254  gtk_widget_show (priv->fd.end_date);
3255  gtk_widget_set_sensitive(GTK_WIDGET(priv->fd.end_date), sensitive);
3256  gnc_date_edit_set_time (GNC_DATE_EDIT(priv->fd.end_date), time_val);
3257  g_signal_connect (G_OBJECT (priv->fd.end_date), "date-changed",
3258  G_CALLBACK (gnc_plugin_page_register_filter_gde_changed_cb),
3259  page);
3260  }
3261 
3262  /* Wire it up */
3263  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, page);
3264 
3265  /* Show it */
3266  gtk_widget_show_all(dialog);
3267  g_object_unref(G_OBJECT(builder));
3268  LEAVE(" ");
3269 }
3270 
3271 static void
3272 gnc_plugin_page_register_cmd_style_changed (GtkAction *action,
3273  GtkRadioAction *current,
3274  GncPluginPageRegister *plugin_page)
3275 {
3277  SplitRegisterStyle value;
3278 
3279  ENTER("(action %p, radio action %p, plugin_page %p)",
3280  action, current, plugin_page);
3281 
3282  g_return_if_fail(GTK_IS_ACTION(action));
3283  g_return_if_fail(GTK_IS_RADIO_ACTION(current));
3284  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3285 
3286  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3287  value = gtk_radio_action_get_current_value(current);
3288  gnc_split_reg_change_style(priv->gsr, value);
3289 
3290  gnc_plugin_page_register_ui_update (NULL, plugin_page);
3291  LEAVE(" ");
3292 }
3293 
3294 static void
3295 gnc_plugin_page_register_cmd_style_double_line (GtkToggleAction *action,
3296  GncPluginPageRegister *plugin_page)
3297 {
3299  SplitRegister *reg;
3300  gboolean use_double_line;
3301 
3302  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3303 
3304  g_return_if_fail(GTK_IS_ACTION(action));
3305  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3306 
3307  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3308  reg = gnc_ledger_display_get_split_register (priv->ledger);
3309 
3310  use_double_line = gtk_toggle_action_get_active (action);
3311  if (use_double_line != reg->use_double_line)
3312  {
3313  gnc_split_register_config(reg, reg->type, reg->style, use_double_line);
3314  gnc_ledger_display_refresh(priv->ledger);
3315  }
3316  LEAVE(" ");
3317 }
3318 
3319 static void
3320 gnc_plugin_page_register_cmd_transfer (GtkAction *action,
3321  GncPluginPageRegister *page)
3322 {
3323  Account *account;
3324  GncWindow *gnc_window;
3325  GtkWidget *window;
3326 
3327  ENTER("(action %p, plugin_page %p)", action, page);
3328 
3329  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3330 
3331  account = gnc_plugin_page_register_get_account (page);
3332  gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window);
3333  window = GTK_WIDGET(gnc_window_get_gtk_window(gnc_window));
3334  gnc_xfer_dialog (window, account);
3335  LEAVE(" ");
3336 }
3337 
3338 static void
3339 gnc_plugin_page_register_cmd_reconcile (GtkAction *action,
3340  GncPluginPageRegister *page)
3341 {
3342  Account *account;
3343  GtkWindow *window;
3344  RecnWindow * recnData;
3345 
3346  ENTER("(action %p, plugin_page %p)", action, page);
3347 
3348  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3349 
3350  account = gnc_plugin_page_register_get_account (page);
3351 
3352  window = gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window));
3353  recnData = recnWindow (GTK_WIDGET(window), account);
3354  gnc_ui_reconcile_window_raise (recnData);
3355  LEAVE(" ");
3356 }
3357 
3358 static void
3359 gnc_plugin_page_register_cmd_autoclear (GtkAction *action,
3360  GncPluginPageRegister *page)
3361 {
3362  Account *account;
3363  GtkWindow *window;
3364  AutoClearWindow * autoClearData;
3365 
3366  ENTER("(action %p, plugin_page %p)", action, page);
3367 
3368  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3369 
3370  account = gnc_plugin_page_register_get_account (page);
3371 
3372  window = gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window));
3373  autoClearData = autoClearWindow (GTK_WIDGET(window), account);
3374  gnc_ui_autoclear_window_raise (autoClearData);
3375  LEAVE(" ");
3376 }
3377 
3378 static void
3379 gnc_plugin_page_register_cmd_stock_split (GtkAction *action,
3380  GncPluginPageRegister *page)
3381 {
3382  Account *account;
3383 
3384  ENTER("(action %p, plugin_page %p)", action, page);
3385 
3386  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3387 
3388  account = gnc_plugin_page_register_get_account (page);
3389  gnc_stock_split_dialog (NULL, account);
3390  LEAVE(" ");
3391 }
3392 
3393 static void
3394 gnc_plugin_page_register_cmd_lots (GtkAction *action,
3395  GncPluginPageRegister *page)
3396 {
3397  Account *account;
3398 
3399  ENTER("(action %p, plugin_page %p)", action, page);
3400 
3401  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3402 
3403  account = gnc_plugin_page_register_get_account (page);
3404  gnc_lot_viewer_dialog (account);
3405  LEAVE(" ");
3406 }
3407 
3408 static void
3409 gnc_plugin_page_register_cmd_enter_transaction (GtkAction *action,
3410  GncPluginPageRegister *plugin_page)
3411 {
3413 
3414  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3415 
3416  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3417 
3418  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3419  gnc_split_reg_enter(priv->gsr, FALSE);
3420  LEAVE(" ");
3421 }
3422 
3423 static void
3424 gnc_plugin_page_register_cmd_cancel_transaction (GtkAction *action,
3425  GncPluginPageRegister *plugin_page)
3426 {
3428 
3429  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3430 
3431  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3432 
3433  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3435  (gnc_ledger_display_get_split_register(priv->ledger));
3436  LEAVE(" ");
3437 }
3438 
3439 static void
3440 gnc_plugin_page_register_cmd_delete_transaction (GtkAction *action,
3441  GncPluginPageRegister *plugin_page)
3442 {
3444 
3445  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3446 
3447  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3448 
3449  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3450  gsr_default_delete_handler(priv->gsr, NULL);
3451  LEAVE(" ");
3452 
3453 }
3454 
3455 static void
3456 gnc_plugin_page_register_cmd_associate_file_transaction (GtkAction *action,
3457  GncPluginPageRegister *plugin_page)
3458 {
3460 
3461  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3462 
3463  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3464 
3465  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3466  gsr_default_associate_handler_file(priv->gsr, NULL);
3467  gnc_plugin_page_register_ui_update (NULL, plugin_page);
3468  LEAVE(" ");
3469 
3470 }
3471 
3472 static void
3473 gnc_plugin_page_register_cmd_associate_location_transaction (GtkAction *action,
3474  GncPluginPageRegister *plugin_page)
3475 {
3477 
3478  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3479 
3480  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3481 
3482  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3483  gsr_default_associate_handler_location(priv->gsr, NULL);
3484  gnc_plugin_page_register_ui_update (NULL, plugin_page);
3485  LEAVE(" ");
3486 
3487 }
3488 
3489 static void
3490 gnc_plugin_page_register_cmd_execassociated_transaction (GtkAction *action,
3491  GncPluginPageRegister *plugin_page)
3492 {
3494 
3495  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3496 
3497  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3498 
3499  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3500  gsr_default_execassociated_handler(priv->gsr, NULL);
3501  LEAVE(" ");
3502 
3503 }
3504 
3505 static void
3506 gnc_plugin_page_register_cmd_blank_transaction (GtkAction *action,
3507  GncPluginPageRegister *plugin_page)
3508 {
3510  SplitRegister *reg;
3511 
3512  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3513 
3514  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3515 
3516  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3517  reg = gnc_ledger_display_get_split_register (priv->ledger);
3518 
3519  if (gnc_split_register_save (reg, TRUE))
3521 
3522  gnc_split_reg_jump_to_blank (priv->gsr);
3523  LEAVE(" ");
3524 }
3525 
3526 static void
3527 gnc_plugin_page_register_cmd_duplicate_transaction (GtkAction *action,
3528  GncPluginPageRegister *plugin_page)
3529 {
3531 
3532  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3533 
3534  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3535 
3536  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3538  (gnc_ledger_display_get_split_register(priv->ledger));
3539  LEAVE(" ");
3540 }
3541 
3542 static void
3543 gnc_plugin_page_register_cmd_reinitialize_transaction (GtkAction *action,
3544  GncPluginPageRegister *plugin_page)
3545 {
3547 
3548  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3549 
3550  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3551 
3552  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3553  gsr_default_reinit_handler(priv->gsr, NULL);
3554  LEAVE(" ");
3555 }
3556 
3557 static void
3558 gnc_plugin_page_register_cmd_expand_transaction (GtkToggleAction *action,
3559  GncPluginPageRegister *plugin_page)
3560 {
3562  SplitRegister *reg;
3563  gboolean expand;
3564 
3565  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3566 
3567  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3568 
3569  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3570  reg = gnc_ledger_display_get_split_register (priv->ledger);
3571  expand = gtk_toggle_action_get_active (action);
3573  LEAVE(" ");
3574 }
3575 
3576 static void
3577 gnc_plugin_page_register_cmd_exchange_rate (GtkAction *action,
3578  GncPluginPageRegister *plugin_page)
3579 {
3581  SplitRegister *reg;
3582 
3583  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3584 
3585  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3586 
3587  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3588  reg = gnc_ledger_display_get_split_register (priv->ledger);
3589 
3590  /* XXX Ignore the return value -- we don't care if this succeeds */
3591  (void)gnc_split_register_handle_exchange (reg, TRUE);
3592  LEAVE(" ");
3593 }
3594 
3595 static void
3596 gnc_plugin_page_register_cmd_jump (GtkAction *action,
3597  GncPluginPageRegister *plugin_page)
3598 {
3600  GncPluginPage *new_page;
3601  GtkWidget *window;
3602  GNCSplitReg *gsr;
3603  SplitRegister *reg;
3604  Account *account;
3605  Account *leader;
3606  Split *split;
3607 
3608  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3609 
3610  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3611 
3612  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3613  window = GNC_PLUGIN_PAGE (plugin_page)->window;
3614  if (window == NULL)
3615  {
3616  LEAVE("no window");
3617  return;
3618  }
3619 
3620  reg = gnc_ledger_display_get_split_register (priv->ledger);
3622  if (split == NULL)
3623  {
3624  LEAVE("no split (1)");
3625  return;
3626  }
3627 
3628  account = xaccSplitGetAccount (split);
3629  if (account == NULL)
3630  {
3631  LEAVE("no account");
3632  return;
3633  }
3634 
3635  leader = gnc_ledger_display_leader (priv->ledger);
3636  if (account == leader)
3637  {
3638  split = xaccSplitGetOtherSplit (split);
3639  if (split == NULL)
3640  {
3641  LEAVE("no split (2)");
3642  return;
3643  }
3644 
3645  account = xaccSplitGetAccount (split);
3646  if (account == NULL)
3647  {
3648  LEAVE("no account (2)");
3649  return;
3650  }
3651 
3652  if (account == leader)
3653  {
3654  LEAVE("register open for account");
3655  return;
3656  }
3657  }
3658 
3659  new_page = gnc_plugin_page_register_new (account, FALSE);
3660  if (new_page == NULL)
3661  {
3662  LEAVE("couldn't create new page");
3663  return;
3664  }
3665 
3666  gnc_main_window_open_page (GNC_MAIN_WINDOW(window), new_page);
3667  gsr = gnc_plugin_page_register_get_gsr (new_page);
3668  gnc_split_reg_jump_to_split(gsr, split);
3669  LEAVE(" ");
3670 }
3671 
3672 static void
3673 gnc_plugin_page_register_cmd_schedule (GtkAction *action,
3674  GncPluginPageRegister *plugin_page)
3675 {
3677 
3678  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3679 
3680  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3681 
3682  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3683  gsr_default_schedule_handler(priv->gsr, NULL);
3684  LEAVE(" ");
3685 }
3686 
3687 static void
3688 gnc_plugin_page_register_cmd_scrub_current (GtkAction *action,
3689  GncPluginPageRegister *plugin_page)
3690 {
3692  Query *query;
3693  Account *root;
3694  Transaction *trans;
3695  Split *split;
3696  GNCLot *lot;
3697  SplitRegister *reg;
3698 
3699  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3700 
3701  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3702 
3703  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3704  query = gnc_ledger_display_get_query( priv->ledger );
3705  if (query == NULL)
3706  {
3707  LEAVE("no query found");
3708  return;
3709  }
3710 
3711  reg = gnc_ledger_display_get_split_register(priv->ledger);
3713  if (trans == NULL)
3714  {
3715  LEAVE("no trans found");
3716  return;
3717  }
3718 
3719  gnc_suspend_gui_refresh();
3720  root = gnc_get_current_root_account();
3721  xaccTransScrubOrphans(trans);
3722  xaccTransScrubImbalance(trans, root, NULL);
3723 
3725  lot = xaccSplitGetLot (split);
3727  gncScrubBusinessLot (lot);
3728  gnc_resume_gui_refresh();
3729  LEAVE(" ");
3730 }
3731 
3732 static void
3733 gnc_plugin_page_register_cmd_scrub_all (GtkAction *action,
3734  GncPluginPageRegister *plugin_page)
3735 {
3737  Query *query;
3738  Account *root;
3739  Transaction *trans;
3740  GNCLot *lot;
3741  Split *split;
3742  GList *node;
3743 
3744  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3745 
3746  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3747 
3748  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3749  query = gnc_ledger_display_get_query( priv->ledger );
3750  if (!query)
3751  {
3752  LEAVE("no query found");
3753  return;
3754  }
3755 
3756  gnc_suspend_gui_refresh();
3757  root = gnc_get_current_root_account();
3758 
3759  for (node = qof_query_run(query); node; node = node->next)
3760  {
3761  split = node->data;
3762  trans = xaccSplitGetParent(split);
3763 
3764  xaccTransScrubOrphans(trans);
3765  xaccTransScrubImbalance(trans, root, NULL);
3766 
3767  lot = xaccSplitGetLot (split);
3769  gncScrubBusinessLot (lot);
3770  }
3771 
3772  gnc_resume_gui_refresh();
3773  LEAVE(" ");
3774 }
3775 
3776 static void
3777 gnc_plugin_page_register_cmd_account_report (GtkAction *action,
3778  GncPluginPageRegister *plugin_page)
3779 {
3781  GncMainWindow *window;
3782  int id;
3783 
3784  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3785 
3786  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3787 
3788  window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
3789  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3790  id = report_helper (priv->ledger, NULL, NULL);
3791  if (id >= 0)
3792  gnc_main_window_open_report(id, window);
3793  LEAVE(" ");
3794 }
3795 
3796 static void
3797 gnc_plugin_page_register_cmd_transaction_report (GtkAction *action,
3798  GncPluginPageRegister *plugin_page)
3799 {
3801  GncMainWindow *window;
3802  SplitRegister *reg;
3803  Split *split;
3804  Query *query;
3805  int id;
3806 
3807 
3808  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3809 
3810  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3811 
3812  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
3813  reg = gnc_ledger_display_get_split_register (priv->ledger);
3814 
3816  if (!split)
3817  return;
3818 
3819  query = qof_query_create_for(GNC_ID_SPLIT);
3820 
3821  qof_query_set_book (query, gnc_get_current_book ());
3822 
3823  xaccQueryAddGUIDMatch (query, xaccSplitGetGUID (split),
3824  GNC_ID_SPLIT, QOF_QUERY_AND);
3825 
3826  window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
3827  id = report_helper (priv->ledger, split, query);
3828  if (id >= 0)
3829  gnc_main_window_open_report(id, window);
3830  LEAVE(" ");
3831 }
3832 
3833 /************************************************************/
3834 /* Auxiliary functions */
3835 /************************************************************/
3836 
3837 void
3839  gint lines_default,
3840  gboolean read_only)
3841 {
3842  GncPluginPageRegister *page;
3844 
3845  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
3846 
3847  page = GNC_PLUGIN_PAGE_REGISTER (plugin_page);
3848  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
3849  priv->lines_default = lines_default;
3850  priv->read_only = read_only;
3851 }
3852 
3853 GNCSplitReg *
3855 {
3856  GncPluginPageRegister *page;
3858 
3859  g_return_val_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page), NULL);
3860 
3861  page = GNC_PLUGIN_PAGE_REGISTER (plugin_page);
3862  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
3863 
3864  return priv->gsr;
3865 }
3866 
3867 static void
3868 gnc_plugin_page_help_changed_cb (GNCSplitReg *gsr, GncPluginPageRegister *register_page)
3869 {
3871  SplitRegister *reg;
3872  GncWindow *window;
3873  char *help;
3874 
3875  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(register_page));
3876 
3877  window = GNC_WINDOW(GNC_PLUGIN_PAGE(register_page)->window);
3878  if (!window)
3879  {
3880  // This routine can be called before the page is added to a
3881  // window.
3882  return;
3883  }
3884 
3885  /* Get the text from the ledger */
3886  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(register_page);
3887  reg = gnc_ledger_display_get_split_register(priv->ledger);
3888  help = gnc_table_get_help(reg->table);
3889  gnc_window_set_status(window, GNC_PLUGIN_PAGE(register_page), help);
3890  g_free(help);
3891 }
3892 
3893 static void
3894 gnc_plugin_page_register_refresh_cb (GHashTable *changes, gpointer user_data)
3895 {
3896  GncPluginPageRegister *page = user_data;
3898 
3899  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(page));
3900  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
3901 
3902  if (changes)
3903  {
3904  const EventInfo* ei;
3905  ei = gnc_gui_get_entity_events(changes, &priv->key);
3906  if (ei)
3907  {
3908  if (ei->event_mask & QOF_EVENT_DESTROY)
3909  {
3910  gnc_main_window_close_page(GNC_PLUGIN_PAGE(page));
3911  return;
3912  }
3913  if (ei->event_mask & QOF_EVENT_MODIFY)
3914  {
3915  }
3916  }
3917  }
3918  else
3919  {
3920  /* forced updates */
3921  gnucash_register_refresh_from_prefs(priv->gsr->reg);
3922  gtk_widget_queue_draw(priv->widget);
3923  }
3924 
3925  gnc_plugin_page_register_ui_update(NULL, page);
3926 }
3927 
3928 static void
3929 gnc_plugin_page_register_close_cb (gpointer user_data)
3930 {
3931  GncPluginPage *plugin_page = GNC_PLUGIN_PAGE(user_data);
3932  gnc_main_window_close_page (plugin_page);
3933 }
3934 
3943 static void
3944 gppr_account_destroy_cb (Account *account)
3945 {
3946  GncPluginPageRegister *page;
3948  GNCLedgerDisplayType ledger_type;
3949  const GncGUID *acct_guid;
3950  const GList *citem;
3951  GList *item, *kill = NULL;
3952 
3953  acct_guid = xaccAccountGetGUID(account);
3954 
3955  /* Find all windows that need to be killed. Don't kill them yet, as
3956  * that would affect the list being walked.*/
3957  citem = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_REGISTER_NAME);
3958  for ( ; citem; citem = g_list_next(citem))
3959  {
3960  page = (GncPluginPageRegister *)citem->data;
3961  priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
3962  ledger_type = gnc_ledger_display_type (priv->ledger);
3963  if (ledger_type == LD_GL)
3964  {
3965  kill = g_list_append(kill, page);
3966  /* kill it */
3967  }
3968  else if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
3969  {
3970  if (guid_compare(acct_guid, &priv->key) == 0)
3971  {
3972  kill = g_list_append(kill, page);
3973  }
3974  }
3975  }
3976 
3977  /* Now kill them. */
3978  for (item = kill; item; item = g_list_next(item))
3979  {
3980  page = (GncPluginPageRegister *)item->data;
3981  gnc_main_window_close_page(GNC_PLUGIN_PAGE(page));
3982  }
3983 }
3984 
3999 static void
4000 gnc_plugin_page_register_event_handler (QofInstance *entity,
4001  QofEventId event_type,
4002  GncPluginPageRegister *page,
4003  GncEventData *ed)
4004 {
4005  Transaction *trans;
4006  QofBook *book;
4007  GncPluginPage *visible_page;
4008  GtkWidget *window;
4009  gchar *label, *color;
4010 
4011  g_return_if_fail(page); /* Required */
4012  if (!GNC_IS_TRANS(entity) && !GNC_IS_ACCOUNT(entity))
4013  return;
4014 
4015  ENTER("entity %p of type %d, page %p, event data %p",
4016  entity, event_type, page, ed);
4017 
4018  window = gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(page));
4019 
4020  if (GNC_IS_ACCOUNT(entity))
4021  {
4022  if (GNC_IS_MAIN_WINDOW(window))
4023  {
4024  label = gnc_plugin_page_register_get_tab_name(GNC_PLUGIN_PAGE(page));
4025  main_window_update_page_name(GNC_PLUGIN_PAGE(page), label);
4026  color = gnc_plugin_page_register_get_tab_color(GNC_PLUGIN_PAGE(page));
4027  main_window_update_page_color(GNC_PLUGIN_PAGE(page), color);
4028  g_free(color);
4029  g_free(label);
4030  }
4031  LEAVE("tab name updated");
4032  return;
4033  }
4034 
4035  if (!(event_type & (QOF_EVENT_MODIFY | QOF_EVENT_DESTROY)))
4036  {
4037  LEAVE("not a modify");
4038  return;
4039  }
4040  trans = GNC_TRANS(entity);
4041  book = qof_instance_get_book(QOF_INSTANCE(trans));
4042  if (!gnc_plugin_page_has_book(GNC_PLUGIN_PAGE(page), book))
4043  {
4044  LEAVE("not in this book");
4045  return;
4046  }
4047 
4048  if (GNC_IS_MAIN_WINDOW(window))
4049  {
4050  visible_page = gnc_main_window_get_current_page(GNC_MAIN_WINDOW(window));
4051  if (visible_page != GNC_PLUGIN_PAGE(page))
4052  {
4053  LEAVE("page not visible");
4054  return;
4055  }
4056  }
4057 
4058  gnc_plugin_page_register_ui_update(NULL, page);
4059  LEAVE(" ");
4060  return;
4061 }
4062 
4063 
GncPluginPage * gnc_plugin_page_register_new(Account *account, gboolean subaccounts)
void xaccAccountSetFilter(Account *acc, const char *str)
Definition: Account.c:2308
void xaccAccountSetSortOrder(Account *acc, const char *str)
Definition: Account.c:2329
Transaction * gnc_split_register_get_current_trans(SplitRegister *reg)
const char * gnc_split_register_get_debit_string(SplitRegister *reg)
void gnc_split_register_void_current_trans(SplitRegister *reg, const char *reason)
GtkWidget * gnc_plugin_page_get_window(GncPluginPage *page)
gboolean xaccTransHasReconciledSplits(const Transaction *trans)
Definition: Transaction.c:2433
const gchar * tab_icon
time64 gnc_time64_get_today_start(void)
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
Definition: Transaction.c:1920
void gnc_plugin_page_register_filter_save_cb(GtkToggleButton *button, GncPluginPageRegister *page)
Split * xaccTransGetSplit(const Transaction *trans, int i)
Definition: Transaction.c:2144
const GList * gnc_gobject_tracking_get_list(const gchar *name)
GncPluginPage *(* recreate_page)(GtkWidget *window, GKeyFile *file, const gchar *group)
Date and Time handling routines.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Definition: gnc-prefs.c:128
Dialog for create/edit an account.
QofBook * qof_instance_get_book(gconstpointer)
void(* update_edit_menu_actions)(GncPluginPage *plugin_page, gboolean hide)
time64 gnc_time64_get_today_end(void)
utility functions for the GnuCash UI
void gnc_split_register_copy_current(SplitRegister *reg)
The type, style and table for the register.
#define PINFO(format, args...)
Definition: qoflog.h:249
const char * xaccAccountGetFilter(const Account *acc)
Definition: Account.c:3107
void qof_query_purge_terms(QofQuery *q, QofQueryParamList *param_list)
GNCAccountType xaccAccountGetType(const Account *acc)
Definition: Account.c:3009
gboolean use_tran_num_for_num_field
const char * xaccTransGetAssociation(const Transaction *trans)
Definition: Transaction.c:2190
void gnc_split_register_unvoid_current_trans(SplitRegister *reg)
Split * gnc_split_register_get_current_split(SplitRegister *reg)
#define DEBUG(format, args...)
Definition: qoflog.h:255
const gchar * gnc_plugin_page_get_page_name(GncPluginPage *page)
Functions that are supported by all types of windows.
void(* QofEventHandler)(QofInstance *ent, QofEventId event_type, gpointer handler_data, gpointer event_data)
Handler invoked when an event is generated.
Definition: qofevent.h:89
Split * gnc_split_register_get_current_trans_split(SplitRegister *reg, VirtualCellLocation *trans_split_loc)
gboolean gnc_split_register_changed(SplitRegister *reg)
void gnc_plugin_page_set_page_long_name(GncPluginPage *page, const char *name)
Transaction * xaccSplitGetParent(const Split *split)
Definition: Split.c:1903
void gnc_split_register_expand_current_trans(SplitRegister *reg, gboolean expand)
gboolean gnc_split_register_save(SplitRegister *reg, gboolean do_commit)
GtkActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
#define ENTER(format, args...)
Definition: qoflog.h:261
Cleanup functions for business objects.
struct _QofQuery QofQuery
Definition: qofquery.h:90
void gnc_plugin_page_register_filter_status_all_cb(GtkButton *button, GncPluginPageRegister *plugin_page)
GType gnc_plugin_page_register_get_type(void)
GncPluginPage * gnc_main_window_get_current_page(GncMainWindow *window)
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
void gnc_ui_edit_account_window(Account *account)
Functions for adding content to a window.
GncPluginPage * gnc_plugin_page_register_new_ledger(GNCLedgerDisplay *ledger)
Definition: guid.h:65
gboolean(* finish_pending)(GncPluginPage *plugin_page)
#define VREC
Definition: Split.h:71
gint qof_event_register_handler(QofEventHandler handler, gpointer handler_data)
Register a handler for events.
void gnc_tm_free(struct tm *time)
free a struct tm* created with gnc_localtime() or gnc_gmtime()
const char * xaccAccountGetColor(const Account *acc)
Definition: Account.c:3100
void gnc_split_register_redraw(SplitRegister *reg)
gboolean use_double_line
void gnc_plugin_page_register_filter_select_range_cb(GtkRadioButton *button, GncPluginPageRegister *page)
#define xaccAccountGetGUID(X)
Definition: Account.h:239
void gnc_plugin_page_register_sort_button_cb(GtkToggleButton *button, GncPluginPageRegister *page)
convert single-entry accounts to clean double-entry
gboolean xaccTransHasSplitsInState(const Transaction *trans, const char state)
Definition: Transaction.c:2463
QofBook * qof_session_get_book(const QofSession *session)
gchar * gnc_account_get_full_name(const Account *account)
Definition: Account.c:3038
void gnc_split_register_paste_current(SplitRegister *reg)
Functions providing a register page for the GnuCash UI.
void main_window_update_page_color(GncPluginPage *page, const gchar *color_in)
gint QofEventId
Definition: qofevent.h:45
Gobject helper routines.
void gnc_plugin_page_register_filter_end_cb(GtkWidget *radio, GncPluginPageRegister *page)
void gnc_plugin_page_set_use_new_window(GncPluginPage *page, gboolean use_new)
void gnc_plugin_page_register_filter_response_cb(GtkDialog *dialog, gint response, GncPluginPageRegister *plugin_page)
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Account * gnc_plugin_page_register2_get_account(GncPluginPageRegister2 *page)
void(* destroy_widget)(GncPluginPage *plugin_page)
void xaccTransScrubImbalance(Transaction *trans, Account *root, Account *account)
Definition: Scrub.c:521
void gnc_plugin_init_short_names(GtkActionGroup *action_group, action_toolbar_labels *toolbar_labels)
Definition: gnc-plugin.c:263
void gnc_plugin_page_register_filter_start_cb(GtkWidget *radio, GncPluginPageRegister *page)
Functions providing menu items from scheme code.
time64 gnc_time64_get_day_end(time64 time_val)
void qof_query_set_book(QofQuery *q, QofBook *book)
gboolean gnc_plugin_page_has_book(GncPluginPage *page, QofBook *book)
GnucashRegister * reg
Definition: gnc-split-reg.h:81
const gchar * plugin_name
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
Definition: Account.c:2915
time64 gnc_mktime(struct tm *time)
calculate seconds from the epoch given a time struct
void xaccTransScrubOrphans(Transaction *trans)
Definition: Scrub.c:124
Gnome specific utility functions.
gboolean xaccAccountIsAPARType(GNCAccountType t)
Definition: Account.c:4225
Additional event handling code.
#define xaccSplitGetGUID(X)
Definition: Split.h:521
struct tm * gnc_localtime(const time64 *secs)
fill out a time struct from a 64-bit time value.
gboolean gnc_split_register_current_trans_expanded(SplitRegister *reg)
All type declarations for the whole Gnucash engine.
#define CREC
Definition: Split.h:67
void gnc_plugin_page_register_filter_status_one_cb(GtkToggleButton *button, GncPluginPageRegister *page)
void(* window_changed)(GncPluginPage *plugin_page, GtkWidget *window)
Generic api to store and retrieve preferences.
CursorClass
Transaction * xaccTransReverse(Transaction *orig)
Definition: Transaction.c:2579
time64 gnc_time64_get_day_start(time64 time_val)
GList * qof_query_run(QofQuery *query)
const char * gnc_split_register_get_credit_string(SplitRegister *reg)
gboolean qof_book_is_readonly(const QofBook *book)
GtkAction * gnc_plugin_page_get_action(GncPluginPage *page, const gchar *name)
void gnc_plugin_page_set_page_color(GncPluginPage *page, const char *color)
gboolean gnc_split_register_handle_exchange(SplitRegister *reg, gboolean force_dialog)
GncPluginPage * gnc_plugin_page_register_new_gl(void)
void gnc_plugin_update_actions(GtkActionGroup *action_group, const gchar **action_names, const gchar *property_name, gboolean value)
Definition: gnc-plugin.c:313
Definition: SplitP.h:71
void qof_event_suspend(void)
Suspend all engine events.
gboolean gncScrubBusinessLot(GNCLot *lot)
CursorClass gnc_split_register_get_current_cursor_class(SplitRegister *reg)
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
const GncGUID * guid_null(void)
GtkWidget *(* create_widget)(GncPluginPage *plugin_page)
void qof_event_resume(void)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:196
void gnc_main_window_close_page(GncPluginPage *page)
Transaction * xaccTransGetReversedBy(const Transaction *trans)
Definition: Transaction.c:2606
Split * xaccSplitGetOtherSplit(const Split *split)
Definition: Split.c:2086
#define LEAVE(format, args...)
Definition: qoflog.h:271
void(* save_page)(GncPluginPage *page, GKeyFile *file, const gchar *group)
Split * gnc_split_register_duplicate_current(SplitRegister *reg)
void gnc_plugin_page_set_page_name(GncPluginPage *page, const char *name)
time64 gnc_time(time64 *tbuf)
get the current local time
Account * gnc_plugin_page_register_get_account(GncPluginPageRegister *page)
void gnc_plugin_page_add_book(GncPluginPage *page, QofBook *book)
gint64 time64
Definition: gnc-date.h:83
GtkActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
void gnc_plugin_page_register_sort_order_save_cb(GtkToggleButton *button, GncPluginPageRegister *page)
void gnc_plugin_page_register_sort_response_cb(GtkDialog *dialog, gint response, GncPluginPageRegister *plugin_page)
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Definition: Transaction.c:1951
const char * xaccAccountGetName(const Account *acc)
Definition: Account.c:3031
const char * xaccAccountGetSortOrder(const Account *acc)
Definition: Account.c:3114
void gnc_plugin_set_important_actions(GtkActionGroup *action_group, const gchar **name)
Definition: gnc-plugin.c:289
void gnc_split_register_cut_current(SplitRegister *reg)
SplitRegisterStyle
GNCSplitReg * gnc_plugin_page_register_get_gsr(GncPluginPage *plugin_page)
void gnc_plugin_page_register_sort_order_reverse_cb(GtkToggleButton *button, GncPluginPageRegister *page)
void main_window_update_page_name(GncPluginPage *page, const gchar *name_in)
void gnc_plugin_page_register_set_options(GncPluginPage *plugin_page, gint lines_default, gboolean read_only)
GtkWidget * summarybar
void gnc_split_register_cancel_cursor_trans_changes(SplitRegister *reg)
GNCLot * xaccSplitGetLot(const Split *split)
Definition: Split.c:1953
GList * qof_query_get_books(QofQuery *q)
const gchar * QofLogModule
Definition: qofid.h:89
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Definition: gnc-prefs.c:148
void gnc_split_register_config(SplitRegister *reg, SplitRegisterType newtype, SplitRegisterStyle newstyle, gboolean use_double_line)