GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-plugin-page-register2.c
1 /**********************************************************************
2  * gnc-plugin-page-register2.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 
44 #include "gnc-plugin-page-register2.h"
45 /*################## Added for Reg2 #################*/
47 /*################## Added for Reg2 #################*/
48 #include "gnc-plugin-register2.h"
50 #include "gnc-plugin-page-report.h"
51 
52 #include "gnc-tree-view.h"
53 #include "gnc-tree-view-split-reg.h"
54 #include "gnc-tree-model-split-reg.h"
55 #include "gnc-tree-control-split-reg.h"
56 
57 #include "dialog-account.h"
58 #include "dialog-find-transactions2.h"
59 #include "dialog-print-check2.h"
60 #include "dialog-transfer.h"
61 #include "dialog-utils.h"
62 #include "SX-book.h"
63 #include "dialog-sx-editor.h"
64 /*################## Added for Reg2 #################*/
65 #include "dialog-sx-editor2.h"
66 /*################## Added for Reg2 #################*/
67 #include "dialog-sx-from-trans.h"
68 #include "assistant-stock-split.h"
69 #include "gnc-component-manager.h"
70 #include "gnc-date.h"
71 #include "gnc-date-edit.h"
72 #include "gnc-engine.h"
73 #include "gnc-event.h"
74 #include "gnc-gnome-utils.h"
75 #include "gnc-gobject-utils.h"
76 #include "gnc-gui-query.h"
77 #include "gnc-icons.h"
78 #include "gnc-prefs.h"
79 #include "gnc-split-reg2.h"
80 #include "gnc-ui-util.h"
81 #include "gnc-window.h"
82 #include "gnc-main-window.h"
83 #include "gnc-session.h"
84 #include "gnome-utils/gnc-warnings.h"
85 #include "dialog-lot-viewer.h"
86 #include "Scrub.h"
87 #include "qof.h"
88 #include "window-reconcile2.h"
89 #include "window-autoclear.h"
90 #include "window-report.h"
91 
92 /* This static indicates the debugging module that this .o belongs to. */
93 static QofLogModule log_module = GNC_MOD_GUI;
94 
95 #define DEFAULT_LINES_AMOUNT 50
96 
97 static void gnc_plugin_page_register2_class_init (GncPluginPageRegister2Class *klass);
98 static void gnc_plugin_page_register2_init (GncPluginPageRegister2 *plugin_page);
99 static void gnc_plugin_page_register2_finalize (GObject *object);
100 
101 static GtkWidget *gnc_plugin_page_register2_create_widget (GncPluginPage *plugin_page);
102 static void gnc_plugin_page_register2_destroy_widget (GncPluginPage *plugin_page);
103 static void gnc_plugin_page_register2_window_changed (GncPluginPage *plugin_page, GtkWidget *window);
104 static void gnc_plugin_page_register2_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
105 static GncPluginPage *gnc_plugin_page_register2_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
106 static void gnc_plugin_page_register2_update_edit_menu (GncPluginPage *page, gboolean hide);
107 static gboolean gnc_plugin_page_register2_finish_pending (GncPluginPage *page);
108 
109 static gboolean gnc_plugin_page_register2_button_press_cb (GtkWidget *widget, GdkEventButton *event, GncPluginPage *page);
110 
111 static gchar *gnc_plugin_page_register2_get_tab_name (GncPluginPage *plugin_page);
112 static gchar *gnc_plugin_page_register2_get_tab_color (GncPluginPage *plugin_page);
113 static gchar *gnc_plugin_page_register2_get_long_name (GncPluginPage *plugin_page);
114 
115 static void gnc_plugin_page_register2_summarybar_position_changed (gpointer prefs, gchar* pref, gpointer user_data);
116 
117 /* Callbacks for the "Filter By" dialog */
121 void gnc_plugin_page_register2_filter_response_cb (GtkDialog *dialog, gint response, GncPluginPageRegister2 *plugin_page);
122 void gnc_plugin_page_register2_filter_status_all_cb (GtkButton *button, GncPluginPageRegister2 *plugin_page);
123 void gnc_plugin_page_register2_filter_status_one_cb (GtkToggleButton *button, GncPluginPageRegister2 *page);
124 void gnc_plugin_page_register2_filter_save_cb (GtkToggleButton *button, GncPluginPageRegister2 *page);
125 
126 static time64 gnc_plugin_page_register2_filter_dmy2time (char *date_string);
127 static gchar *gnc_plugin_page_register2_filter_time2dmy (time64 raw_time);
128 static gchar *gnc_plugin_page_register2_get_filter (GncPluginPage *plugin_page);
129 void gnc_plugin_page_register2_set_filter (GncPluginPage *plugin_page, const gchar *filter);
130 
131 static void gnc_ppr_update_status_query (GncPluginPageRegister2 *page, gboolean refresh_page);
132 static void gnc_ppr_update_date_query (GncPluginPageRegister2 *page, gboolean refresh_page);
133 
134 /* Command callbacks */
135 static void gnc_plugin_page_register2_cmd_print_check (GtkAction *action, GncPluginPageRegister2 *plugin_page);
136 static void gnc_plugin_page_register2_cmd_cut (GtkAction *action, GncPluginPageRegister2 *plugin_page);
137 static void gnc_plugin_page_register2_cmd_copy (GtkAction *action, GncPluginPageRegister2 *plugin_page);
138 static void gnc_plugin_page_register2_cmd_paste (GtkAction *action, GncPluginPageRegister2 *plugin_page);
139 static void gnc_plugin_page_register2_cmd_edit_account (GtkAction *action, GncPluginPageRegister2 *plugin_page);
140 static void gnc_plugin_page_register2_cmd_find_transactions (GtkAction *action, GncPluginPageRegister2 *plugin_page);
141 static void gnc_plugin_page_register2_cmd_cut_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
142 static void gnc_plugin_page_register2_cmd_copy_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
143 static void gnc_plugin_page_register2_cmd_paste_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
144 static void gnc_plugin_page_register2_cmd_void_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
145 static void gnc_plugin_page_register2_cmd_unvoid_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
146 static void gnc_plugin_page_register2_cmd_reverse_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
147 static void gnc_plugin_page_register2_cmd_reload (GtkAction *action, GncPluginPageRegister2 *plugin_page);
148 static void gnc_plugin_page_register2_cmd_view_filter_by (GtkAction *action, GncPluginPageRegister2 *plugin_page);
149 static void gnc_plugin_page_register2_cmd_style_changed (GtkAction *action, GtkRadioAction *current, GncPluginPageRegister2 *plugin_page);
150 static void gnc_plugin_page_register2_cmd_style_double_line (GtkToggleAction *action, GncPluginPageRegister2 *plugin_page);
151 static void gnc_plugin_page_register2_cmd_style_extra_dates (GtkToggleAction *action, GncPluginPageRegister2 *plugin_page);
152 
153 static void gnc_plugin_page_register2_cmd_reconcile (GtkAction *action, GncPluginPageRegister2 *plugin_page);
154 static void gnc_plugin_page_register2_cmd_autoclear (GtkAction *action, GncPluginPageRegister2 *plugin_page);
155 static void gnc_plugin_page_register2_cmd_transfer (GtkAction *action, GncPluginPageRegister2 *plugin_page);
156 static void gnc_plugin_page_register2_cmd_stock_split (GtkAction *action, GncPluginPageRegister2 *plugin_page);
157 static void gnc_plugin_page_register2_cmd_lots (GtkAction *action, GncPluginPageRegister2 *plugin_page);
158 static void gnc_plugin_page_register2_cmd_enter_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
159 static void gnc_plugin_page_register2_cmd_cancel_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
160 static void gnc_plugin_page_register2_cmd_delete_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
161 static void gnc_plugin_page_register2_cmd_blank_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
162 static void gnc_plugin_page_register2_cmd_duplicate_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
163 static void gnc_plugin_page_register2_cmd_reinitialize_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
164 static void gnc_plugin_page_register2_cmd_expand_transaction (GtkToggleAction *action, GncPluginPageRegister2 *plugin_page);
165 static void gnc_plugin_page_register2_cmd_exchange_rate (GtkAction *action, GncPluginPageRegister2 *plugin_page);
166 static void gnc_plugin_page_register2_cmd_jump (GtkAction *action, GncPluginPageRegister2 *plugin_page);
167 static void gnc_plugin_page_register2_cmd_schedule (GtkAction *action, GncPluginPageRegister2 *plugin_page);
168 static void gnc_plugin_page_register2_cmd_scrub_all (GtkAction *action, GncPluginPageRegister2 *plugin_page);
169 static void gnc_plugin_page_register2_cmd_scrub_current (GtkAction *action, GncPluginPageRegister2 *plugin_page);
170 static void gnc_plugin_page_register2_cmd_account_report (GtkAction *action, GncPluginPageRegister2 *plugin_page);
171 static void gnc_plugin_page_register2_cmd_transaction_report (GtkAction *action, GncPluginPageRegister2 *plugin_page);
172 static void gnc_plugin_page_register2_cmd_entryUp (GtkAction *action, GncPluginPageRegister2 *plugin_page);
173 static void gnc_plugin_page_register2_cmd_entryDown (GtkAction *action, GncPluginPageRegister2 *plugin_page);
174 
175 static void gnc_plugin_page_help_changed_cb (GNCSplitReg2 *gsr, GncPluginPageRegister2 *register_page );
176 static void gnc_plugin_page_register2_refresh_cb (GHashTable *changes, gpointer user_data);
177 static void gnc_plugin_page_register2_close_cb (gpointer user_data);
178 
179 static void gnc_plugin_page_register2_ui_update (gpointer various, GncPluginPageRegister2 *page);
180 static void gppr_account_destroy_cb (Account *account);
181 static void gnc_plugin_page_register2_event_handler (QofInstance *entity,
182  QofEventId event_type,
184  GncEventData *ed);
185 
186 /************************************************************/
187 /* Actions */
188 /************************************************************/
189 
190 #define CUT_TRANSACTION_LABEL N_("Cu_t Transaction")
191 #define COPY_TRANSACTION_LABEL N_("_Copy Transaction")
192 #define PASTE_TRANSACTION_LABEL N_("_Paste Transaction")
193 #define DUPLICATE_TRANSACTION_LABEL N_("Dup_licate Transaction")
194 #define DELETE_TRANSACTION_LABEL N_("_Delete Transaction")
195 #define CUT_SPLIT_LABEL N_("Cu_t Split")
196 #define COPY_SPLIT_LABEL N_("_Copy Split")
197 #define PASTE_SPLIT_LABEL N_("_Paste Split")
198 #define DUPLICATE_SPLIT_LABEL N_("Dup_licate Split")
199 #define DELETE_SPLIT_LABEL N_("_Delete Split")
200 #define CUT_TRANSACTION_TIP N_("Cut the selected transaction into clipboard")
201 #define COPY_TRANSACTION_TIP N_("Copy the selected transaction into clipboard")
202 #define PASTE_TRANSACTION_TIP N_("Paste the transaction from the clipboard")
203 #define DUPLICATE_TRANSACTION_TIP N_("Make a copy of the current transaction")
204 #define DELETE_TRANSACTION_TIP N_("Delete the current transaction")
205 #define CUT_SPLIT_TIP N_("Cut the selected split into clipboard")
206 #define COPY_SPLIT_TIP N_("Copy the selected split into clipboard")
207 #define PASTE_SPLIT_TIP N_("Paste the split from the clipboard")
208 #define DUPLICATE_SPLIT_TIP N_("Make a copy of the current split")
209 #define DELETE_SPLIT_TIP N_("Delete the current split")
210 
211 #define TRANSACTION_UP_ACTION "TransactionUpAction"
212 #define TRANSACTION_DOWN_ACTION "TransactionDownAction"
213 
214 static GtkActionEntry gnc_plugin_page_register2_actions [] =
215 {
216  /* File menu */
217 
218  {
219  "FilePrintAction", GTK_STOCK_PRINT, N_("_Print Checks..."), "<control>p", NULL,
220  G_CALLBACK (gnc_plugin_page_register2_cmd_print_check)
221  },
222 
223  /* Edit menu */
224 
225  {
226  "EditCutAction", GTK_STOCK_CUT, N_("Cu_t"), NULL,
227  N_("Cut the current selection and copy it to clipboard"),
228  G_CALLBACK (gnc_plugin_page_register2_cmd_cut)
229  },
230  {
231  "EditCopyAction", GTK_STOCK_COPY, N_("_Copy"), NULL,
232  N_("Copy the current selection to clipboard"),
233  G_CALLBACK (gnc_plugin_page_register2_cmd_copy)
234  },
235  {
236  "EditPasteAction", GTK_STOCK_PASTE, N_("_Paste"), NULL,
237  N_("Paste the clipboard content at the cursor position"),
238  G_CALLBACK (gnc_plugin_page_register2_cmd_paste)
239  },
240  {
241  "EditEditAccountAction", GNC_STOCK_EDIT_ACCOUNT, N_("Edit _Account"), "<control>e",
242  N_("Edit the selected account"),
243  G_CALLBACK (gnc_plugin_page_register2_cmd_edit_account)
244  },
245  {
246  "EditFindTransactionsAction", GTK_STOCK_FIND, N_("_Find..."), "<control>f",
247  N_("Find transactions with a search"),
248  G_CALLBACK (gnc_plugin_page_register2_cmd_find_transactions)
249  },
250 
251  /* Transaction menu */
252 
253  {
254  "CutTransactionAction", GTK_STOCK_CUT, CUT_TRANSACTION_LABEL, "",
255  CUT_TRANSACTION_TIP,
256  G_CALLBACK (gnc_plugin_page_register2_cmd_cut_transaction)
257  },
258  {
259  "CopyTransactionAction", GTK_STOCK_COPY, COPY_TRANSACTION_LABEL, "",
260  COPY_TRANSACTION_TIP,
261  G_CALLBACK (gnc_plugin_page_register2_cmd_copy_transaction)
262  },
263  {
264  "PasteTransactionAction", GTK_STOCK_PASTE, PASTE_TRANSACTION_LABEL, "",
265  PASTE_TRANSACTION_TIP,
266  G_CALLBACK (gnc_plugin_page_register2_cmd_paste_transaction)
267  },
268  {
269  "DuplicateTransactionAction", GTK_STOCK_COPY, DUPLICATE_TRANSACTION_LABEL, "",
270  DUPLICATE_TRANSACTION_TIP,
271  G_CALLBACK (gnc_plugin_page_register2_cmd_duplicate_transaction)
272  },
273  {
274  "DeleteTransactionAction", GTK_STOCK_DELETE, DELETE_TRANSACTION_LABEL, NULL,
275  DELETE_TRANSACTION_TIP,
276  G_CALLBACK (gnc_plugin_page_register2_cmd_delete_transaction)
277  },
278  {
279  "RemoveTransactionSplitsAction", GTK_STOCK_CLEAR, N_("Remo_ve All Splits"), NULL,
280  N_("Remove all splits in the current transaction"),
281  G_CALLBACK (gnc_plugin_page_register2_cmd_reinitialize_transaction)
282  },
283  {
284  "RecordTransactionAction", GTK_STOCK_ADD, N_("_Enter Transaction"), NULL,
285  N_("Record the current transaction"),
286  G_CALLBACK (gnc_plugin_page_register2_cmd_enter_transaction)
287  },
288  {
289  "CancelTransactionAction", GTK_STOCK_CANCEL, N_("Ca_ncel Transaction"), NULL,
290  N_("Cancel the current transaction"),
291  G_CALLBACK (gnc_plugin_page_register2_cmd_cancel_transaction)
292  },
293  {
294  "VoidTransactionAction", NULL, N_("_Void Transaction"), NULL, NULL,
295  G_CALLBACK (gnc_plugin_page_register2_cmd_void_transaction)
296  },
297  {
298  "UnvoidTransactionAction", NULL, N_("_Unvoid Transaction"), NULL, NULL,
299  G_CALLBACK (gnc_plugin_page_register2_cmd_unvoid_transaction)
300  },
301  {
302  "ReverseTransactionAction", NULL, N_("Add _Reversing Transaction"), NULL, NULL,
303  G_CALLBACK (gnc_plugin_page_register2_cmd_reverse_transaction)
304  },
305  {
306  TRANSACTION_UP_ACTION, GTK_STOCK_GO_UP, N_("Move Transaction _Up"), NULL,
307  N_("Move the current transaction one row upwards. Only available if the date and number of both rows are identical and the register window is sorted by date."),
308  G_CALLBACK (gnc_plugin_page_register2_cmd_entryUp)
309  },
310  {
311  TRANSACTION_DOWN_ACTION, GTK_STOCK_GO_DOWN, N_("Move Transaction Do_wn"), NULL,
312  N_("Move the current transaction one row downwards. Only available if the date and number of both rows are identical and the register window is sorted by date."),
313  G_CALLBACK (gnc_plugin_page_register2_cmd_entryDown)
314  },
315 
316  /* View menu */
317 
318  {
319  "ViewFilterByAction", NULL, N_("_Filter By..."), NULL, NULL,
320  G_CALLBACK (gnc_plugin_page_register2_cmd_view_filter_by)
321  },
322  {
323  "ViewRefreshAction", GTK_STOCK_REFRESH, N_("_Refresh"), "<control>r",
324  N_("Refresh this window"),
325  G_CALLBACK (gnc_plugin_page_register2_cmd_reload)
326  },
327 
328  /* Actions menu */
329 
330  {
331  "ActionsTransferAction", GNC_STOCK_TRANSFER, N_("_Transfer..."), "<control>t",
332  N_("Transfer funds from one account to another"),
333  G_CALLBACK (gnc_plugin_page_register2_cmd_transfer)
334  },
335  {
336  "ActionsReconcileAction", GTK_STOCK_INDEX, N_("_Reconcile..."), NULL,
337  N_("Reconcile the selected account"),
338  G_CALLBACK (gnc_plugin_page_register2_cmd_reconcile)
339  },
340  {
341  "ActionsAutoClearAction", GTK_STOCK_INDEX, N_("_Auto-clear..."), NULL,
342  N_("Automatically clear individual transactions, so as to reach a certain cleared amount"),
343  G_CALLBACK (gnc_plugin_page_register2_cmd_autoclear)
344  },
345  {
346  "ActionsStockSplitAction", NULL, N_("Stoc_k Split..."), NULL,
347  N_("Record a stock split or a stock merger"),
348  G_CALLBACK (gnc_plugin_page_register2_cmd_stock_split)
349  },
350  {
351  "ActionsLotsAction", NULL, N_("View _Lots..."), NULL,
352  N_("Bring up the lot viewer/editor window"),
353  G_CALLBACK (gnc_plugin_page_register2_cmd_lots)
354  },
355  {
356  "BlankTransactionAction", GTK_STOCK_GOTO_BOTTOM, N_("_Blank Transaction"), "<control>Page_Down",
357  N_("Move to the blank transaction at the bottom of the register"),
358  G_CALLBACK (gnc_plugin_page_register2_cmd_blank_transaction)
359  },
360  {
361  "EditExchangeRateAction", NULL, N_("Edit E_xchange Rate"), NULL,
362  N_("Edit the exchange rate for the current transaction"),
363  G_CALLBACK (gnc_plugin_page_register2_cmd_exchange_rate)
364  },
365  {
366  "JumpTransactionAction", GNC_STOCK_JUMP_TO, N_("_Jump"), NULL,
367  N_("Jump to the corresponding transaction in the other account"),
368  G_CALLBACK (gnc_plugin_page_register2_cmd_jump)
369  },
370  {
371  "ScheduleTransactionAction", GNC_STOCK_SCHEDULE, N_("Sche_dule..."), NULL,
372  N_("Create a Scheduled Transaction with the current transaction as a template"),
373  G_CALLBACK (gnc_plugin_page_register2_cmd_schedule)
374  },
375  {
376  "ScrubAllAction", NULL, N_("_All transactions"), NULL, NULL,
377  G_CALLBACK (gnc_plugin_page_register2_cmd_scrub_all)
378  },
379  {
380  "ScrubCurrentAction", NULL, N_("_This transaction"), NULL, NULL,
381  G_CALLBACK (gnc_plugin_page_register2_cmd_scrub_current)
382  },
383 
384  /* Reports menu */
385 
386  {
387  "ReportsAccountReportAction", NULL, N_("Account Report"), NULL,
388  N_("Open a register report for this Account"),
389  G_CALLBACK (gnc_plugin_page_register2_cmd_account_report)
390  },
391  {
392  "ReportsAcctTransReportAction", NULL, N_("Account Report - Single Transaction"), NULL,
393  N_("Open a register report for the selected Transaction"),
394  G_CALLBACK (gnc_plugin_page_register2_cmd_transaction_report)
395  },
396 };
397 
398 static guint gnc_plugin_page_register2_n_actions = G_N_ELEMENTS (gnc_plugin_page_register2_actions);
399 
400 static GtkToggleActionEntry toggle_entries[] =
401 {
402  {
403  "ViewStyleDoubleLineAction", NULL, N_("_Double Line"), NULL,
404  N_("Show two lines of information for each transaction"),
405  G_CALLBACK (gnc_plugin_page_register2_cmd_style_double_line), FALSE
406  },
407 
408  {
409  "ViewStyleExtraDatesAction", NULL, N_("Show _Extra Dates"), NULL,
410  N_("Show entered and reconciled dates"),
411  G_CALLBACK (gnc_plugin_page_register2_cmd_style_extra_dates), FALSE
412  },
413 
414  {
415  "SplitTransactionAction", GNC_STOCK_SPLIT_TRANS, N_("S_plit Transaction"), NULL,
416  N_("Show all splits in the current transaction"),
417  G_CALLBACK (gnc_plugin_page_register2_cmd_expand_transaction), FALSE
418  },
419 };
420 
421 static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
422 
423 static GtkRadioActionEntry radio_entries_2 [] =
424 {
425  /* Translators: This is a menu item in the View menu */
426  {
427  "ViewStyleBasicAction", NULL, N_("_Basic Ledger"), NULL,
428  N_("Show transactions on one or two lines"), REG2_STYLE_LEDGER
429  },
430  /* Translators: This is a menu item in the View menu */
431  {
432  "ViewStyleAutoSplitAction", NULL, N_("_Auto-Split Ledger"), NULL,
433  N_("Show transactions on one or two lines and expand the current transaction"), REG2_STYLE_AUTO_LEDGER
434  },
435  /* Translators: This is a menu item in the View menu */
436  {
437  "ViewStyleJournalAction", NULL, N_("Transaction _Journal"), NULL,
438  N_("Show expanded transactions with all splits"), REG2_STYLE_JOURNAL
439  }
440 };
441 
442 static guint n_radio_entries_2 = G_N_ELEMENTS (radio_entries_2);
443 
447 static const gchar *important_actions[] =
448 {
449  "SplitTransactionAction",
450  NULL,
451 };
452 
455 static const gchar *actions_requiring_account[] =
456 {
457  "EditEditAccountAction",
458  "ActionsReconcileAction",
459  "ActionsAutoClearAction",
460  "ActionsLotsAction",
461  NULL
462 };
463 
465 static const gchar *view_style_actions[] =
466 {
467  "ViewStyleBasicAction",
468  "ViewStyleAutoSplitAction",
469  "ViewStyleJournalAction",
470  NULL
471 };
472 
474 static action_toolbar_labels toolbar_labels[] =
475 {
476  { "ActionsTransferAction", N_("Transfer") },
477  { "RecordTransactionAction", N_("Enter") },
478  { "CancelTransactionAction", N_("Cancel") },
479  { "DeleteTransactionAction", N_("Delete") },
480  { "DuplicateTransactionAction", N_("Duplicate") },
481  { "SplitTransactionAction", N_("Split") },
482  { "ScheduleTransactionAction", N_("Schedule") },
483  { "BlankTransactionAction", N_("Blank") },
484  { "ActionsReconcileAction", N_("Reconcile") },
485  { "ActionsAutoClearAction", N_("Auto-clear") },
486  { TRANSACTION_UP_ACTION, N_("Up") },
487  { TRANSACTION_DOWN_ACTION, N_("Down") },
488  { NULL, NULL },
489 };
490 
491 struct status_action
492 {
493  const char *action_name;
494  int value;
495  GtkWidget *widget;
496 };
497 
498 static struct status_action status_actions[] =
499 {
500  { "filter_status_reconciled", CLEARED_RECONCILED, NULL },
501  { "filter_status_cleared", CLEARED_CLEARED, NULL },
502  { "filter_status_voided", CLEARED_VOIDED, NULL },
503  { "filter_status_frozen", CLEARED_FROZEN, NULL },
504  { "filter_status_unreconciled", CLEARED_NO, NULL },
505  { NULL, 0, NULL },
506 };
507 
508 #define CLEARED_VALUE "cleared_value"
509 #define DEFAULT_FILTER "0x001f"
510 
511 /************************************************************/
512 /* Data Structures */
513 /************************************************************/
514 
516 {
517  GtkWidget *widget;
518 
519  GNCLedgerDisplay2 *ledger;
520  GNCSplitReg2 *gsr;
521 
522  gint event_handler_id;
523  gint component_manager_id;
524  GncGUID key; /* The guid of the Account we're watching */
525 
526  gint lines_default;
527  gboolean read_only;
528 
529  struct
530  {
531  GtkWidget *dialog;
532  GtkWidget *table;
533  GtkWidget *start_date_choose;
534  GtkWidget *start_date_today;
535  GtkWidget *start_date;
536  GtkWidget *end_date_choose;
537  GtkWidget *end_date_today;
538  GtkWidget *end_date;
539  cleared_match_t original_cleared_match;
540  cleared_match_t cleared_match;
541  time64 original_start_time;
542  time64 original_end_time;
543  time64 start_time;
544  time64 end_time;
545  gboolean original_save_filter;
546  gboolean save_filter;
547  } fd;
549 
550 #define GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(o) \
551  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_PAGE_REGISTER2, GncPluginPageRegister2Private))
552 
553 static GObjectClass *parent_class = NULL;
554 
555 /************************************************************/
556 /* Implementation */
557 /************************************************************/
558 
559 GType
561 {
562  static GType gnc_plugin_page_register2_type = 0;
563 
564  if (gnc_plugin_page_register2_type == 0)
565  {
566  static const GTypeInfo our_info =
567  {
569  NULL,
570  NULL,
571  (GClassInitFunc) gnc_plugin_page_register2_class_init,
572  NULL,
573  NULL,
574  sizeof (GncPluginPageRegister2),
575  0,
576  (GInstanceInitFunc) gnc_plugin_page_register2_init
577  };
578 
579  gnc_plugin_page_register2_type = g_type_register_static (GNC_TYPE_PLUGIN_PAGE,
580  GNC_PLUGIN_PAGE_REGISTER2_NAME,
581  &our_info, 0);
582  }
583 
584  return gnc_plugin_page_register2_type;
585 }
586 
587 /*#################################################################################*/
588 /*#################################################################################*/
589 static GncPluginPage *
590 gnc_plugin_page_register2_new_common (GNCLedgerDisplay2 *ledger)
591 {
592  GncPluginPageRegister2 *register_page;
594  GncPluginPage *plugin_page;
595 
596  GncTreeModelSplitReg *model;
597  GtkTreeView *tv;
598 
599  GNCSplitReg2 *gsr;
600 
601  const GList *item;
602  GList *book_list;
603  gchar *label;
604  gchar *label_color;
605  QofQuery *q;
606  Account *account;
607 
608  /* Is there an existing page? */
609  gsr = gnc_ledger_display2_get_user_data (ledger);
610  if (gsr)
611  {
612  item = gnc_gobject_tracking_get_list (GNC_PLUGIN_PAGE_REGISTER2_NAME);
613  for ( ; item; item = g_list_next (item))
614  {
615  register_page = (GncPluginPageRegister2 *)item->data;
616  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (register_page);
617  if (priv->gsr == gsr)
618  return GNC_PLUGIN_PAGE (register_page);
619  }
620  }
621 
622  register_page = g_object_new (GNC_TYPE_PLUGIN_PAGE_REGISTER2, NULL);
623  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (register_page);
624  priv->ledger = ledger;
625  priv->key = *guid_null();
626 
627  plugin_page = GNC_PLUGIN_PAGE (register_page);
628  label = gnc_plugin_page_register2_get_tab_name (plugin_page);
629  gnc_plugin_page_set_page_name (plugin_page, label);
630  g_free (label);
631 
632  label_color = gnc_plugin_page_register2_get_tab_color (plugin_page);
633  gnc_plugin_page_set_page_color (plugin_page, label_color);
634  g_free (label_color);
635 
636  label = gnc_plugin_page_register2_get_long_name (plugin_page);
637  gnc_plugin_page_set_page_long_name (plugin_page, label);
638  g_free (label);
639 
640  q = gnc_ledger_display2_get_query (ledger);
641  book_list = qof_query_get_books (q);
642  for (item = book_list; item; item = g_list_next (item))
643  gnc_plugin_page_add_book (plugin_page, (QofBook *)item->data);
644  // Do not free the list. It is owned by the query.
645 
646  priv->component_manager_id = 0;
647  return plugin_page;
648 }
649 
650 /*#################################################################################*/
651 
653 gnc_plugin_page_register2_new (Account *account, gboolean subaccounts)
654 {
655  GNCLedgerDisplay2 *ledger;
656  GncPluginPage *page;
658 
659 /*################## Added for Reg2 #################*/
660  const GList *item;
661  GncPluginPageRegister *old_register_page;
662 /*################## Added for Reg2 #################*/
663 
664  ENTER("account=%p, subaccounts=%s", account,
665  subaccounts ? "TRUE" : "FALSE");
666 
667 /*################## Added for Reg2 #################*/
668  // We test for the old register being open here, ie matching account guids
669  item = gnc_gobject_tracking_get_list (GNC_PLUGIN_PAGE_REGISTER_NAME);
670  for ( ; item; item = g_list_next (item))
671  {
672  Account *old_account;
673  old_register_page = (GncPluginPageRegister *)item->data;
674  old_account = gnc_plugin_page_register_get_account (old_register_page);
675 
676  if (guid_equal (xaccAccountGetGUID (account), xaccAccountGetGUID (old_account)))
677  {
678  gnc_error_dialog (NULL, "%s",
679  _("You have tried to open an account in the new register while it is open in the old register."));
680  return NULL;
681  }
682  }
683 /*################## Added for Reg2 #################*/
684 
685  if (subaccounts)
686  ledger = gnc_ledger_display2_subaccounts (account);
687  else
688  ledger = gnc_ledger_display2_simple (account);
689 
690  page = gnc_plugin_page_register2_new_common (ledger);
691  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
692  priv->key = *xaccAccountGetGUID (account);
693 
694  LEAVE("%p", page);
695  return page;
696 }
697 
700 {
701  GNCLedgerDisplay2 *ledger;
702 
703  ledger = gnc_ledger_display2_gl ();
704  return gnc_plugin_page_register2_new_common (ledger);
705 }
706 
709 {
710  return gnc_plugin_page_register2_new_common (ledger);
711 }
712 
713 static void
714 gnc_plugin_page_register2_class_init (GncPluginPageRegister2Class *klass)
715 {
716  GObjectClass *object_class = G_OBJECT_CLASS (klass);
717  GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
718 
719  parent_class = g_type_class_peek_parent (klass);
720 
721  object_class->finalize = gnc_plugin_page_register2_finalize;
722 
723  gnc_plugin_class->tab_icon = GNC_STOCK_ACCOUNT;
724  gnc_plugin_class->plugin_name = GNC_PLUGIN_PAGE_REGISTER2_NAME;
725  gnc_plugin_class->create_widget = gnc_plugin_page_register2_create_widget;
726  gnc_plugin_class->destroy_widget = gnc_plugin_page_register2_destroy_widget;
727  gnc_plugin_class->window_changed = gnc_plugin_page_register2_window_changed;
728  gnc_plugin_class->save_page = gnc_plugin_page_register2_save_page;
729  gnc_plugin_class->recreate_page = gnc_plugin_page_register2_recreate_page;
730  gnc_plugin_class->update_edit_menu_actions = gnc_plugin_page_register2_update_edit_menu;
731  gnc_plugin_class->finish_pending = gnc_plugin_page_register2_finish_pending;
732 
733  g_type_class_add_private(klass, sizeof(GncPluginPageRegister2Private));
734 
735  gnc_ui_register_account_destroy_callback (gppr_account_destroy_cb);
736 }
737 
738 static void
739 gnc_plugin_page_register2_init (GncPluginPageRegister2 *plugin_page)
740 {
742  GncPluginPage *parent;
743  GtkActionGroup *action_group;
744  gboolean use_new;
745 
746  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
747 
748  /* Init parent declared variables */
749  parent = GNC_PLUGIN_PAGE(plugin_page);
750  use_new = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_USE_NEW);
751  g_object_set(G_OBJECT(plugin_page),
752  "page-name", _("General Ledger2"),
753  "page-uri", "default:",
754  "ui-description", "gnc-plugin-page-register2-ui.xml",
755  "use-new-window", use_new,
756  NULL);
757 
758  /* Create menu and toolbar information */
759  action_group =
761  "GncPluginPageRegister2Actions");
762  gtk_action_group_add_actions (action_group, gnc_plugin_page_register2_actions,
763  gnc_plugin_page_register2_n_actions, plugin_page);
764  gtk_action_group_add_toggle_actions (action_group,
765  toggle_entries, n_toggle_entries,
766  plugin_page);
767  gtk_action_group_add_radio_actions (action_group,
768  radio_entries_2, n_radio_entries_2,
769  REG2_STYLE_LEDGER,
770  G_CALLBACK(gnc_plugin_page_register2_cmd_style_changed),
771  plugin_page);
772 
773  gnc_plugin_init_short_names (action_group, toolbar_labels);
774  gnc_plugin_set_important_actions (action_group, important_actions);
775 
776  priv->lines_default = DEFAULT_LINES_AMOUNT;
777  priv->read_only = FALSE;
778  priv->fd.cleared_match = CLEARED_ALL;
779 }
780 
781 static void
782 gnc_plugin_page_register2_finalize (GObject *object)
783 {
786 
787  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (object));
788 
789  ENTER("object %p", object);
790  page = GNC_PLUGIN_PAGE_REGISTER2 (object);
791  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
792 
793  G_OBJECT_CLASS (parent_class)->finalize (object);
794  LEAVE(" ");
795 }
796 
797 Account *
799 {
801  GNCLedgerDisplay2Type ledger_type;
802  Account *leader;
803 
804  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
805  ledger_type = gnc_ledger_display2_type (priv->ledger);
806  leader = gnc_ledger_display2_leader (priv->ledger);
807 
808  if ((ledger_type == LD2_SINGLE) || (ledger_type == LD2_SUBACCOUNT))
809  return leader;
810  return NULL;
811 }
812 
813 /* This is the list of actions which are switched inactive in a read-only book. */
814 static const char* readonly_inactive_actions[] =
815 {
816  "EditCutAction",
817  "EditPasteAction",
818  "CutTransactionAction",
819  "PasteTransactionAction",
820  TRANSACTION_UP_ACTION,
821  TRANSACTION_DOWN_ACTION,
822  "DuplicateTransactionAction",
823  "DeleteTransactionAction",
824  "RemoveTransactionSplitsAction",
825  "RecordTransactionAction",
826  "CancelTransactionAction",
827  "UnvoidTransactionAction",
828  "VoidTransactionAction",
829  "ReverseTransactionAction",
830  "ActionsTransferAction",
831  "ActionsReconcileAction",
832  "ActionsStockSplitAction",
833  "ScheduleTransactionAction",
834  "ScrubAllAction",
835  "ScrubCurrentAction",
836  NULL
837 };
838 
839 /* This is the list of actions whose text needs to be changed based on whether */
840 /* the current cursor class is transaction or split. */
841 static const char* tran_vs_split_actions[] =
842 {
843  "CutTransactionAction",
844  "CopyTransactionAction",
845  "PasteTransactionAction",
846  "DuplicateTransactionAction",
847  "DeleteTransactionAction",
848  NULL
849 };
850 
851 /* This is the list of labels for when the current cursor class is transaction. */
852 static const char* tran_action_labels[] =
853 {
854  CUT_TRANSACTION_LABEL,
855  COPY_TRANSACTION_LABEL,
856  PASTE_TRANSACTION_LABEL,
857  DUPLICATE_TRANSACTION_LABEL,
858  DELETE_TRANSACTION_LABEL,
859  NULL
860 };
861 
862 /* This is the list of tooltips for when the current cursor class is transaction. */
863 static const char* tran_action_tips[] =
864 {
865  CUT_TRANSACTION_TIP,
866  COPY_TRANSACTION_TIP,
867  PASTE_TRANSACTION_TIP,
868  DUPLICATE_TRANSACTION_TIP,
869  DELETE_TRANSACTION_TIP,
870  NULL
871 };
872 
873 /* This is the list of labels for when the current cursor class is split. */
874 static const char* split_action_labels[] =
875 {
876  CUT_SPLIT_LABEL,
877  COPY_SPLIT_LABEL,
878  PASTE_SPLIT_LABEL,
879  DUPLICATE_SPLIT_LABEL,
880  DELETE_SPLIT_LABEL,
881  NULL
882 };
883 
884 /* This is the list of tooltips for when the current cursor class is split. */
885 static const char* split_action_tips[] =
886 {
887  CUT_SPLIT_TIP,
888  COPY_SPLIT_TIP,
889  PASTE_SPLIT_TIP,
890  DUPLICATE_SPLIT_TIP,
891  DELETE_SPLIT_TIP,
892  NULL
893 };
894 
895 static void
896 gnc_plugin_page_register2_ui_update (gpointer various, GncPluginPageRegister2 *page) // this works
897 {
899  GncTreeViewSplitReg *view;
900  GncTreeModelSplitReg *model;
901  GtkAction *action;
902  gboolean expanded, voided;
903  Transaction *trans;
904 
905  /* Set 'Split Transaction' */
906  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
907  g_return_if_fail(priv);
908  model = gnc_ledger_display2_get_split_model_register (priv->ledger);
909  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
910  g_return_if_fail(model);
911  g_return_if_fail(view);
912 
913  expanded = gnc_tree_view_split_reg_trans_expanded (view, NULL);
914  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page),
915  "SplitTransactionAction");
916  gtk_action_set_sensitive (action, model->style == REG2_STYLE_LEDGER);
917  g_signal_handlers_block_by_func
918  (action, gnc_plugin_page_register2_cmd_expand_transaction, page);
919  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), expanded);
920  g_signal_handlers_unblock_by_func
921  (action, gnc_plugin_page_register2_cmd_expand_transaction, page);
922 
923  /* Set 'Void' and 'Unvoid' */
924  trans = gnc_tree_view_split_reg_get_current_trans (view);
925  voided = xaccTransHasSplitsInState (trans, VREC);
926 
927  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page),
928  "VoidTransactionAction");
929  gtk_action_set_sensitive (GTK_ACTION (action), !voided);
930 
931  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page),
932  "UnvoidTransactionAction");
933  gtk_action_set_sensitive (GTK_ACTION (action), voided);
934 
935  /* Modify the activeness of the up/down arrows */
936  {
937  GtkAction *action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page), TRANSACTION_UP_ACTION);
938  gtk_action_set_sensitive(action,
939  gnc_tree_control_split_reg_is_current_movable_updown(view, TRUE));
940  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page), TRANSACTION_DOWN_ACTION);
941  gtk_action_set_sensitive(action,
942  gnc_tree_control_split_reg_is_current_movable_updown(view, FALSE));
943  }
944 
945  /* If we are in a readonly book, make any modifying action inactive */
946  if (qof_book_is_readonly(gnc_get_current_book ()))
947  {
948  const char **iter;
949  for (iter = readonly_inactive_actions; *iter; ++iter)
950  {
951  /* Set the action's sensitivity */
952  GtkAction *action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page), *iter);
953  gtk_action_set_sensitive (action, FALSE);
954  }
955  }
956 
957  /* Modifying action descriptions based on row depth */
958  {
959  RowDepth depth;
960  const char **iter, **label_iter, **tooltip_iter;
961  gboolean curr_label_trans = FALSE;
962  depth = gnc_tree_view_reg_get_selected_row_depth (view);
963  iter = tran_vs_split_actions;
964  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page), *iter);
965  label_iter = tran_action_labels;
966  if (g_strcmp0 (gtk_action_get_label (action), _(*label_iter)) == 0)
967  curr_label_trans = TRUE;
968  if ((depth == SPLIT3) && curr_label_trans)
969  {
970  label_iter = split_action_labels;
971  tooltip_iter = split_action_tips;
972  for (iter = tran_vs_split_actions; *iter; ++iter)
973  {
974  /* Adjust the action's label and tooltip */
975  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page), *iter);
976  gtk_action_set_label (action, _(*label_iter));
977  gtk_action_set_tooltip (action, _(*tooltip_iter));
978  ++label_iter;
979  ++tooltip_iter;
980  }
981  }
982  else if ((depth == TRANS1 || depth == TRANS2) && !curr_label_trans)
983  {
984  label_iter = tran_action_labels;
985  tooltip_iter = tran_action_tips;
986  for (iter = tran_vs_split_actions; *iter; ++iter)
987  {
988  /* Adjust the action's label and tooltip */
989  action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE (page), *iter);
990  gtk_action_set_label (action, _(*label_iter));
991  gtk_action_set_tooltip (action, _(*tooltip_iter));
992  ++label_iter;
993  ++tooltip_iter;
994  }
995  }
996  }
997 }
998 
999 static void
1000 gnc_plugin_page_register2_ui_initial_state (GncPluginPageRegister2 *page) // this works
1001 {
1003  GtkActionGroup *action_group;
1004  GtkAction *action;
1005  Account *account;
1006  GncTreeViewSplitReg *view;
1007  GncTreeModelSplitReg *model;
1008  GNCLedgerDisplay2Type ledger_type;
1009  int i;
1010  gboolean is_readwrite = !qof_book_is_readonly (gnc_get_current_book());
1011 
1012  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
1013  account = gnc_plugin_page_register2_get_account (page);
1014  action_group = gnc_plugin_page_get_action_group (GNC_PLUGIN_PAGE (page));
1015  gnc_plugin_update_actions(action_group, actions_requiring_account,
1016  "sensitive", is_readwrite && account != NULL);
1017 
1018  /* Set "style" radio button */
1019  ledger_type = gnc_ledger_display2_type (priv->ledger);
1020  gnc_plugin_update_actions (action_group, view_style_actions,
1021  "sensitive", ledger_type == LD2_SINGLE);
1022 
1023  model = gnc_ledger_display2_get_split_model_register (priv->ledger);
1024  for (i = n_radio_entries_2 - 1; i > 0; i--)
1025  {
1026  DEBUG(" index %d: comparing %x to %x", i, radio_entries_2[i].value,
1027  model->style);
1028  if (radio_entries_2[i].value == model->style)
1029  {
1030  DEBUG("match");
1031  break;
1032  }
1033  }
1034 
1035  /* Either a match was found, or fell out with i = 0 */
1036  action = gtk_action_group_get_action (action_group, radio_entries_2[i].name);
1037  g_signal_handlers_block_by_func (action, gnc_plugin_page_register2_cmd_style_changed, page);
1038  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1039  g_signal_handlers_unblock_by_func (action, gnc_plugin_page_register2_cmd_style_changed, page);
1040 
1041  view = gnc_split_reg2_get_register (priv->gsr);
1042 
1043  /* Set "double line" toggle button */
1044  action = gtk_action_group_get_action (action_group, "ViewStyleDoubleLineAction");
1045  g_signal_handlers_block_by_func (action, gnc_plugin_page_register2_cmd_style_double_line, page);
1046  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), model->use_double_line);
1047  g_signal_handlers_unblock_by_func (action, gnc_plugin_page_register2_cmd_style_double_line, page);
1048 
1049  /* Set "extra dates" toggle button */
1050  action = gtk_action_group_get_action (action_group, "ViewStyleExtraDatesAction");
1051  g_signal_handlers_block_by_func (action, gnc_plugin_page_register2_cmd_style_extra_dates, page);
1052  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), view->show_extra_dates);
1053  g_signal_handlers_unblock_by_func (action, gnc_plugin_page_register2_cmd_style_extra_dates, page);
1054 }
1055 
1056 
1057 /*#################################################################################*/
1058 /*#################################################################################*/
1059 /* Virtual Functions */
1060 
1061 static GtkWidget *
1062 gnc_plugin_page_register2_create_widget (GncPluginPage *plugin_page)
1063 {
1064  GncPluginPageRegister2 *page;
1066  GNCLedgerDisplay2Type ledger_type;
1067  GncWindow *gnc_window;
1068  guint numRows;
1069  GtkWidget *gsr;
1070 
1071  GncTreeViewSplitReg *view;
1072  GncTreeModelSplitReg *model;
1073  Account *acct;
1074  gchar **filter;
1075  gchar *order;
1076  int filter_changed = 0;
1077 
1078  ENTER("page %p", plugin_page);
1079  page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
1080  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
1081  if (priv->widget != NULL)
1082  {
1083  LEAVE("existing widget %p", priv->widget);
1084  return priv->widget;
1085  }
1086 
1087  priv->widget = gtk_vbox_new (FALSE, 0);
1088  gtk_widget_show (priv->widget);
1089 
1090  numRows = priv->lines_default;
1091  numRows = MIN (numRows, DEFAULT_LINES_AMOUNT);
1092 
1093  gnc_window = GNC_WINDOW (GNC_PLUGIN_PAGE (page)->window);
1094 
1095  gsr = gnc_split_reg2_new (priv->ledger,
1096  gnc_window_get_gtk_window (gnc_window),
1097  numRows, priv->read_only);
1098  priv->gsr = (GNCSplitReg2 *)gsr;
1099  gtk_widget_show (gsr);
1100 
1101  gtk_box_pack_start (GTK_BOX (priv->widget), gsr, TRUE, TRUE, 0);
1102 
1103  g_signal_connect (G_OBJECT (gsr), "help-changed",
1104  G_CALLBACK (gnc_plugin_page_help_changed_cb),
1105  page );
1106 
1107  view = gnc_split_reg2_get_register (priv->gsr);
1108 
1109  // Callback for right mouse events
1110  g_signal_connect (G_OBJECT (GTK_TREE_VIEW (view)), "button-press-event",
1111  G_CALLBACK (gnc_plugin_page_register2_button_press_cb), page);
1112 
1113  model = gnc_ledger_display2_get_split_model_register (priv->ledger);
1114 
1115  gnc_tree_model_split_reg_config (model, model->type, model->style, model->use_double_line);
1116 
1117  gnc_plugin_page_register2_ui_initial_state (page);
1118  gnc_plugin_page_register2_ui_update (NULL, page);
1119 
1120  ledger_type = gnc_ledger_display2_type (priv->ledger);
1121 
1122  if (ledger_type == LD2_SINGLE || ledger_type == LD2_SUBACCOUNT || ledger_type == LD2_GL)
1123  {
1124  /* Set the filter for the split register and status of save filter button */
1125  priv->fd.save_filter = FALSE;
1126 
1127  filter = g_strsplit(gnc_plugin_page_register2_get_filter (plugin_page), ",", -1);
1128 
1129  PINFO("Loaded Filter Status is %s", filter[0]);
1130 
1131  priv->fd.cleared_match = (gint)g_ascii_strtoll (filter[0], NULL, 16 );
1132 
1133  if (filter[0] && (g_strcmp0 (filter[0], DEFAULT_FILTER) != 0))
1134  filter_changed = filter_changed + 1;
1135 
1136  if (filter[1] && (g_strcmp0 (filter[1], "0") != 0 ))
1137  {
1138  PINFO("Loaded Filter Start Date is %s", filter[1]);
1139 
1140  priv->fd.start_time = gnc_plugin_page_register2_filter_dmy2time (filter[1]);
1141  priv->fd.start_time = gnc_time64_get_day_start (priv->fd.start_time);
1142  filter_changed = filter_changed + 1;
1143 
1144  if (filter[2] && (g_strcmp0 (filter[2], "0") != 0 ))
1145  {
1146  PINFO("Loaded Filter End Date is %s", filter[2]);
1147 
1148  priv->fd.end_time = gnc_plugin_page_register2_filter_dmy2time (filter[2]);
1149  priv->fd.end_time = gnc_time64_get_day_end (priv->fd.end_time);
1150  filter_changed = filter_changed + 1;
1151  }
1152  }
1153 
1154  if (filter_changed != 0)
1155  priv->fd.save_filter = TRUE;
1156 
1157  priv->fd.original_save_filter = priv->fd.save_filter;
1158  g_strfreev (filter);
1159 
1160  /* Update Query with Filter Status and Dates */
1161  gnc_ppr_update_status_query (page, FALSE);
1162  gnc_ppr_update_date_query (page, FALSE);
1163  }
1164 
1165 //FIXME may change, can we load filter at same time of sort so we do one querry on load
1166  gnc_ledger_display2_refresh (priv->ledger);
1167 
1168  /* This sets the default selection on load, not required for templates */
1169  if (!gnc_tree_model_split_reg_get_template (model))
1170  gnc_tree_view_split_reg_default_selection (view);
1171 
1172  plugin_page->summarybar = gnc_split_reg2_create_summary_bar (priv->gsr);
1173  if (plugin_page->summarybar)
1174  {
1175  gtk_widget_show_all (plugin_page->summarybar);
1176  gtk_box_pack_start (GTK_BOX (priv->widget), plugin_page->summarybar,
1177  FALSE, FALSE, 0);
1178  gnc_plugin_page_register2_summarybar_position_changed (NULL, NULL, page);
1179  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
1180  GNC_PREF_SUMMARYBAR_POSITION_TOP,
1181  gnc_plugin_page_register2_summarybar_position_changed,
1182  page);
1183  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
1184  GNC_PREF_SUMMARYBAR_POSITION_BOTTOM,
1185  gnc_plugin_page_register2_summarybar_position_changed,
1186  page);
1187  }
1188 
1189  priv->event_handler_id = qof_event_register_handler
1190  ((QofEventHandler)gnc_plugin_page_register2_event_handler, page);
1191  priv->component_manager_id =
1192  gnc_register_gui_component (GNC_PLUGIN_PAGE_REGISTER2_NAME,
1193  gnc_plugin_page_register2_refresh_cb,
1194  gnc_plugin_page_register2_close_cb,
1195  page);
1196  gnc_gui_component_set_session (priv->component_manager_id,
1197  gnc_get_current_session());
1199  if (acct)
1200  gnc_gui_component_watch_entity (
1201  priv->component_manager_id, xaccAccountGetGUID (acct),
1202  QOF_EVENT_DESTROY | QOF_EVENT_MODIFY);
1203 
1204  /* This allows the plugin page to be updated from the view */
1205  gnc_split_reg2_set_moved_cb
1206  (priv->gsr, (GFunc)gnc_plugin_page_register2_ui_update, page);
1207 
1208  LEAVE(" ");
1209  return priv->widget;
1210 }
1211 
1212 /*#################################################################################*/
1213 
1221 static gboolean
1222 gnc_plugin_page_register2_button_press_cb (GtkWidget *widget,
1223  GdkEventButton *event,
1224  GncPluginPage *page)
1225 {
1226 
1227  g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
1228 
1229  ENTER("widget %p, event %p, page %p", widget, event, page);
1230  gnc_main_window_button_press_cb (widget, event, page);
1231  LEAVE(" ");
1232 
1233  /* Always return FALSE. This will let the tree view callback run as
1234  * well which will select the item under the cursor. By the time
1235  * the user sees the menu both callbacks will have run and the menu
1236  * actions will operate on the just-selected account. */
1237  return FALSE;
1238 }
1239 
1240 static void
1241 gnc_plugin_page_register2_destroy_widget (GncPluginPage *plugin_page)
1242 {
1243  GncPluginPageRegister2 *page;
1245 
1246  ENTER("page %p", plugin_page);
1247  page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
1248  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
1249 
1250  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
1251  GNC_PREF_SUMMARYBAR_POSITION_TOP,
1252  gnc_plugin_page_register2_summarybar_position_changed,
1253  page);
1254  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
1255  GNC_PREF_SUMMARYBAR_POSITION_BOTTOM,
1256  gnc_plugin_page_register2_summarybar_position_changed,
1257  page);
1258 
1259  if (priv->widget == NULL)
1260  {
1261  LEAVE(" ");
1262  return;
1263  }
1264 
1265  if (priv->component_manager_id)
1266  {
1267  gnc_unregister_gui_component (priv->component_manager_id);
1268  priv->component_manager_id = 0;
1269  }
1270 
1271  if (priv->event_handler_id)
1272  {
1273  qof_event_unregister_handler (priv->event_handler_id);
1274  priv->event_handler_id = 0;
1275  }
1276 
1277  if (priv->fd.dialog)
1278  {
1279  gtk_widget_destroy (priv->fd.dialog);
1280  memset(&priv->fd, 0, sizeof(priv->fd));
1281  }
1282 
1283  gtk_widget_hide (priv->widget);
1284 
1285  if (priv->ledger)
1286  {
1287  gnc_ledger_display2_close (priv->ledger);
1288  priv->ledger = NULL;
1289  }
1290 
1291  if (priv->widget)
1292  {
1293  g_object_unref (G_OBJECT(priv->widget));
1294  priv->widget = NULL;
1295  }
1296  LEAVE(" ");
1297 }
1298 
1299 static void
1300 gnc_plugin_page_register2_window_changed (GncPluginPage *plugin_page,
1301  GtkWidget *window) // this works
1302 {
1303  GncPluginPageRegister2 *page;
1305 
1306  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
1307 
1308  page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
1309  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
1310 
1311  priv->gsr->window =
1312  GTK_WIDGET(gnc_window_get_gtk_window (GNC_WINDOW (window)));
1313 }
1314 
1315 static const gchar *style_names[] =
1316 {
1317  "Ledger",
1318  "Auto Ledger",
1319  "Journal",
1320  NULL
1321 };
1322 
1323 #define KEY_REGISTER_TYPE "RegisterType"
1324 #define KEY_ACCOUNT_NAME "AccountName"
1325 #define KEY_REGISTER_STYLE "RegisterStyle"
1326 #define KEY_DOUBLE_LINE "DoubleLineMode"
1327 #define KEY_EXTRA_DATES "ExtraDatesMode"
1328 
1329 #define LABEL_ACCOUNT "Account"
1330 #define LABEL_SUBACCOUNT "SubAccount"
1331 #define LABEL_GL "GL"
1332 #define LABEL_SEARCH "Search"
1333 
1334 #define SPLIT_REGISTER_GUID "SplitRegister GUID"
1335 
1345 static void
1346 gnc_plugin_page_register2_save_page (GncPluginPage *plugin_page,
1347  GKeyFile *key_file,
1348  const gchar *group_name)
1349 {
1350  GncPluginPageRegister2 *page;
1352  GNCLedgerDisplay2Type ledger_type;
1353  GncTreeViewSplitReg *view;
1354  GncTreeModelSplitReg *model;
1355  Account *leader;
1356 
1357  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
1358  g_return_if_fail (key_file != NULL);
1359  g_return_if_fail (group_name != NULL);
1360 
1361  ENTER("page %p, key_file %p, group_name %s", plugin_page, key_file,
1362  group_name);
1363 
1364  page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
1365  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
1366 
1367  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
1368  model = gnc_ledger_display2_get_split_model_register (priv->ledger);
1369  ledger_type = gnc_ledger_display2_type (priv->ledger);
1370  if (ledger_type > LD2_GL)
1371  {
1372  LEAVE("Unsupported ledger type");
1373  return;
1374  }
1375  if ((ledger_type == LD2_SINGLE) || (ledger_type == LD2_SUBACCOUNT))
1376  {
1377  const gchar *label;
1378  gchar* name;
1379  label = (ledger_type == LD2_SINGLE) ? LABEL_ACCOUNT : LABEL_SUBACCOUNT;
1380  leader = gnc_ledger_display2_leader (priv->ledger);
1381  g_key_file_set_string (key_file, group_name, KEY_REGISTER_TYPE, label);
1382  name = gnc_account_get_full_name (leader);
1383  g_key_file_set_string (key_file, group_name, KEY_ACCOUNT_NAME, name);
1384  g_free (name);
1385  }
1386  else if (model->type == GENERAL_LEDGER2)
1387  {
1388  g_key_file_set_string (key_file, group_name, KEY_REGISTER_TYPE,
1389  LABEL_GL);
1390  }
1391  else if (model->type == SEARCH_LEDGER2)
1392  {
1393  g_key_file_set_string (key_file, group_name, KEY_REGISTER_TYPE,
1394  LABEL_SEARCH);
1395  }
1396  else
1397  {
1398  LEAVE("Unsupported register type");
1399  return;
1400  }
1401 
1402  g_key_file_set_string (key_file, group_name, KEY_REGISTER_STYLE, style_names[model->style]);
1403  g_key_file_set_boolean (key_file, group_name, KEY_DOUBLE_LINE, model->use_double_line);
1404  g_key_file_set_boolean (key_file, group_name, KEY_EXTRA_DATES, view->show_extra_dates);
1405 
1406  LEAVE(" ");
1407 }
1408 
1421 static void
1422 gnc_plugin_page_register2_restore_edit_menu (GncPluginPage *page,
1423  GKeyFile *key_file,
1424  const gchar *group_name)
1425 {
1427  GtkAction *action;
1428  GError *error = NULL;
1429  gchar *style_name;
1430  gint i;
1431  gboolean use_double_line;
1432  gboolean show_extra_dates;
1433 
1434  ENTER(" ");
1435  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
1436 
1437  /* Convert the style name to an index */
1438  style_name = g_key_file_get_string (key_file, group_name,
1439  KEY_REGISTER_STYLE, &error);
1440  for (i = 0 ; style_names[i]; i++)
1441  {
1442  if (g_ascii_strcasecmp (style_name, style_names[i]) == 0)
1443  {
1444  DEBUG("Found match for style name: %s", style_name);
1445  break;
1446  }
1447  }
1448  g_free (style_name);
1449 
1450  /* Update the style menu action for this page */
1451  if (i <= REG2_STYLE_JOURNAL)
1452  {
1453  DEBUG("Setting style: %d", i);
1454  action = gnc_plugin_page_get_action (page, radio_entries_2[i].name);
1455  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1456  }
1457 
1458  /* Update the double line action on this page */
1459  use_double_line =
1460  g_key_file_get_boolean (key_file, group_name, KEY_DOUBLE_LINE, &error);
1461  DEBUG("Setting double_line_mode: %d", use_double_line);
1462  action = gnc_plugin_page_get_action (page, "ViewStyleDoubleLineAction");
1463  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), use_double_line);
1464 
1465  /* Update the extra dates action on this page */
1466  show_extra_dates =
1467  g_key_file_get_boolean (key_file, group_name, KEY_EXTRA_DATES, &error);
1468  DEBUG("Setting extra_dates_mode: %d", show_extra_dates);
1469  action = gnc_plugin_page_get_action (page, "ViewStyleExtraDatesAction");
1470  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), show_extra_dates);
1471  LEAVE(" ");
1472 }
1473 
1483 static GncPluginPage *
1484 gnc_plugin_page_register2_recreate_page (GtkWidget *window,
1485  GKeyFile *key_file,
1486  const gchar *group_name)
1487 {
1488  GncPluginPage *page;
1489  GError *error = NULL;
1490  gchar *reg_type, *acct_name;
1491  Account *account;
1492  QofBook *book;
1493  gboolean include_subs;
1494 
1495  g_return_val_if_fail (key_file, NULL);
1496  g_return_val_if_fail (group_name, NULL);
1497  ENTER("key_file %p, group_name %s", key_file, group_name);
1498 
1499  /* Create the new page. */
1500  reg_type = g_key_file_get_string (key_file, group_name,
1501  KEY_REGISTER_TYPE, &error);
1502  DEBUG("Page type: %s", reg_type);
1503  if ((g_ascii_strcasecmp (reg_type, LABEL_ACCOUNT) == 0) ||
1504  (g_ascii_strcasecmp (reg_type, LABEL_SUBACCOUNT) == 0))
1505  {
1506  include_subs = (g_ascii_strcasecmp(reg_type, LABEL_SUBACCOUNT) == 0);
1507  DEBUG("Include subs: %d", include_subs);
1508  acct_name = g_key_file_get_string (key_file, group_name,
1509  KEY_ACCOUNT_NAME, &error);
1510  book = qof_session_get_book (gnc_get_current_session());
1511  account = gnc_account_lookup_by_full_name (gnc_book_get_root_account(book),
1512  acct_name);
1513  g_free (acct_name);
1514  if (account == NULL)
1515  {
1516  LEAVE("Bad account name");
1517  g_free (reg_type);
1518  return NULL;
1519  }
1520  page = gnc_plugin_page_register2_new (account, include_subs);
1521  }
1522  else if (g_ascii_strcasecmp (reg_type, LABEL_GL) == 0)
1523  {
1525  }
1526  else
1527  {
1528  LEAVE("Bad ledger type");
1529  g_free (reg_type);
1530  return NULL;
1531  }
1532  g_free (reg_type);
1533 
1534  /* Recreate page in given window */
1535  gnc_plugin_page_set_use_new_window (page, FALSE);
1536 
1537  /* Install it now so we can them manipulate the created widget */
1538  gnc_main_window_open_page (GNC_MAIN_WINDOW (window), page);
1539 
1540  /* Now update the page to the last state it was in */
1541  gnc_plugin_page_register2_restore_edit_menu (page, key_file, group_name);
1542  LEAVE(" ");
1543  return page;
1544 }
1545 
1546 
1547 /*
1548  * Based on code from Epiphany (src/ephy-window.c)
1549  */
1550 static void
1551 gnc_plugin_page_register2_update_edit_menu (GncPluginPage *page, gboolean hide) //this works
1552 {
1554  GncPluginPageRegister2 *reg_page;
1555  GncTreeViewSplitReg *view;
1556  GtkAction *action;
1557  gboolean can_copy = FALSE, can_cut = FALSE, can_paste = FALSE;
1558  gboolean has_selection;
1559  gboolean is_readwrite = !qof_book_is_readonly (gnc_get_current_book());
1560  reg_page = GNC_PLUGIN_PAGE_REGISTER2 (page);
1561  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (reg_page);
1562  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
1563 
1564  // This is set while we are editing a cell
1565  if (view->editing_now)
1566  has_selection = TRUE;
1567  else
1568  has_selection = FALSE;
1569 
1570  can_copy = has_selection;
1571  can_cut = is_readwrite && has_selection;
1572  can_paste = is_readwrite;
1573 
1574  action = gnc_plugin_page_get_action (page, "EditCopyAction");
1575  gtk_action_set_sensitive (action, can_copy);
1576  gtk_action_set_visible (action, !hide || can_copy);
1577  action = gnc_plugin_page_get_action (page, "EditCutAction");
1578  gtk_action_set_sensitive (action, can_cut);
1579  gtk_action_set_visible (action, !hide || can_cut);
1580  action = gnc_plugin_page_get_action (page, "EditPasteAction");
1581  gtk_action_set_sensitive (action, can_paste);
1582  gtk_action_set_visible (action, !hide || can_paste);
1583 }
1584 
1585 static gboolean
1586 gnc_plugin_page_register2_finish_pending (GncPluginPage *page) //this works
1587 {
1589  GncPluginPageRegister2 *reg_page;
1590  GncTreeViewSplitReg *view;
1591  GtkWidget *dialog, *window;
1592  const gchar *name;
1593  gint response;
1594 
1595  reg_page = GNC_PLUGIN_PAGE_REGISTER2 (page);
1596  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (reg_page);
1597  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
1598 
1599  /* Make sure we have stopped editing */
1600  gnc_tree_view_split_reg_finish_edit (view);
1601 
1602  if (!view || (gnc_tree_view_split_reg_get_dirty_trans (view) == NULL))
1603  return TRUE;
1604 
1605  name = gnc_plugin_page_register2_get_tab_name (page);
1606  window = gnc_plugin_page_get_window (page);
1607  dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1608  GTK_DIALOG_DESTROY_WITH_PARENT,
1609  GTK_MESSAGE_WARNING,
1610  GTK_BUTTONS_NONE,
1611  /* Translators: %s is the name
1612  of the tab page */
1613  _("Save changes to %s?"), name);
1614  gtk_message_dialog_format_secondary_text
1615  (GTK_MESSAGE_DIALOG (dialog),
1616  "%s",
1617  _("This register has pending changes to a transaction. "
1618  "Would you like to save the changes to this transaction, "
1619  "discard the transaction, or cancel the operation?"));
1620  gnc_gtk_dialog_add_button (dialog, _("_Discard Transaction"),
1621  GTK_STOCK_DELETE, GTK_RESPONSE_REJECT);
1622  gtk_dialog_add_button (GTK_DIALOG (dialog),
1623  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1624  gnc_gtk_dialog_add_button (dialog, _("_Save Transaction"),
1625  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT);
1626 
1627  response = gtk_dialog_run (GTK_DIALOG (dialog));
1628  gtk_widget_destroy (dialog);
1629 
1630  switch (response)
1631  {
1632  case GTK_RESPONSE_ACCEPT:
1633  return (gnc_tree_control_split_reg_save (view, TRUE));
1634 
1635  case GTK_RESPONSE_REJECT:
1636  gnc_tree_control_split_reg_cancel_edit (view, TRUE);
1637  return TRUE;
1638 
1639  default:
1640  return FALSE;
1641  }
1642 }
1643 
1644 static gchar *
1645 gnc_plugin_page_register2_get_tab_name (GncPluginPage *plugin_page)
1646 {
1648  GNCLedgerDisplay2Type ledger_type;
1649  GNCLedgerDisplay2 *ld;
1650  GncTreeModelSplitReg *model;
1651  Account *leader;
1652 
1653  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
1654 
1655  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
1656  ld = priv->ledger;
1657  model = gnc_ledger_display2_get_split_model_register(ld);
1658  ledger_type = gnc_ledger_display2_type (ld);
1659  leader = gnc_ledger_display2_leader (ld);
1660 
1661  switch (ledger_type)
1662  {
1663  case LD2_SINGLE:
1664  return g_strdup(xaccAccountGetName (leader));
1665 
1666  case LD2_SUBACCOUNT:
1667  return g_strdup_printf("%s+", xaccAccountGetName (leader));
1668 
1669  case LD2_GL:
1670  switch (model->type)
1671  {
1672  case GENERAL_LEDGER:
1673  case INCOME_LEDGER:
1674  return g_strdup(_("General Ledger"));
1675  case PORTFOLIO_LEDGER:
1676  return g_strdup(_("Portfolio"));
1677  case SEARCH_LEDGER:
1678  return g_strdup(_("Search Results"));
1679  default:
1680  break;
1681  }
1682  break;
1683 
1684  default:
1685  break;
1686  }
1687 
1688  return g_strdup(_("unknown"));
1689 }
1690 
1691 static gchar *
1692 gnc_plugin_page_register2_get_tab_color (GncPluginPage *plugin_page)
1693 {
1695  GNCLedgerDisplay2Type ledger_type;
1696  GNCLedgerDisplay2 *ld;
1697  Account *leader;
1698  const char* color;
1699 
1700  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
1701 
1702  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
1703  ld = priv->ledger;
1704  ledger_type = gnc_ledger_display2_type (ld);
1705  leader = gnc_ledger_display2_leader (ld);
1706  color = NULL;
1707 
1708  if ((ledger_type == LD2_SINGLE) || (ledger_type == LD2_SUBACCOUNT))
1709  color = xaccAccountGetColor (leader);
1710 
1711  return g_strdup(color ? color : "Not Set");
1712 }
1713 
1714 static gchar *
1715 gnc_plugin_page_register2_get_filter (GncPluginPage *plugin_page)
1716 {
1718  GNCLedgerDisplay2Type ledger_type;
1719  GNCLedgerDisplay2 *ld;
1720  Account *leader;
1721  const char* filter;
1722 
1723  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
1724 
1725  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
1726  ld = priv->ledger;
1727  ledger_type = gnc_ledger_display2_type (ld);
1728  leader = gnc_ledger_display2_leader (ld);
1729  filter = NULL;
1730 
1731  if ((ledger_type == LD2_SINGLE) || (ledger_type == LD2_SUBACCOUNT))
1732  filter = xaccAccountGetFilter (leader);
1733 
1734  return filter ? g_strdup(filter) : g_strdup_printf("%s,%s,%s", DEFAULT_FILTER, "0", "0");
1735 }
1736 
1737 void
1738 gnc_plugin_page_register2_set_filter (GncPluginPage *plugin_page, const gchar *filter )
1739 {
1741  GNCLedgerDisplay2Type ledger_type;
1742  GNCLedgerDisplay2 *ld;
1743  Account *leader;
1744  gchar *default_filter;
1745 
1746  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
1747  ld = priv->ledger;
1748  ledger_type = gnc_ledger_display2_type (ld);
1749  leader = gnc_ledger_display2_leader (ld);
1750 
1751  if (leader != NULL)
1752  {
1753  default_filter = g_strdup_printf("%s,%s,%s", DEFAULT_FILTER, "0", "0");
1754 
1755  if (!filter || (g_strcmp0 (filter, default_filter) == 0))
1756  xaccAccountSetFilter (leader, NULL);
1757  else
1758  xaccAccountSetFilter (leader, filter);
1759 
1760  g_free (default_filter);
1761  }
1762  return;
1763 }
1764 
1765 static gchar *
1766 gnc_plugin_page_register2_get_long_name (GncPluginPage *plugin_page)
1767 {
1769  GNCLedgerDisplay2Type ledger_type;
1770  GNCLedgerDisplay2 *ld;
1771  Account *leader;
1772 
1773  g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
1774 
1775  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
1776  ld = priv->ledger;
1777  ledger_type = gnc_ledger_display2_type (ld);
1778  leader = gnc_ledger_display2_leader (ld);
1779 
1780  switch (ledger_type)
1781  {
1782  case LD2_SINGLE:
1783  return gnc_account_get_full_name (leader);
1784 
1785  case LD2_SUBACCOUNT:
1786  {
1787  gchar *account_full_name = gnc_account_get_full_name (leader);
1788  gchar *return_string = g_strdup_printf ("%s+", account_full_name);
1789  g_free ((gpointer *) account_full_name);
1790  return return_string;
1791  }
1792 
1793  default:
1794  break;
1795  }
1796 
1797  return NULL;
1798 }
1799 
1800 static void
1801 gnc_plugin_page_register2_summarybar_position_changed (gpointer prefs, gchar* pref, gpointer user_data)
1802 {
1803  GncPluginPage *plugin_page;
1804  GncPluginPageRegister2 *page;
1806  GtkPositionType position = GTK_POS_BOTTOM;
1807 
1808  g_return_if_fail (user_data != NULL);
1809 
1810  if (!GNC_IS_PLUGIN_PAGE (user_data))
1811  return;
1812 
1813  plugin_page = GNC_PLUGIN_PAGE (user_data);
1814  page = GNC_PLUGIN_PAGE_REGISTER2 (user_data);
1815  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
1816 
1817  if (priv == NULL)
1818  return;
1819 
1820  if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SUMMARYBAR_POSITION_TOP))
1821  position = GTK_POS_TOP;
1822 
1823  gtk_box_reorder_child (GTK_BOX (priv->widget),
1824  plugin_page->summarybar,
1825  (position == GTK_POS_TOP ? 0 : -1) );
1826 }
1827 
1828 /*#################################################################################*/
1829 /*#################################################################################*/
1830 
1831 /************************************************************/
1832 /* "Filter By" Dialog */
1833 /************************************************************/
1834 
1847 static void
1848 gnc_ppr_update_status_query (GncPluginPageRegister2 *page, gboolean refresh_page)
1849 {
1851  GSList *param_list;
1852  Query *query;
1853 
1854  ENTER(" ");
1855  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
1856  query = gnc_ledger_display2_get_query (priv->ledger );
1857  if (!query)
1858  {
1859  LEAVE("no query found");
1860  return;
1861  }
1862 
1863  /* Remove the old status match */
1864  param_list = qof_query_build_param_list (SPLIT_RECONCILE, NULL);
1865  if (param_list)
1866  {
1867  qof_query_purge_terms (query, param_list);
1868  g_slist_free(param_list);
1869  }
1870 
1871  /* Install the new status match */
1872  if (priv->fd.cleared_match != CLEARED_ALL)
1873  xaccQueryAddClearedMatch(query, priv->fd.cleared_match, QOF_QUERY_AND);
1874 
1875  if (refresh_page)
1876  gnc_ledger_display2_refresh (priv->ledger);
1877  LEAVE(" ");
1878 }
1879 
1892 static void
1893 gnc_ppr_update_date_query (GncPluginPageRegister2 *page, gboolean refresh_page)
1894 {
1896  GSList *param_list;
1897  Query *query;
1898 
1899  ENTER(" ");
1900  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
1901  if (!priv->ledger)
1902  {
1903  LEAVE("no ledger");
1904  return;
1905  }
1906 
1907  query = gnc_ledger_display2_get_query (priv->ledger);
1908  if (!query)
1909  {
1910  LEAVE("no query");
1911  return;
1912  }
1913 
1914  /* Delete any existing old date spec. */
1915  param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, NULL);
1916  if (param_list)
1917  {
1918  qof_query_purge_terms (query, param_list);
1919  g_slist_free(param_list);
1920  }
1921 
1922  if (priv->fd.start_time || priv->fd.end_time)
1923  {
1924  /* Build a new spec */
1925  xaccQueryAddDateMatchTT (query,
1926  priv->fd.start_time != 0, priv->fd.start_time,
1927  priv->fd.end_time != 0, priv->fd.end_time,
1928  QOF_QUERY_AND);
1929  }
1930 
1931  if (refresh_page)
1932  gnc_ledger_display2_refresh (priv->ledger);
1933  LEAVE(" ");
1934 }
1935 
1936 /* This function converts a time64 value date to a string */
1937 static gchar *
1938 gnc_plugin_page_register2_filter_time2dmy (time64 raw_time)
1939 {
1940  struct tm * timeinfo;
1941  gchar date_string[11];
1942  gint i;
1943 
1944  timeinfo = gnc_localtime (&raw_time);
1945  i = strftime (date_string, 11, "%d-%m-%Y", timeinfo);
1946  PINFO("Date string is %s", date_string);
1947 
1948  gnc_tm_free (timeinfo);
1949  return g_strdup (date_string);
1950 }
1951 
1952 /* This function converts a string date to a time64 value */
1953 static time64
1954 gnc_plugin_page_register2_filter_dmy2time (char *date_string)
1955 {
1956  struct tm when;
1957 
1958  PINFO("Date string is %s", date_string);
1959  memset (&when, 0, sizeof (when));
1960  sscanf (date_string, "%d-%d-%d", &when.tm_mday,
1961  &when.tm_mon, &when.tm_year);
1962 
1963  when.tm_year -= 1900;
1964  when.tm_mon -= 1;
1965 
1966  return gnc_mktime (&when);
1967 }
1968 
1979 void
1981  GncPluginPageRegister2 *page)
1982 {
1984  const gchar *name;
1985  gint i, value;
1986 
1987  g_return_if_fail (GTK_IS_CHECK_BUTTON (button));
1988  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
1989 
1990  name = gtk_buildable_get_name (GTK_BUILDABLE (button));
1991  ENTER("toggle button %s (%p), plugin_page %p", name, button, page);
1992 
1993  /* Determine what status bit to change */
1994  value = CLEARED_NONE;
1995  for (i = 0; status_actions[i].action_name; i++)
1996  {
1997  if (g_strcmp0 (name, status_actions[i].action_name) == 0)
1998  {
1999  value = status_actions[i].value;
2000  break;
2001  }
2002  }
2003 
2004  /* Compute the new match status */
2005  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2006  if (gtk_toggle_button_get_active (button))
2007  priv->fd.cleared_match |= value;
2008  else
2009  priv->fd.cleared_match &= ~value;
2010  gnc_ppr_update_status_query (page, TRUE);
2011  LEAVE(" ");
2012 }
2013 
2023 void
2025  GncPluginPageRegister2 *page)
2026 {
2028  GtkWidget *widget;
2029  gint i;
2030 
2031  g_return_if_fail (GTK_IS_BUTTON (button));
2032  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2033 
2034  ENTER("(button %p, page %p)", button, page);
2035 
2036  /* Turn on all the check menu items */
2037  for (i = 0; status_actions[i].action_name; i++)
2038  {
2039  widget = status_actions[i].widget;
2040  g_signal_handlers_block_by_func (widget, gnc_plugin_page_register2_filter_status_one_cb, page);
2041  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
2042  g_signal_handlers_unblock_by_func (widget, gnc_plugin_page_register2_filter_status_one_cb, page);
2043  }
2044 
2045  /* Set the requested status */
2046  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2047  priv->fd.cleared_match = CLEARED_ALL;
2048  gnc_ppr_update_status_query (page, TRUE);
2049  LEAVE(" ");
2050 }
2051 
2063 static void
2064 get_filter_times (GncPluginPageRegister2 *page)
2065 {
2067  GtkWidget *button, *today, *gde;
2068  time64 time_val;
2069 
2070  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2071  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->fd.start_date_choose)))
2072  {
2073  time_val = gnc_date_edit_get_date (GNC_DATE_EDIT (priv->fd.start_date));
2074  time_val = gnc_time64_get_day_start (time_val);
2075  priv->fd.start_time = time_val;
2076  }
2077  else
2078  {
2079  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->fd.start_date_today)))
2080  {
2081  priv->fd.start_time = gnc_time64_get_today_start();
2082  }
2083  else
2084  {
2085  priv->fd.start_time = 0;
2086  }
2087  }
2088 
2089  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->fd.end_date_choose)))
2090  {
2091  time_val = gnc_date_edit_get_date (GNC_DATE_EDIT (priv->fd.end_date));
2092  time_val = gnc_time64_get_day_end (time_val);
2093  priv->fd.end_time = time_val;
2094  }
2095  else
2096  {
2097  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->fd.start_date_today)))
2098  {
2099  priv->fd.end_time = gnc_time64_get_today_end();
2100  }
2101  else
2102  {
2103  priv->fd.end_time = 0;
2104  }
2105  }
2106 }
2107 
2123 void
2125  GncPluginPageRegister2 *page)
2126 {
2128  gboolean active;
2129 
2130  g_return_if_fail (GTK_IS_RADIO_BUTTON (button));
2131  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2132 
2133  ENTER("(button %p, page %p)", button, page);
2134  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2135  active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
2136  gtk_widget_set_sensitive (priv->fd.table, active);
2137  if (active)
2138  {
2139  get_filter_times (page);
2140  }
2141  else
2142  {
2143  priv->fd.start_time = 0;
2144  priv->fd.end_time = 0;
2145  }
2146  gnc_ppr_update_date_query (page, TRUE);
2147  LEAVE(" ");
2148 }
2149 
2160 static void
2161 gnc_plugin_page_register2_filter_gde_changed_cb (GtkWidget *unused,
2162  GncPluginPageRegister2 *page)
2163 {
2164  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2165 
2166  ENTER("(widget %s(%p), page %p)", gtk_buildable_get_name (GTK_BUILDABLE (unused)), unused, page);
2167  get_filter_times (page);
2168  gnc_ppr_update_date_query (page, TRUE);
2169  LEAVE(" ");
2170 }
2171 
2191 void
2193  GncPluginPageRegister2 *page)
2194 {
2196  const gchar *name;
2197  gboolean active;
2198 
2199  g_return_if_fail (GTK_IS_RADIO_BUTTON (radio));
2200  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2201 
2202  ENTER("(radio %s(%p), page %p)", gtk_buildable_get_name (GTK_BUILDABLE (radio)), radio, page);
2203  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2204  if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio)))
2205  {
2206  LEAVE("1st callback of pair. Defer to 2nd callback.");
2207  return;
2208  }
2209 
2210  name = gtk_buildable_get_name (GTK_BUILDABLE (radio));
2211  active = (g_strcmp0 (name, g_strdup ("start_date_choose")) == 0 ? 1 : 0 );
2212  gtk_widget_set_sensitive (priv->fd.start_date, active);
2213  get_filter_times (page);
2214  gnc_ppr_update_date_query (page, TRUE);
2215  LEAVE(" ");
2216 }
2217 
2237 void
2239  GncPluginPageRegister2 *page)
2240 {
2242  const gchar *name;
2243  gboolean active;
2244 
2245  g_return_if_fail (GTK_IS_RADIO_BUTTON (radio));
2246  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2247 
2248  ENTER("(radio %s(%p), page %p)", gtk_buildable_get_name (GTK_BUILDABLE (radio)), radio, page);
2249  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2250  if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio)))
2251  {
2252  LEAVE("1st callback of pair. Defer to 2nd callback.");
2253  return;
2254  }
2255 
2256  name = gtk_buildable_get_name (GTK_BUILDABLE (radio));
2257  active = (g_strcmp0 (name, g_strdup ("end_date_choose")) == 0 ? 1 : 0 );
2258  gtk_widget_set_sensitive (priv->fd.end_date, active);
2259  get_filter_times (page);
2260  gnc_ppr_update_date_query (page, TRUE);
2261  LEAVE(" ");
2262 }
2263 
2272 void
2274  GncPluginPageRegister2 *page)
2275 {
2277 
2278  g_return_if_fail (GTK_IS_CHECK_BUTTON (button));
2279  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2280 
2281  ENTER("Save toggle button (%p), plugin_page %p", button, page);
2282 
2283  /* Compute the new save filter status */
2284  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2285  if (gtk_toggle_button_get_active (button))
2286  priv->fd.save_filter = TRUE;
2287  else
2288  priv->fd.save_filter = FALSE;
2289  LEAVE(" ");
2290 }
2291 
2303 void
2305  gint response,
2306  GncPluginPageRegister2 *page)
2307 {
2309  GncPluginPage *plugin_page;
2310 
2311  g_return_if_fail (GTK_IS_DIALOG (dialog));
2312  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2313 
2314  ENTER(" ");
2315  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2316  plugin_page = GNC_PLUGIN_PAGE (page);
2317 
2318  if (response != GTK_RESPONSE_OK)
2319  {
2320  /* Remove the old status match */
2321  priv->fd.cleared_match = priv->fd.original_cleared_match;
2322  gnc_ppr_update_status_query (page, FALSE);
2323  priv->fd.start_time = priv->fd.original_start_time;
2324  priv->fd.end_time = priv->fd.original_end_time;
2325  priv->fd.save_filter = priv->fd.original_save_filter;
2326  gnc_ppr_update_date_query (page, FALSE);
2327  gnc_ledger_display2_refresh (priv->ledger);
2328  }
2329  else
2330  {
2331  priv->fd.original_save_filter = priv->fd.save_filter;
2332 
2333  if (priv->fd.save_filter)
2334  {
2335  gchar* filter;
2336  filter = g_strdup_printf ("0x%04x", priv->fd.cleared_match);
2337 
2338  if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->fd.start_date_choose)) && priv->fd.start_time != 0 )
2339  {
2340  gchar *timeval = gnc_plugin_page_register2_filter_time2dmy (priv->fd.start_time);
2341  filter = g_strconcat (filter, ",", timeval, NULL);
2342  g_free (timeval);
2343  }
2344  else
2345  filter = g_strconcat (filter, ",0", NULL);
2346 
2347  if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->fd.end_date_choose)) && priv->fd.end_time != 0 )
2348  {
2349  gchar *timeval = gnc_plugin_page_register2_filter_time2dmy (priv->fd.end_time);
2350  filter = g_strconcat (filter, ",", timeval, NULL);
2351  g_free (timeval);
2352  }
2353  else
2354  filter = g_strconcat (filter, ",0", NULL);
2355 
2356  PINFO("The filter to save is %s", filter);
2357 
2358  gnc_plugin_page_register2_set_filter (plugin_page, filter);
2359  g_free (filter);
2360  }
2361  }
2362  priv->fd.dialog = NULL;
2363  gtk_widget_destroy (GTK_WIDGET (dialog));
2364  LEAVE(" ");
2365 }
2366 
2367 /*#################################################################################*/
2368 /*#################################################################################*/
2369 
2370 /************************************************************/
2371 /* Report Helper Functions */
2372 /************************************************************/
2373 
2374 static char *
2375 gnc_reg_get_name (GNCLedgerDisplay2 *ledger, gboolean for_window) // this works
2376 {
2377  Account *leader;
2378  GncTreeModelSplitReg *model;
2379  gchar *account_name;
2380  gchar *reg_name;
2381  gchar *name;
2382  GNCLedgerDisplay2Type ledger_type;
2383 
2384  if (ledger == NULL)
2385  return NULL;
2386 
2387  model = gnc_ledger_display2_get_split_model_register (ledger);
2388  ledger_type = gnc_ledger_display2_type (ledger);
2389 
2390  switch (model->type)
2391  {
2392  case GENERAL_LEDGER:
2393  case INCOME_LEDGER:
2394  if (for_window)
2395  reg_name = _("General Ledger");
2396  else
2397  reg_name = _("General Ledger Report");
2398  break;
2399  case PORTFOLIO_LEDGER:
2400  if (for_window)
2401  reg_name = _("Portfolio");
2402  else
2403  reg_name = _("Portfolio Report");
2404  break;
2405  case SEARCH_LEDGER:
2406  if (for_window)
2407  reg_name = _("Search Results");
2408  else
2409  reg_name = _("Search Results Report");
2410  break;
2411  default:
2412  if (for_window)
2413  reg_name = _("Register");
2414  else
2415  reg_name = _("Register Report");
2416  break;
2417  }
2418 
2419  leader = gnc_ledger_display2_leader (ledger);
2420 
2421  if ((leader != NULL) && (ledger_type != LD2_GL))
2422  {
2423  account_name = gnc_account_get_full_name (leader);
2424 
2425  if (ledger_type == LD2_SINGLE)
2426  {
2427  name = g_strconcat (account_name, " - ", reg_name, NULL);
2428  }
2429  else
2430  {
2431  name = g_strconcat (account_name, " ", _("and subaccounts"), " - ", reg_name, NULL);
2432  }
2433  g_free (account_name);
2434  }
2435  else
2436  name = g_strdup (reg_name);
2437 
2438  return name;
2439 }
2440 
2441 static int
2442 report_helper (GNCLedgerDisplay2 *ledger, Split *split, Query *query) //this works
2443 {
2444  GncTreeViewSplitReg *view;
2445  GncTreeModelSplitReg *model;
2446  Account *account;
2447  char *str;
2448  const char *tmp;
2449  swig_type_info * qtype;
2450  SCM args;
2451  SCM func;
2452  SCM arg;
2453 
2454  args = SCM_EOL;
2455 
2456  view = gnc_ledger_display2_get_split_view_register (ledger);
2457  model = gnc_ledger_display2_get_split_model_register (ledger);
2458 
2459  func = scm_c_eval_string ("gnc:register-report-create");
2460  g_return_val_if_fail (scm_is_procedure (func), -1);
2461  tmp = gnc_tree_view_split_reg_get_credit_debit_string (view, TRUE);
2462 
2463  arg = scm_from_utf8_string (tmp ? tmp : _("Credit"));
2464  args = scm_cons (arg, args);
2465  tmp = gnc_tree_view_split_reg_get_credit_debit_string (view, FALSE);
2466  arg = scm_from_utf8_string (tmp ? tmp : _("Debit"));
2467  args = scm_cons (arg, args);
2468 
2469  str = gnc_reg_get_name (ledger, FALSE);
2470  arg = scm_from_utf8_string (str ? str : "");
2471  args = scm_cons (arg, args);
2472  g_free (str);
2473 
2474  arg = SCM_BOOL (model->use_double_line);
2475  args = scm_cons (arg, args);
2476 
2477  arg = SCM_BOOL (model->type == GENERAL_LEDGER2 || model->type == INCOME_LEDGER2
2478  || model->type == SEARCH_LEDGER2);
2479  args = scm_cons (arg, args);
2480 
2481  arg = SCM_BOOL (model->style == REG2_STYLE_JOURNAL);
2482  args = scm_cons (arg, args);
2483 
2484  if (!query)
2485  {
2486  query = gnc_ledger_display2_get_query (ledger);
2487  g_return_val_if_fail (query != NULL, -1);
2488  }
2489 
2490  qtype = SWIG_TypeQuery ("_p__QofQuery");
2491  g_return_val_if_fail (qtype, -1);
2492 
2493  arg = SWIG_NewPointerObj (query, qtype, 0);
2494  args = scm_cons (arg, args);
2495  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
2496 
2497 
2498  if (split)
2499  {
2500  qtype = SWIG_TypeQuery ("_p_Split");
2501  g_return_val_if_fail (qtype, -1);
2502  arg = SWIG_NewPointerObj (split, qtype, 0);
2503  }
2504  else
2505  {
2506  arg = SCM_BOOL_F;
2507  }
2508  args = scm_cons (arg, args);
2509  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
2510 
2511 
2512  qtype = SWIG_TypeQuery ("_p_Account");
2513  g_return_val_if_fail (qtype, -1);
2514 
2515  account = gnc_ledger_display2_leader (ledger);
2516  arg = SWIG_NewPointerObj (account, qtype, 0);
2517  args = scm_cons (arg, args);
2518  g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
2519 
2520 
2521  /* Apply the function to the args */
2522  arg = scm_apply (func, args, SCM_EOL);
2523  g_return_val_if_fail (scm_is_exact (arg), -1);
2524 
2525  return scm_to_int (arg);
2526 }
2527 
2528 /*#################################################################################*/
2529 /*#################################################################################*/
2530 
2531 /************************************************************/
2532 /* Command callbacks */
2533 /************************************************************/
2534 
2535 static void
2536 gnc_plugin_page_register2_cmd_print_check (GtkAction *action,
2537  GncPluginPageRegister2 *plugin_page) // this works
2538 {
2540  GncTreeViewSplitReg *view;
2541  GncTreeModelSplitReg *model;
2542  Split * split;
2543  Transaction * trans;
2544  GList * splits = NULL, *item;
2545  GNCLedgerDisplay2Type ledger_type;
2546  Account * account;
2547 
2548  ENTER("(action %p, plugin_page %p)", action, plugin_page);
2549 
2550  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
2551 
2552  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
2553  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2554  model = gnc_ledger_display2_get_split_model_register (priv->ledger);
2555  ledger_type = gnc_ledger_display2_type (priv->ledger);
2556 
2557  if (ledger_type == LD2_SINGLE || ledger_type == LD2_SUBACCOUNT)
2558  {
2559  account = gnc_plugin_page_register2_get_account (plugin_page);
2560  split = gnc_tree_view_split_reg_get_current_split (view);
2561  trans = xaccSplitGetParent (split);
2562 
2563  if (trans == NULL)
2564  {
2565  LEAVE("trans is NULL");
2566  return;
2567  }
2568 
2569  /* See if we were asked to print a blank trans. */
2570  if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
2571  {
2572  LEAVE("Asked to print a blank trans");
2573  return;
2574  }
2575 
2576  /* See if we are being edited in another register */
2577  if (gnc_tree_control_split_reg_trans_test_for_edit (view, trans))
2578  {
2579  LEAVE("trans being edited in another register");
2580  return;
2581  }
2582 
2583  /* Make sure we ask to commit any changes before we proceed */
2584  if (gnc_tree_control_split_reg_trans_open_and_warn (view, trans))
2585  {
2586  LEAVE("trans being edited");
2587  return;
2588  }
2589 
2590  if (split && trans)
2591  {
2592  if (xaccSplitGetAccount(split) == account)
2593  {
2594  splits = g_list_append(splits, split);
2595  gnc_ui_print_check_dialog_create2 (plugin_page, splits);
2596  g_list_free(splits);
2597  }
2598  else
2599  {
2600  /* This split is not for the account shown in this register. Get the
2601  split for that account and use it. */
2602  split = gnc_tree_model_split_reg_trans_get_split_equal_to_ancestor(trans, account);
2603  if (split)
2604  {
2605  splits = g_list_append(splits, split);
2606  gnc_ui_print_check_dialog_create2 (plugin_page, splits);
2607  g_list_free(splits);
2608  }
2609  }
2610  }
2611  }
2612  else if (ledger_type == LD2_GL && model->type == SEARCH_LEDGER2)
2613  {
2614  Account *common_acct = NULL, *account;
2615  splits = qof_query_run (gnc_ledger_display2_get_query (priv->ledger));
2616  /* Make sure each split is from the same account */
2617  for (item = splits; item; item = g_list_next (item))
2618  {
2619  split = (Split *) item->data;
2620  if (common_acct == NULL)
2621  {
2622  common_acct = xaccSplitGetAccount (split);
2623  }
2624  else
2625  {
2626  if (xaccSplitGetAccount (split) != common_acct)
2627  {
2628  GtkWidget *dialog, *window;
2629  gint response;
2630  const gchar *title = _("Print checks from multiple accounts?");
2631  const gchar *message =
2632  _("This search result contains splits from more than one account. "
2633  "Do you want to print the checks even though they are not all "
2634  "from the same account?");
2635  window = gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page));
2636  dialog = gtk_message_dialog_new (GTK_WINDOW (window),
2637  GTK_DIALOG_DESTROY_WITH_PARENT,
2638  GTK_MESSAGE_WARNING,
2639  GTK_BUTTONS_CANCEL,
2640  "%s", title);
2641  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
2642  "%s", message);
2643  gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Print checks"),
2644  GTK_RESPONSE_YES);
2645  response = gnc_dialog_run (GTK_DIALOG (dialog),
2646  GNC_PREF_WARN_CHECKPRINTING_MULTI_ACCT);
2647  gtk_widget_destroy (dialog);
2648  if (response != GTK_RESPONSE_YES)
2649  {
2650  LEAVE("Multiple accounts");
2651  return;
2652  }
2653  break;
2654  }
2655  }
2656  }
2657  gnc_ui_print_check_dialog_create2 (plugin_page, splits);
2658  }
2659  else
2660  {
2661  gnc_error_dialog (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (plugin_page)), "%s",
2662  _("You can only print checks from a bank account register or search results."));
2663  LEAVE("Unsupported ledger type");
2664  return;
2665  }
2666  LEAVE(" ");
2667 }
2668 
2669 static void
2670 gnc_plugin_page_register2_cmd_cut (GtkAction *action,
2671  GncPluginPageRegister2 *page) //this works
2672 {
2674  GncTreeViewSplitReg *view;
2675  GtkWidget *window, *widget;
2676 
2677  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2678 
2679  ENTER("(action %p, page %p)", action, page);
2680  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2681  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2682 
2683  window = gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page));
2684  widget = gtk_window_get_focus (GTK_WINDOW (window));
2685 
2686  DEBUG("(widget name is %s)", gtk_widget_get_name (widget));
2687 
2688  if (GTK_IS_ENTRY(widget))
2689  g_signal_emit_by_name(widget, "cut-clipboard", NULL);
2690 
2691  LEAVE("");
2692 }
2693 
2694 static void
2695 gnc_plugin_page_register2_cmd_copy (GtkAction *action,
2696  GncPluginPageRegister2 *page) //this works
2697 {
2699  GncTreeViewSplitReg *view;
2700  GtkWidget *window, *widget;
2701 
2702  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2703 
2704  ENTER("(action %p, page %p)", action, page);
2705  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2706  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2707 
2708  window = gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page));
2709  widget = gtk_window_get_focus (GTK_WINDOW (window));
2710 
2711  DEBUG("(widget name is %s)", gtk_widget_get_name (widget));
2712 
2713  if (GTK_IS_ENTRY(widget))
2714  g_signal_emit_by_name (widget, "copy-clipboard", NULL);
2715 
2716  LEAVE("");
2717 }
2718 
2719 static void
2720 gnc_plugin_page_register2_cmd_paste (GtkAction *action,
2721  GncPluginPageRegister2 *page) //this works
2722 {
2724  GncTreeViewSplitReg *view;
2725  GtkWidget *window, *widget;
2726 
2727  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2728 
2729  ENTER("(action %p, page %p)", action, page);
2730  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2731  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2732 
2733  window = gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page));
2734  widget = gtk_window_get_focus (GTK_WINDOW (window));
2735 
2736  DEBUG("(widget name is %s)", gtk_widget_get_name (widget));
2737 
2738  if (GTK_IS_ENTRY(widget))
2739  g_signal_emit_by_name (widget, "paste-clipboard", NULL);
2740 
2741  LEAVE("");
2742 }
2743 
2744 static void
2745 gnc_plugin_page_register2_cmd_edit_account (GtkAction *action,
2746  GncPluginPageRegister2 *page) //this works
2747 {
2748  Account *account;
2749 
2750  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
2751 
2752  ENTER("(action %p, page %p)", action, page);
2753  account = gnc_plugin_page_register2_get_account (page);
2754  if (account)
2755  gnc_ui_edit_account_window (account);
2756  LEAVE(" ");
2757 }
2758 
2759 static void
2760 gnc_plugin_page_register2_cmd_find_transactions (GtkAction *action,
2761  GncPluginPageRegister2 *page) // this works
2762 {
2764 
2765  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
2766 
2767  ENTER("(action %p, page %p)", action, page);
2768  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
2769 
2770  gnc_ui_find_transactions_dialog_create2 (priv->ledger);
2771  LEAVE(" ");
2772 }
2773 
2774 static void
2775 gnc_plugin_page_register2_cmd_cut_transaction (GtkAction *action,
2776  GncPluginPageRegister2 *page) // this works
2777 {
2779  GncTreeViewSplitReg *view;
2780 
2781  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
2782 
2783  ENTER("(action %p, page %p)", action, page);
2784  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
2785  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2786  gnc_tree_control_split_reg_cut_trans (view);
2787 
2788  LEAVE(" ");
2789 }
2790 
2791 static void
2792 gnc_plugin_page_register2_cmd_copy_transaction (GtkAction *action,
2793  GncPluginPageRegister2 *page) // this works
2794 {
2796  GncTreeViewSplitReg *view;
2797 
2798  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
2799 
2800  ENTER("(action %p, page %p)", action, page);
2801  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
2802  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2803  gnc_tree_control_split_reg_copy_trans (view);
2804  LEAVE(" ");
2805 }
2806 
2807 static void
2808 gnc_plugin_page_register2_cmd_paste_transaction (GtkAction *action,
2809  GncPluginPageRegister2 *page) //this works
2810 {
2812  GncTreeViewSplitReg *view;
2813 
2814  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
2815 
2816  ENTER("(action %p, page %p)", action, page);
2817  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
2818  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2819  gnc_tree_control_split_reg_paste_trans (view);
2820  LEAVE(" ");
2821 }
2822 
2823 static void
2824 gnc_plugin_page_register2_cmd_void_transaction (GtkAction *action,
2825  GncPluginPageRegister2 *page) //this works
2826 {
2828  GtkWidget *dialog, *entry;
2829  GncTreeViewSplitReg *view;
2830  Transaction *trans;
2831  GtkBuilder *builder;
2832  const char *reason;
2833  gint result;
2834 
2835  ENTER("(action %p, page %p)", action, page);
2836 
2837  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2838 
2839  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2840  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2841  trans = gnc_tree_view_split_reg_get_current_trans (view);
2842  if (trans == NULL)
2843  {
2844  LEAVE("trans is NULL");
2845  return;
2846  }
2847  if (xaccTransHasSplitsInState (trans, VREC))
2848  {
2849  LEAVE("trans has split in VREC state");
2850  return;
2851  }
2853  {
2854  gnc_error_dialog (NULL, "%s", _("You cannot void a transaction with reconciled or cleared splits."));
2855  LEAVE("trans with reconciled splits");
2856  return;
2857  }
2858 
2859  if (!gnc_plugin_page_register2_finish_pending (GNC_PLUGIN_PAGE (page)))
2860  {
2861  LEAVE("finish pending");
2862  return;
2863  }
2864 
2865  builder = gtk_builder_new();
2866  gnc_builder_add_from_file (builder , "gnc-plugin-page-register2.glade", "Void Transaction");
2867  dialog = GTK_WIDGET (gtk_builder_get_object (builder, "Void Transaction"));
2868  entry = GTK_WIDGET (gtk_builder_get_object (builder, "reason"));
2869 
2870  result = gtk_dialog_run (GTK_DIALOG (dialog));
2871  if (result == GTK_RESPONSE_OK)
2872  {
2873  reason = gtk_entry_get_text (GTK_ENTRY (entry));
2874  if (reason == NULL)
2875  reason = "";
2876  gnc_tree_control_split_reg_void_current_trans (view, reason);
2877  }
2878 
2879  /* All done. Get rid of it. */
2880  gtk_widget_destroy (dialog);
2881  g_object_unref (G_OBJECT(builder));
2882  LEAVE(" ");
2883 }
2884 
2885 static void
2886 gnc_plugin_page_register2_cmd_unvoid_transaction (GtkAction *action,
2887  GncPluginPageRegister2 *page) //this works
2888 {
2890  GncTreeViewSplitReg *view;
2891  Transaction *trans;
2892 
2893  ENTER("(action %p, page %p)", action, page);
2894 
2895  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2896 
2897  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2898  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2899  trans = gnc_tree_view_split_reg_get_current_trans (view);
2900  if (!xaccTransHasSplitsInState (trans, VREC))
2901  {
2902  LEAVE("trans has split in VREC state");
2903  return;
2904  }
2905  gnc_tree_control_split_reg_unvoid_current_trans (view);
2906  LEAVE(" ");
2907 }
2908 
2909 static void
2910 gnc_plugin_page_register2_cmd_reverse_transaction (GtkAction *action,
2911  GncPluginPageRegister2 *page) //this works
2912 {
2914  GncTreeViewSplitReg *view;
2915 
2916  ENTER("(action %p, page %p)", action, page);
2917 
2918  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2919 
2920  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2921  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2922 
2923  gnc_tree_control_split_reg_reverse_current (view);
2924  LEAVE(" ");
2925 }
2926 
2927 static void
2928 gnc_plugin_page_register2_cmd_entryUp (GtkAction *action,
2929  GncPluginPageRegister2 *plugin_page)
2930 {
2932  GncTreeViewSplitReg *view;
2933  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
2934 
2935  ENTER("(action %p, plugin_page %p)", action, plugin_page);
2936  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
2937  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2938  g_return_if_fail(view);
2939  gnc_tree_control_split_reg_move_current_entry_updown(view, TRUE);
2940  LEAVE(" ");
2941 }
2942 
2943 static void
2944 gnc_plugin_page_register2_cmd_entryDown (GtkAction *action,
2945  GncPluginPageRegister2 *plugin_page)
2946 {
2948  GncTreeViewSplitReg *view;
2949  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
2950 
2951  ENTER("(action %p, plugin_page %p)", action, plugin_page);
2952  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
2953  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
2954  g_return_if_fail(view);
2955  gnc_tree_control_split_reg_move_current_entry_updown(view, FALSE);
2956  LEAVE(" ");
2957 }
2958 
2959 
2960 /*#################################################################################*/
2961 /*#################################################################################*/
2962 
2963 static void
2964 gnc_plugin_page_register2_cmd_view_filter_by (GtkAction *action,
2965  GncPluginPageRegister2 *page) //this works
2966 {
2968  GNCLedgerDisplay2Type ledger_type;
2969  GtkWidget *dialog, *toggle, *button, *start_date, *end_date, *table, *hbox;
2970  time64 start_time, end_time, time_val;
2971  GtkBuilder *builder;
2972  gboolean sensitive, value;
2973  Query *query;
2974  GList *split_list;
2975  gchar *title;
2976  int i;
2977 
2978  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
2979  ENTER("(action %p, page %p)", action, page);
2980 
2981  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
2982  if (priv->fd.dialog)
2983  {
2984  gtk_window_present (GTK_WINDOW (priv->fd.dialog));
2985  LEAVE("existing dialog");
2986  return;
2987  }
2988 
2989  /* Create the dialog */
2990  builder = gtk_builder_new();
2991  gnc_builder_add_from_file (builder, "gnc-plugin-page-register2.glade", "Filter By");
2992  dialog = GTK_WIDGET (gtk_builder_get_object (builder, "Filter By"));
2993  priv->fd.dialog = dialog;
2994  gtk_window_set_transient_for (GTK_WINDOW (dialog),
2995  gnc_window_get_gtk_window (GNC_WINDOW (GNC_PLUGIN_PAGE (page)->window)));
2996 
2997  /* Translators: The %s is the name of the plugin page */
2998  title = g_strdup_printf (_("Filter %s by..."),
2999  gnc_plugin_page_get_page_name (GNC_PLUGIN_PAGE (page)));
3000  gtk_window_set_title (GTK_WINDOW (dialog), title);
3001  g_free(title);
3002 
3003  /* Set the check buttons for the current status */
3004  for (i = 0; status_actions[i].action_name; i++)
3005  {
3006  toggle = GTK_WIDGET (gtk_builder_get_object (builder, status_actions[i].action_name));
3007  value = priv->fd.cleared_match & status_actions[i].value;
3008  status_actions[i].widget = toggle;
3009  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), value);
3010  }
3011  priv->fd.original_cleared_match = priv->fd.cleared_match;
3012 
3013  button = GTK_WIDGET (gtk_builder_get_object (builder, "filter_save"));
3014  if (priv->fd.save_filter == TRUE)
3015  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
3016 
3017  // General Ledgers can not save filters so disable button.
3018  ledger_type = gnc_ledger_display2_type (priv->ledger);
3019  if (ledger_type == LD2_GL)
3020  gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
3021 
3022  /* Set the date info */
3023  button = GTK_WIDGET (gtk_builder_get_object (builder, "filter_show_range"));
3024  query = gnc_ledger_display2_get_query (priv->ledger);
3025  xaccQueryGetDateMatchTT (query, &start_time, &end_time);
3026  priv->fd.original_start_time = start_time;
3027  priv->fd.start_time = start_time;
3028  priv->fd.original_end_time = end_time;
3029  priv->fd.end_time = end_time;
3030 
3031  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), start_time || end_time);
3032  table = GTK_WIDGET (gtk_builder_get_object (builder, "select_range_table"));
3033  priv->fd.table = table;
3034  gtk_widget_set_sensitive (GTK_WIDGET (table), start_time || end_time);
3035 
3036  priv->fd.start_date_choose = GTK_WIDGET (gtk_builder_get_object (builder, "start_date_choose"));
3037  priv->fd.start_date_today = GTK_WIDGET (gtk_builder_get_object (builder, "start_date_today"));
3038  priv->fd.end_date_choose = GTK_WIDGET (gtk_builder_get_object (builder, "end_date_choose"));
3039  priv->fd.end_date_today = GTK_WIDGET (gtk_builder_get_object (builder, "end_date_today"));
3040 
3041  {
3042  /* Start date info */
3043  if (start_time == 0)
3044  {
3045  button = GTK_WIDGET (gtk_builder_get_object (builder, "start_date_earliest"));
3046  time_val = xaccQueryGetEarliestDateFound (query);
3047  sensitive = FALSE;
3048  }
3049  else
3050  {
3051  time_val = start_time;
3052  if ((start_time >= gnc_time64_get_today_start()) &&
3053  (start_time <= gnc_time64_get_today_end()))
3054  {
3055  button = priv->fd.start_date_today;
3056  sensitive = FALSE;
3057  }
3058  else
3059  {
3060  button = priv->fd.start_date_choose;
3061  sensitive = TRUE;
3062  }
3063  }
3064  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
3065  priv->fd.start_date = gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE);
3066  hbox = GTK_WIDGET (gtk_builder_get_object (builder, "start_date_hbox"));
3067  gtk_box_pack_start (GTK_BOX (hbox), priv->fd.start_date, TRUE, TRUE, 0);
3068  gtk_widget_show (priv->fd.start_date);
3069  gtk_widget_set_sensitive (GTK_WIDGET (priv->fd.start_date), sensitive);
3070  gnc_date_edit_set_time (GNC_DATE_EDIT (priv->fd.start_date), time_val);
3071  g_signal_connect (G_OBJECT (priv->fd.start_date), "date-changed",
3072  G_CALLBACK (gnc_plugin_page_register2_filter_gde_changed_cb),
3073  page);
3074  }
3075 
3076  {
3077  /* End date info */
3078  if (end_time == 0)
3079  {
3080  button = GTK_WIDGET (gtk_builder_get_object (builder, "end_date_latest"));
3081  time_val = xaccQueryGetLatestDateFound (query);
3082  sensitive = FALSE;
3083  }
3084  else
3085  {
3086  time_val = end_time;
3087  if ((end_time >= gnc_time64_get_today_start()) &&
3088  (end_time <= gnc_time64_get_today_end()))
3089  {
3090  button = priv->fd.end_date_today;
3091  sensitive = FALSE;
3092  }
3093  else
3094  {
3095  button = priv->fd.end_date_choose;
3096  sensitive = TRUE;
3097  }
3098  }
3099  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
3100  priv->fd.end_date = gnc_date_edit_new (gnc_time (NULL), FALSE, FALSE);
3101  hbox = GTK_WIDGET (gtk_builder_get_object (builder, "end_date_hbox"));
3102  gtk_box_pack_start (GTK_BOX (hbox), priv->fd.end_date, TRUE, TRUE, 0);
3103  gtk_widget_show (priv->fd.end_date);
3104  gtk_widget_set_sensitive (GTK_WIDGET (priv->fd.end_date), sensitive);
3105  gnc_date_edit_set_time (GNC_DATE_EDIT (priv->fd.end_date), time_val);
3106  g_signal_connect (G_OBJECT (priv->fd.end_date), "date-changed",
3107  G_CALLBACK (gnc_plugin_page_register2_filter_gde_changed_cb),
3108  page);
3109  }
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_all (dialog);
3116  g_object_unref (G_OBJECT (builder));
3117  LEAVE(" ");
3118 }
3119 
3120 
3121 static void
3122 gnc_plugin_page_register2_cmd_reload (GtkAction *action, GncPluginPageRegister2 *plugin_page) //this works
3123 {
3125  GncTreeViewSplitReg *view;
3126 
3127  Transaction *trans;
3128 
3129  ENTER("(action %p, page %p)", action, plugin_page);
3130 
3131  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3132 
3133  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3134 
3135  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3136 
3137  trans = gnc_tree_view_split_reg_get_current_trans (view);
3138 
3139  /* Make sure we ask to commit any changes before we proceed */
3140  if (gnc_tree_control_split_reg_trans_open_and_warn (view, trans))
3141  {
3142  LEAVE("trans being edited");
3143  return;
3144  }
3145 
3146  /* give gtk+ a chance to handle pending events */
3147  while (gtk_events_pending ())
3148  gtk_main_iteration ();
3149 
3150  gnc_ledger_display2_refresh (priv->ledger);
3151 
3152  LEAVE(" ");
3153 }
3154 
3155 /*#################################################################################*/
3156 /*#################################################################################*/
3157 
3158 static void
3159 gnc_plugin_page_register2_cmd_style_changed (GtkAction *action,
3160  GtkRadioAction *current,
3161  GncPluginPageRegister2 *plugin_page) //this works
3162 {
3164  SplitRegisterStyle2 value;
3165 
3166  ENTER("(action %p, radio action %p, plugin_page %p)",
3167  action, current, plugin_page);
3168 
3169  g_return_if_fail (GTK_IS_ACTION (action));
3170  g_return_if_fail (GTK_IS_RADIO_ACTION (current));
3171  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3172 
3173  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3174  value = gtk_radio_action_get_current_value (current);
3175  gnc_split_reg2_change_style (priv->gsr, value);
3176 
3177  gnc_plugin_page_register2_ui_update (NULL, plugin_page);
3178  LEAVE(" ");
3179 }
3180 
3181 static void
3182 gnc_plugin_page_register2_cmd_style_double_line (GtkToggleAction *action,
3183  GncPluginPageRegister2 *plugin_page) // this works
3184 {
3186  GncTreeModelSplitReg *model;
3187  GncTreeViewSplitReg *view;
3188  gboolean use_double_line;
3189 
3190  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3191 
3192  g_return_if_fail (GTK_IS_ACTION (action));
3193  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3194 
3195  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3196  model = gnc_ledger_display2_get_split_model_register (priv->ledger);
3197 
3198  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3199 
3200  use_double_line = gtk_toggle_action_get_active (action);
3201  if (use_double_line != model->use_double_line)
3202  {
3203  gnc_tree_model_split_reg_config (model, model->type, model->style, use_double_line);
3204 
3205  // This will re-display the view.
3206  gnc_tree_view_split_reg_set_format (view);
3207  gnc_ledger_display2_refresh (priv->ledger);
3208  }
3209  LEAVE(" ");
3210 }
3211 
3212 static void
3213 gnc_plugin_page_register2_cmd_style_extra_dates (GtkToggleAction *action,
3214  GncPluginPageRegister2 *plugin_page) // this works
3215 {
3217  GncTreeModelSplitReg *model;
3218  GncTreeViewSplitReg *view;
3219  gboolean show_extra_dates;
3220 
3221  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3222 
3223  g_return_if_fail (GTK_IS_ACTION (action));
3224  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3225 
3226  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3227  model = gnc_ledger_display2_get_split_model_register (priv->ledger);
3228 
3229  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3230 
3231  show_extra_dates = gtk_toggle_action_get_active (action);
3232  if (show_extra_dates != view->show_extra_dates)
3233  {
3234  view->show_extra_dates = show_extra_dates;
3235  gnc_ledger_display2_refresh (priv->ledger);
3236  }
3237  LEAVE(" ");
3238 }
3239 
3240 static void
3241 gnc_plugin_page_register2_cmd_transfer (GtkAction *action,
3242  GncPluginPageRegister2 *page) //this works
3243 {
3244  Account *account;
3245  GncWindow *gnc_window;
3246  GtkWidget *window;
3247 
3248  ENTER("(action %p, plugin_page %p)", action, page);
3249 
3250  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
3251 
3252  account = gnc_plugin_page_register2_get_account (page);
3253  gnc_window = GNC_WINDOW (GNC_PLUGIN_PAGE (page)->window);
3254  window = GTK_WIDGET (gnc_window_get_gtk_window (gnc_window));
3255  gnc_xfer_dialog (window, account);
3256  LEAVE(" ");
3257 }
3258 
3259 static void
3260 gnc_plugin_page_register2_cmd_reconcile (GtkAction *action,
3261  GncPluginPageRegister2 *page) // this works
3262 {
3264  GncTreeViewSplitReg *view;
3265  Account *account;
3266  Transaction *trans;
3267  GtkWindow *window;
3268  RecnWindow2 * recnData;
3269 
3270  ENTER("(action %p, plugin_page %p)", action, page);
3271 
3272  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
3273 
3274  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
3275  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3276 
3277  account = gnc_plugin_page_register2_get_account (page);
3278 
3279  trans = gnc_tree_view_split_reg_get_current_trans (view);
3280 
3281  /* Make sure we ask to commit any changes before we proceed */
3282  if (gnc_tree_control_split_reg_trans_open_and_warn (view, trans))
3283  {
3284  LEAVE("trans being edited");
3285  return;
3286  }
3287 
3288  window = gnc_window_get_gtk_window (GNC_WINDOW (GNC_PLUGIN_PAGE (page)->window));
3289  recnData = recnWindow2 (GTK_WIDGET (window), account);
3290  gnc_ui_reconcile_window2_raise (recnData);
3291  LEAVE(" ");
3292 }
3293 
3294 static void
3295 gnc_plugin_page_register2_cmd_autoclear (GtkAction *action,
3296  GncPluginPageRegister2 *page)
3297 {
3298  Account *account;
3299  GtkWindow *window;
3300  AutoClearWindow * autoClearData;
3301 
3302  ENTER("(action %p, plugin_page %p)", action, page);
3303 
3304  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
3305 
3306  account = gnc_plugin_page_register2_get_account (page);
3307 
3308  window = gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window));
3309  autoClearData = autoClearWindow (GTK_WIDGET(window), account);
3310  gnc_ui_autoclear_window_raise (autoClearData);
3311  LEAVE(" ");
3312 }
3313 
3314 static void
3315 gnc_plugin_page_register2_cmd_stock_split (GtkAction *action,
3316  GncPluginPageRegister2 *page) // this works
3317 {
3318  Account *account;
3319 
3320  ENTER("(action %p, plugin_page %p)", action, page);
3321 
3322  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
3323 
3324  account = gnc_plugin_page_register2_get_account (page);
3325  gnc_stock_split_dialog (NULL, account);
3326  LEAVE(" ");
3327 }
3328 
3329 static void
3330 gnc_plugin_page_register2_cmd_lots (GtkAction *action,
3331  GncPluginPageRegister2 *page) // this works
3332 {
3333  Account *account;
3334 
3335  ENTER("(action %p, plugin_page %p)", action, page);
3336 
3337  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
3338 
3339  account = gnc_plugin_page_register2_get_account (page);
3340  gnc_lot_viewer_dialog (account);
3341  LEAVE(" ");
3342 }
3343 
3344 static void
3345 gnc_plugin_page_register2_cmd_enter_transaction (GtkAction *action,
3346  GncPluginPageRegister2 *plugin_page) //this works
3347 {
3349  GncTreeViewSplitReg *view;
3350 
3351  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3352 
3353  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3354 
3355  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3356  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3357  gnc_tree_control_split_reg_enter (view);
3358  LEAVE(" ");
3359 }
3360 
3361 static void
3362 gnc_plugin_page_register2_cmd_cancel_transaction (GtkAction *action,
3363  GncPluginPageRegister2 *plugin_page) //this works
3364 {
3366  GncTreeViewSplitReg *view;
3367 
3368  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3369 
3370  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3371 
3372  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3373  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3374  gnc_tree_control_split_reg_cancel_edit (view, FALSE);
3375  LEAVE(" ");
3376 }
3377 
3378 static void
3379 gnc_plugin_page_register2_cmd_delete_transaction (GtkAction *action,
3380  GncPluginPageRegister2 *plugin_page) //this works
3381 {
3383  GncTreeViewSplitReg *view;
3384 
3385  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3386 
3387  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3388 
3389  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3390  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3391  gnc_tree_control_split_reg_delete (view, NULL);
3392  LEAVE(" ");
3393 
3394 }
3395 
3396 static void
3397 gnc_plugin_page_register2_cmd_blank_transaction (GtkAction *action,
3398  GncPluginPageRegister2 *plugin_page) //this works
3399 {
3401  GncTreeViewSplitReg *view;
3402 
3403  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3404 
3405  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3406 
3407  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3408  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3409  gnc_tree_control_split_reg_jump_to_blank (view);
3410  LEAVE(" ");
3411 }
3412 
3413 static void
3414 gnc_plugin_page_register2_cmd_duplicate_transaction (GtkAction *action,
3415  GncPluginPageRegister2 *plugin_page) //this works
3416 {
3418  GncTreeViewSplitReg *view;
3419 
3420  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3421 
3422  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3423 
3424  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3425  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3426  gnc_tree_control_split_reg_duplicate_current (view);
3427  LEAVE(" ");
3428 }
3429 
3430 static void
3431 gnc_plugin_page_register2_cmd_reinitialize_transaction (GtkAction *action,
3432  GncPluginPageRegister2 *plugin_page) //this works
3433 {
3435  GncTreeViewSplitReg *view;
3436 
3437  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3438 
3439  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3440 
3441  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3442  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3443  gnc_tree_control_split_reg_reinit (view, NULL);
3444  LEAVE(" ");
3445 }
3446 
3447 static void
3448 gnc_plugin_page_register2_cmd_expand_transaction (GtkToggleAction *action,
3449  GncPluginPageRegister2 *plugin_page) // this works
3450 {
3452  GncTreeViewSplitReg *view;
3453  gboolean expand;
3454 
3455  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3456 
3457  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3458 
3459  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3460  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3461  expand = gtk_toggle_action_get_active (action);
3462  if (expand)
3463  gnc_tree_view_split_reg_expand_trans (view, NULL);
3464  else
3465  gnc_tree_view_split_reg_collapse_trans (view, NULL);
3466  LEAVE(" ");
3467 }
3468 
3469 static void
3470 gnc_plugin_page_register2_cmd_exchange_rate (GtkAction *action,
3471  GncPluginPageRegister2 *plugin_page) //this works
3472 {
3474  GncTreeViewSplitReg *view;
3475 
3476  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3477 
3478  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3479 
3480  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3481  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3482  gnc_tree_control_split_reg_exchange_rate (view);
3483  LEAVE(" ");
3484 }
3485 
3486 static void
3487 gnc_plugin_page_register2_cmd_jump (GtkAction *action,
3488  GncPluginPageRegister2 *plugin_page) //this works
3489 {
3491  GncPluginPage *new_page;
3492  GncPluginPageRegister2 *new_reg_page;
3493  GtkWidget *window;
3494  GNCLedgerDisplay2 *ld;
3495  GncTreeViewSplitReg *view, *new_view;
3496  GncTreeModelSplitReg *new_model;
3497  Account *account;
3498  Account *leader;
3499  Split *split;
3500  RowDepth depth;
3501 
3502  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3503 
3504  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3505 
3506  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3507  window = GNC_PLUGIN_PAGE (plugin_page)->window;
3508  if (window == NULL)
3509  {
3510  LEAVE("no window");
3511  return;
3512  }
3513 
3514  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3515  split = gnc_tree_view_split_reg_get_current_split (view);
3516  if (split == NULL)
3517  {
3518  split = gnc_tree_control_split_reg_get_current_trans_split (view);
3519  if (split == NULL)
3520  {
3521  LEAVE("split is NULL");
3522  return;
3523  }
3524  }
3525 
3526  if (!gnc_tree_view_split_reg_trans_expanded (view, NULL))
3527  {
3528  Transaction *trans = xaccSplitGetParent (split);
3529  if (xaccTransCountSplits (trans) > 2)
3530  {
3531  LEAVE("more than 2 splits");
3532  return;
3533  }
3534  }
3535 
3536  depth = gnc_tree_view_reg_get_selected_row_depth (view);
3537  if (gnc_tree_view_split_reg_trans_expanded (view, NULL) && depth != SPLIT3)
3538  {
3539  LEAVE("expanded but no split selected");
3540  return;
3541  }
3542 
3543  account = xaccSplitGetAccount (split);
3544  if (account == NULL)
3545  {
3546  LEAVE("account is NULL");
3547  return;
3548  }
3549 
3550  leader = gnc_ledger_display2_leader (priv->ledger);
3551  if (account == leader)
3552  {
3553  split = xaccSplitGetOtherSplit (split);
3554  if (split == NULL)
3555  {
3556  LEAVE("no other split");
3557  return;
3558  }
3559 
3560  account = xaccSplitGetAccount (split);
3561  if (account == NULL)
3562  {
3563  LEAVE("no other account");
3564  return;
3565  }
3566 
3567  if (account == leader)
3568  {
3569  LEAVE("register open for account");
3570  return;
3571  }
3572  }
3573 
3574  new_page = gnc_plugin_page_register2_new (account, FALSE);
3575  if (new_page == NULL)
3576  {
3577  LEAVE("couldn't create new page");
3578  return;
3579  }
3580 
3581  gnc_main_window_open_page (GNC_MAIN_WINDOW (window), new_page);
3582 
3583  ld = gnc_plugin_page_register2_get_ledger (new_page);
3584  new_view = gnc_ledger_display2_get_split_view_register (ld);
3585  new_model = gnc_ledger_display2_get_split_model_register (ld);
3586 
3587  new_model->current_trans = xaccSplitGetParent (split);
3588 
3589  if (!gnc_tree_model_split_reg_trans_is_in_view (new_model, xaccSplitGetParent (split)))
3590  g_signal_emit_by_name (new_model, "refresh_trans");
3591 
3592  gnc_tree_control_split_reg_jump_to (new_view, NULL, split, FALSE);
3593  LEAVE(" ");
3594 }
3595 
3596 
3602 static void
3603 gnc_plugin_page_register2_cmd_schedule (GtkAction *action,
3604  GncPluginPageRegister2 *plugin_page) // this works
3605 {
3607  GncTreeViewSplitReg *view;
3608  Transaction *trans;
3609 
3610  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3611 
3612  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
3613 
3614  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
3615  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3616 
3617  trans = gnc_tree_view_split_reg_get_current_trans (view);
3618 
3619  if (trans == NULL)
3620  {
3621  LEAVE("trans is NULL");
3622  return;
3623  }
3624 
3625  /* See if we were asked to schedule a blank trans. */
3626  if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
3627  {
3628  LEAVE("Asked to schedule a blank trans");
3629  return;
3630  }
3631 
3632  /* See if we are being edited in another register */
3633  if (gnc_tree_control_split_reg_trans_test_for_edit (view, trans))
3634  {
3635  LEAVE("trans being edited in another register");
3636  return;
3637  }
3638 
3639  /* Make sure we ask to commit any changes before we proceed */
3640  if (gnc_tree_control_split_reg_trans_open_and_warn (view, trans))
3641  {
3642  LEAVE("trans being edited");
3643  return;
3644  }
3645 
3646  /* If the transaction has a sched-xact KVP frame, then go to the editor
3647  * for the existing SX; otherwise, do the sx-from-trans dialog. */
3648  {
3649  GncGUID *fromSXId = NULL;
3650  SchedXaction *theSX = NULL;
3651  GList *sxElts;
3652  qof_instance_get (QOF_INSTANCE (trans),
3653  "from-sched-xaction", &fromSXId,
3654  NULL);
3655 
3656  /* Get the correct SX */
3657  for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
3658  (!theSX) && sxElts;
3659  sxElts = sxElts->next )
3660  {
3661  SchedXaction *sx = (SchedXaction*)sxElts->data;
3662  theSX =
3663  ((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
3664  ? sx : NULL);
3665  }
3666 
3667  if (theSX)
3668  {
3669  gnc_ui_scheduled_xaction_editor_dialog_create2 (theSX, FALSE);
3670  LEAVE(" ");
3671  return;
3672  }
3673  }
3674  gnc_sx_create_from_trans (trans);
3675  LEAVE(" ");
3676 }
3677 
3678 static void
3679 gnc_plugin_page_register2_cmd_scrub_current (GtkAction *action,
3680  GncPluginPageRegister2 *plugin_page) // this works
3681 {
3683  GncTreeViewSplitReg *view;
3684  Query *query;
3685  Account *root;
3686  Transaction *trans;
3687 
3688  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3689 
3690  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3691 
3692  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3693  query = gnc_ledger_display2_get_query (priv->ledger);
3694  if (query == NULL)
3695  {
3696  LEAVE("no query found");
3697  return;
3698  }
3699 
3700  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3701  trans = gnc_tree_view_split_reg_get_current_trans (view);
3702  if (trans == NULL)
3703  {
3704  LEAVE("no trans found");
3705  return;
3706  }
3707 
3708  gnc_suspend_gui_refresh();
3709  root = gnc_get_current_root_account ();
3710  xaccTransScrubOrphans (trans);
3711  xaccTransScrubImbalance (trans, root, NULL);
3712  gnc_resume_gui_refresh ();
3713  LEAVE(" ");
3714 }
3715 
3716 static void
3717 gnc_plugin_page_register2_cmd_scrub_all (GtkAction *action,
3718  GncPluginPageRegister2 *plugin_page) // this works
3719 {
3721  Query *query;
3722  Account *root;
3723  Transaction *trans;
3724  Split *split;
3725  GList *node;
3726 
3727  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
3728 
3729  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3730 
3731  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
3732  query = gnc_ledger_display2_get_query( priv->ledger );
3733  if (!query)
3734  {
3735  LEAVE("no query found");
3736  return;
3737  }
3738 
3739  gnc_suspend_gui_refresh();
3740  root = gnc_get_current_root_account();
3741 
3742  for (node = qof_query_run(query); node; node = node->next)
3743  {
3744  split = node->data;
3745  trans = xaccSplitGetParent(split);
3746 
3747  xaccTransScrubOrphans(trans);
3748  xaccTransScrubImbalance(trans, root, NULL);
3749  }
3750 
3751  gnc_resume_gui_refresh();
3752  LEAVE(" ");
3753 }
3754 
3755 static void
3756 gnc_plugin_page_register2_cmd_account_report (GtkAction *action,
3757  GncPluginPageRegister2 *plugin_page) // this works
3758 {
3760  GncMainWindow *window;
3761  int id;
3762 
3763  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3764 
3765  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
3766 
3767  window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
3768  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
3769  id = report_helper (priv->ledger, NULL, NULL);
3770  if (id >= 0)
3771  gnc_main_window_open_report(id, window);
3772  LEAVE(" ");
3773 }
3774 
3775 static void
3776 gnc_plugin_page_register2_cmd_transaction_report (GtkAction *action,
3777  GncPluginPageRegister2 *plugin_page) // this works
3778 {
3780  GncMainWindow *window;
3781  GncTreeViewSplitReg *view;
3782  Split *split;
3783  Query *query;
3784  int id;
3785 
3786  ENTER("(action %p, plugin_page %p)", action, plugin_page);
3787 
3788  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
3789 
3790  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
3791  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3792 
3793  split = gnc_tree_view_split_reg_get_current_split (view);
3794  if (!split)
3795  {
3796  LEAVE("split is NULL");
3797  return;
3798  }
3799 
3800  query = qof_query_create_for(GNC_ID_SPLIT);
3801 
3802  qof_query_set_book (query, gnc_get_current_book ());
3803 
3804  xaccQueryAddGUIDMatch (query, xaccSplitGetGUID (split),
3805  GNC_ID_SPLIT, QOF_QUERY_AND);
3806 
3807  window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
3808  id = report_helper (priv->ledger, split, query);
3809  if (id >= 0)
3810  gnc_main_window_open_report(id, window);
3811  LEAVE(" ");
3812 }
3813 
3814 /*#################################################################################*/
3815 /*#################################################################################*/
3816 
3817 /************************************************************/
3818 /* Auxiliary functions */
3819 /************************************************************/
3820 
3821 void
3823  gint lines_default,
3824  gboolean read_only)
3825 {
3826  GncPluginPageRegister2 *page;
3828 
3829  g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
3830 
3831  page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
3832  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
3833  priv->lines_default = lines_default;
3834  priv->read_only = read_only;
3835 }
3836 
3837 GNCSplitReg2 *
3839 {
3840  GncPluginPageRegister2 *page;
3842 
3843  g_return_val_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page), NULL);
3844 
3845  page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
3846  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
3847 
3848  return priv->gsr;
3849 }
3850 
3851 
3854 {
3855  GncPluginPageRegister2 *page;
3857 
3858  g_return_val_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page), NULL);
3859 
3860  page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
3861  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
3862 
3863  return priv->ledger;
3864 }
3865 static void
3866 gnc_plugin_page_help_changed_cb (GNCSplitReg2 *gsr, GncPluginPageRegister2 *register_page) //this works
3867 {
3869  GncTreeViewSplitReg *view;
3870  GncWindow *window;
3871  char *help;
3872 
3873  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (register_page));
3874 
3875  window = GNC_WINDOW (GNC_PLUGIN_PAGE (register_page)->window);
3876  if (!window)
3877  {
3878  // This routine can be called before the page is added to a
3879  // window.
3880  return;
3881  }
3882  /* Get the text from the view */
3883  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (register_page);
3884  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3885  help = g_strdup (view->help_text);
3886  gnc_window_set_status (window, GNC_PLUGIN_PAGE (register_page), help);
3887  g_free (help);
3888 }
3889 
3890 static void
3891 gnc_plugin_page_register2_refresh_cb (GHashTable *changes, gpointer user_data) //this works
3892 {
3893  GncPluginPageRegister2 *page = user_data;
3895  GncTreeViewSplitReg *view;
3896 
3897  g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
3898  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
3899  view = gnc_ledger_display2_get_split_view_register (priv->ledger);
3900 
3901  if (changes)
3902  {
3903  const EventInfo* ei;
3904 
3905  ei = gnc_gui_get_entity_events (changes, &priv->key);
3906  if (ei)
3907  {
3908  if (ei->event_mask & QOF_EVENT_DESTROY)
3909  {
3910  /* Account has been deleted, close plugin page
3911  * but prevent that action from writing state information
3912  * for this deleted account
3913  */
3914  g_object_set (G_OBJECT (view), "state-section", NULL, NULL);
3915  gnc_main_window_close_page (GNC_PLUGIN_PAGE (page));
3916  return;
3917  }
3918  if (ei->event_mask & QOF_EVENT_MODIFY)
3919  {
3920  }
3921  }
3922  }
3923  else
3924  {
3925  /* Force updates */
3926  gnc_tree_view_split_reg_refresh_from_prefs (view);
3927  }
3928  gnc_plugin_page_register2_ui_update (NULL, page);
3929 }
3930 
3931 static void
3932 gnc_plugin_page_register2_close_cb (gpointer user_data)
3933 {
3934  GncPluginPage *plugin_page = GNC_PLUGIN_PAGE(user_data);
3935  gnc_main_window_close_page (plugin_page);
3936 }
3937 
3946 static void
3947 gppr_account_destroy_cb (Account *account)
3948 {
3949  GncPluginPageRegister2 *page;
3951  GNCLedgerDisplay2Type ledger_type;
3952  const GncGUID *acct_guid;
3953  const GList *citem;
3954  GList *item, *kill = NULL;
3955 
3956  acct_guid = xaccAccountGetGUID(account);
3957 
3958  /* Find all windows that need to be killed. Don't kill them yet, as
3959  * that would affect the list being walked.*/
3960  citem = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_REGISTER2_NAME);
3961  for ( ; citem; citem = g_list_next(citem))
3962  {
3963  page = (GncPluginPageRegister2 *)citem->data;
3964  priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
3965  ledger_type = gnc_ledger_display2_type (priv->ledger);
3966  if (ledger_type == LD2_GL)
3967  {
3968  kill = g_list_append(kill, page);
3969  /* kill it */
3970  }
3971  else if ((ledger_type == LD2_SINGLE) || (ledger_type == LD2_SUBACCOUNT))
3972  {
3973  if (guid_compare(acct_guid, &priv->key) == 0)
3974  {
3975  kill = g_list_append(kill, page);
3976  }
3977  }
3978  }
3979 
3980  /* Now kill them. */
3981  for (item = kill; item; item = g_list_next(item))
3982  {
3983  page = (GncPluginPageRegister2 *)item->data;
3984  gnc_main_window_close_page(GNC_PLUGIN_PAGE(page));
3985  }
3986 }
3987 
4002 static void
4003 gnc_plugin_page_register2_event_handler (QofInstance *entity,
4004  QofEventId event_type,
4005  GncPluginPageRegister2 *page,
4006  GncEventData *ed)
4007 {
4008  Transaction *trans;
4009  QofBook *book;
4010  GncPluginPage *visible_page;
4011  GtkWidget *window;
4012  gchar *label, *color;
4013 
4014  g_return_if_fail(page); /* Required */
4015  if (!GNC_IS_TRANS(entity) && !GNC_IS_ACCOUNT(entity))
4016  return;
4017 
4018  ENTER("entity %p of type %d, page %p, event data %p",
4019  entity, event_type, page, ed);
4020 
4021  window = gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(page));
4022 
4023  if (GNC_IS_ACCOUNT(entity))
4024  {
4025  if (GNC_IS_MAIN_WINDOW(window))
4026  {
4027  label = gnc_plugin_page_register2_get_tab_name(GNC_PLUGIN_PAGE(page));
4028  main_window_update_page_name(GNC_PLUGIN_PAGE(page), label);
4029  color = gnc_plugin_page_register2_get_tab_color(GNC_PLUGIN_PAGE(page));
4030  main_window_update_page_color(GNC_PLUGIN_PAGE(page), color);
4031  g_free(color);
4032  g_free(label);
4033  }
4034  LEAVE("tab name updated");
4035  return;
4036  }
4037 
4038  if (!(event_type & (QOF_EVENT_MODIFY | QOF_EVENT_DESTROY)))
4039  {
4040  LEAVE("not a modify");
4041  return;
4042  }
4043  trans = GNC_TRANS(entity);
4044  book = qof_instance_get_book(QOF_INSTANCE(trans));
4045  if (!gnc_plugin_page_has_book(GNC_PLUGIN_PAGE(page), book))
4046  {
4047  LEAVE("not in this book");
4048  return;
4049  }
4050 
4051  if (GNC_IS_MAIN_WINDOW(window))
4052  {
4053  visible_page = gnc_main_window_get_current_page(GNC_MAIN_WINDOW(window));
4054  if (visible_page != GNC_PLUGIN_PAGE(page))
4055  {
4056  LEAVE("page not visible");
4057  return;
4058  }
4059  }
4060 
4061  gnc_plugin_page_register2_ui_update(NULL, page);
4062  LEAVE(" ");
4063  return;
4064 }
4065 
4066 
void gnc_plugin_page_register2_filter_status_one_cb(GtkToggleButton *button, GncPluginPageRegister2 *page)
GNCLedgerDisplay2 * gnc_plugin_page_register2_get_ledger(GncPluginPage *plugin_page)
void xaccAccountSetFilter(Account *acc, const char *str)
Definition: Account.c:2308
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 gnc_plugin_page_register2_set_options(GncPluginPage *plugin_page, gint lines_default, gboolean read_only)
void qof_instance_get(const QofInstance *inst, const gchar *first_param,...)
Wrapper for g_object_get.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
GncPluginPage *(* recreate_page)(GtkWidget *window, GKeyFile *file, const gchar *group)
gboolean gnc_main_window_button_press_cb(GtkWidget *whatever, GdkEventButton *event, GncPluginPage *page)
Date and Time handling routines.
GType gnc_plugin_page_register2_get_type(void)
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
#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)
common utilities for manipulating a GtkTreeView within gnucash
#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
void gnc_plugin_page_register2_filter_start_cb(GtkWidget *radio, GncPluginPageRegister2 *page)
void gnc_plugin_page_register2_filter_save_cb(GtkToggleButton *button, GncPluginPageRegister2 *page)
GncPluginPage * gnc_plugin_page_register2_new(Account *account, gboolean subaccounts)
void gnc_plugin_page_set_page_long_name(GncPluginPage *page, const char *name)
Transaction * xaccSplitGetParent(const Split *split)
Definition: Split.c:1903
GncPluginPage * gnc_plugin_page_register2_new_gl(void)
void gnc_plugin_page_register2_filter_end_cb(GtkWidget *radio, GncPluginPageRegister2 *page)
GtkActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
#define ENTER(format, args...)
Definition: qoflog.h:261
struct _QofQuery QofQuery
Definition: qofquery.h:90
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.
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()
void gnc_plugin_page_register2_filter_status_all_cb(GtkButton *button, GncPluginPageRegister2 *plugin_page)
const char * xaccAccountGetColor(const Account *acc)
Definition: Account.c:3100
GNCSplitReg2 * gnc_plugin_page_register2_get_gsr(GncPluginPage *plugin_page)
int xaccTransCountSplits(const Transaction *trans)
Definition: Transaction.c:2170
#define xaccAccountGetGUID(X)
Definition: Account.h:239
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
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_set_use_new_window(GncPluginPage *page, gboolean use_new)
GncPluginPage * gnc_plugin_page_register2_new_ledger(GNCLedgerDisplay2 *ledger)
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
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)
Anchor Scheduled Transaction info in a book. See src/doc/books.txt for design overview.
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.
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.
#define xaccSchedXactionGetGUID(X)
Definition: SchedXaction.h:321
All type declarations for the whole Gnucash engine.
#define CREC
Definition: Split.h:67
void(* window_changed)(GncPluginPage *plugin_page, GtkWidget *window)
Generic api to store and retrieve preferences.
void gnc_plugin_page_register2_filter_select_range_cb(GtkRadioButton *button, GncPluginPageRegister2 *page)
time64 gnc_time64_get_day_start(time64 time_val)
GList * qof_query_run(QofQuery *query)
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)
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
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
const GncGUID * guid_null(void)
GtkWidget *(* create_widget)(GncPluginPage *plugin_page)
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)
Split * xaccSplitGetOtherSplit(const Split *split)
Definition: Split.c:2086
#define LEAVE(format, args...)
Definition: qoflog.h:271
void gnc_plugin_page_register2_filter_response_cb(GtkDialog *dialog, gint response, GncPluginPageRegister2 *plugin_page)
void(* save_page)(GncPluginPage *page, GKeyFile *file, const gchar *group)
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)
const char * xaccAccountGetName(const Account *acc)
Definition: Account.c:3031
void gnc_plugin_set_important_actions(GtkActionGroup *action_group, const gchar **name)
Definition: gnc-plugin.c:289
void main_window_update_page_name(GncPluginPage *page, const gchar *name_in)
GtkWidget * summarybar
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