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