1 /********************************************************************\
2 * split-register-model.c -- split register model object *
3 * *
4 * This program is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU General Public License as *
6 * published by the Free Software Foundation; either version 2 of *
7 * the License, or (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License*
15 * along with this program; if not, contact: *
16 * *
17 * Free Software Foundation Voice: +1-617-542-5942 *
18 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19 * Boston, MA 02110-1301, USA gnu@gnu.org *
20 * *
21 \********************************************************************/
22
23 #include <config.h>
24
25 #include <glib.h>
26 #include <glib/gi18n.h>
27
28 #include "datecell.h"
29 #include "dialog-utils.h"
30 #include "dialog-doclink-utils.h"
31 #include "gnc-engine.h"
32 #include "gnc-prefs.h"
33 #include "gnc-ui.h"
34 #include "gnc-uri-utils.h"
35 #include "gnc-glib-utils.h"
36 #include "gnc-filepath-utils.h"
37 #include "gnc-warnings.h"
38 #include "doclinkcell.h"
39 #include "pricecell.h"
40 #include "recncell.h"
41 #include "split-register.h"
42 #include "split-register-model.h"
43 #include "split-register-model-save.h"
44 #include "split-register-p.h"
45 #include "engine-helpers.h"
46
47 /* This static indicates the debugging module that this .o belongs to. */
48 static QofLogModule log_module = GNC_MOD_LEDGER;
49
50 /* Flag for determining colorization of negative amounts. */
51 static gboolean use_red_for_negative = TRUE;
52
53 /* This returns the balance at runtime of a register at the split defined by virt_loc regardless of
54 * sort order. It always assumes that the first txn in the register is starting from a 0 balance.
55 * If gboolean subaccounts is TRUE, then it will return the total balance of the parent account
56 * and all its subaccounts. FALSE will return the balance of just the parent account of the register. */
57 static gnc_numeric
gnc_split_register_get_rbaln(VirtualLocation virt_loc,gpointer user_data,gboolean subaccounts)58 gnc_split_register_get_rbaln (VirtualLocation virt_loc, gpointer user_data,
59 gboolean subaccounts)
60 {
61 SplitRegister* reg = user_data;
62 Split* split;
63 SRInfo* info = gnc_split_register_get_info (reg);
64 gnc_numeric balance;
65 Account* account = NULL;
66 Transaction* trans;
67 GList* node, *child;
68 GList* children = NULL;
69 int i, row;
70
71 balance = gnc_numeric_zero();
72
73 /* Return NULL if this is a blank transaction. */
74 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
75 if (split == xaccSplitLookup (&info->blank_split_guid,
76 gnc_get_current_book()))
77 return gnc_numeric_zero();
78
79 trans = xaccSplitGetParent (split);
80 if (!trans)
81 return gnc_numeric_zero();
82
83 /* Get a list of accounts for matching */
84 account = gnc_split_register_get_default_account (reg);
85 if (!account)
86 /* Register has no account (perhaps general journal) so it has no
87 well defined balance, return zero. */
88 return balance;
89
90 if (subaccounts)
91 {
92 children = gnc_account_get_descendants (account);
93 children = g_list_prepend (children, account);
94 }
95
96 /* Get the row number we're on, then start with the first row. */
97 row = virt_loc.vcell_loc.virt_row;
98 virt_loc.vcell_loc.virt_row = 0;
99
100 while (virt_loc.vcell_loc.virt_row <= row)
101 {
102 /* Get new temporary split and its parent transaction */
103 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
104 trans = xaccSplitGetParent (split);
105
106 i = 1;
107 for (node = xaccTransGetSplitList (trans); node; node = node->next)
108 {
109 Split* secondary = node->data;
110 i++;
111
112 if (subaccounts)
113 {
114 /* Add up the splits that belong to the transaction if they are
115 * from the lead account or one of the subaccounts. */
116 account = xaccSplitGetAccount (secondary);
117
118 for (child = children; child; child = child->next)
119 {
120 if (account == child->data)
121 {
122 balance = gnc_numeric_add_fixed (balance, xaccSplitGetAmount (secondary));
123 break;
124 }
125 }
126 }
127 else
128 {
129 if (account == xaccSplitGetAccount (secondary))
130 balance = gnc_numeric_add_fixed (balance, xaccSplitGetAmount (secondary));
131 }
132 }
133 virt_loc.vcell_loc.virt_row += i;
134 }
135
136 if (subaccounts)
137 g_list_free (children);
138
139 return balance;
140 }
141
142 static gnc_commodity*
gnc_split_register_get_split_commodity(SplitRegister * reg,VirtualLocation virt_loc)143 gnc_split_register_get_split_commodity (SplitRegister* reg,
144 VirtualLocation virt_loc)
145 {
146 CursorClass cursor_class;
147 Account* account;
148 Split* split;
149
150 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
151 if (!split)
152 return NULL;
153
154 cursor_class = gnc_split_register_get_cursor_class (reg,
155 virt_loc.vcell_loc);
156 if (cursor_class != CURSOR_CLASS_SPLIT)
157 return NULL;
158
159 account = NULL;
160
161 if (virt_cell_loc_equal (virt_loc.vcell_loc,
162 reg->table->current_cursor_loc.vcell_loc) &&
163 gnc_table_layout_get_cell_changed (reg->table->layout, XFRM_CELL, FALSE))
164 {
165 const char* name;
166
167 name = gnc_table_layout_get_cell_value (reg->table->layout, XFRM_CELL);
168 account = gnc_account_lookup_for_register (gnc_get_current_root_account(),
169 name);
170 }
171
172 if (!account)
173 account = xaccSplitGetAccount (split);
174
175 if (!account)
176 return NULL;
177
178 return xaccAccountGetCommodity (account);
179 }
180
181 static gboolean
gnc_split_register_use_security_cells(SplitRegister * reg,VirtualLocation virt_loc)182 gnc_split_register_use_security_cells (SplitRegister* reg,
183 VirtualLocation virt_loc)
184 {
185 CursorClass cursor_class;
186 Account* account;
187 Split* split;
188
189 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
190 if (!split)
191 return TRUE;
192
193 cursor_class = gnc_split_register_get_cursor_class (reg,
194 virt_loc.vcell_loc);
195 if (cursor_class != CURSOR_CLASS_SPLIT)
196 return TRUE;
197
198 account = NULL;
199
200 if (virt_cell_loc_equal (virt_loc.vcell_loc,
201 reg->table->current_cursor_loc.vcell_loc) &&
202 gnc_table_layout_get_cell_changed (reg->table->layout, XFRM_CELL, FALSE))
203 {
204 const char* name;
205
206 name = gnc_table_layout_get_cell_value (reg->table->layout, XFRM_CELL);
207 account = gnc_account_lookup_for_register (gnc_get_current_root_account(),
208 name);
209 }
210
211 if (!account)
212 account = xaccSplitGetAccount (split);
213
214 if (!account)
215 return TRUE;
216
217 if (xaccTransUseTradingAccounts (xaccSplitGetParent (split)))
218 {
219 gnc_commodity* commod = xaccAccountGetCommodity (account);
220 if (!gnc_commodity_is_iso (commod) ||
221 !gnc_commodity_equal (commod,
222 xaccTransGetCurrency (xaccSplitGetParent (split))))
223 return TRUE;
224 }
225
226 return xaccAccountIsPriced (account);
227 }
228
229 static const char*
gnc_split_register_get_date_label(VirtualLocation virt_loc,gpointer user_data)230 gnc_split_register_get_date_label (VirtualLocation virt_loc,
231 gpointer user_data)
232 {
233 return _ ("Date");
234 }
235
236 static const char*
gnc_split_register_get_due_date_label(VirtualLocation virt_loc,gpointer user_data)237 gnc_split_register_get_due_date_label (VirtualLocation virt_loc,
238 gpointer user_data)
239 {
240 return _ ("Due Date");
241 }
242
243 static const char*
gnc_split_register_get_num_label(VirtualLocation virt_loc,gpointer user_data)244 gnc_split_register_get_num_label (VirtualLocation virt_loc,
245 gpointer user_data)
246 {
247 SplitRegister* reg = user_data;
248
249 switch (reg->type)
250 {
251 case RECEIVABLE_REGISTER:
252 case PAYABLE_REGISTER:
253 /* Column label for Invoice IDs in A/P & A/R accounts */
254 return _ ("Ref");
255 default:
256 return _ ("Num");
257 }
258 }
259
260 static const char*
gnc_split_register_get_tran_num_label(VirtualLocation virt_loc,gpointer user_data)261 gnc_split_register_get_tran_num_label (VirtualLocation virt_loc,
262 gpointer user_data)
263 {
264 SplitRegister* reg = user_data;
265
266 switch (reg->type)
267 {
268 case RECEIVABLE_REGISTER:
269 case PAYABLE_REGISTER:
270 return _ ("T-Ref");
271 case GENERAL_JOURNAL:
272 case INCOME_LEDGER:
273 case SEARCH_LEDGER:
274 {
275 if (reg->use_tran_num_for_num_field)
276 return _ ("Num");
277 }
278 default:
279 return _ ("T-Num");
280 }
281 }
282
283 static const char*
gnc_split_register_get_desc_label(VirtualLocation virt_loc,gpointer user_data)284 gnc_split_register_get_desc_label (VirtualLocation virt_loc,
285 gpointer user_data)
286 {
287 SplitRegister* reg = user_data;
288
289 switch (reg->type)
290 {
291 case RECEIVABLE_REGISTER:
292 return _ ("Customer");
293 case PAYABLE_REGISTER:
294 return _ ("Vendor");
295 default:
296 return _ ("Description");
297 }
298 }
299
300 static const char*
gnc_split_register_get_recn_label(VirtualLocation virt_loc,gpointer user_data)301 gnc_split_register_get_recn_label (VirtualLocation virt_loc,
302 gpointer user_data)
303 {
304 SplitRegister* reg = user_data;
305
306 switch (reg->type)
307 {
308 case RECEIVABLE_REGISTER:
309 case PAYABLE_REGISTER:
310 return _ ("Paid");
311
312 default:
313 return C_ ("Column header for 'Reconciled'", "R");
314 }
315 }
316
317 static const char*
gnc_split_register_get_baln_label(VirtualLocation virt_loc,gpointer user_data)318 gnc_split_register_get_baln_label (VirtualLocation virt_loc,
319 gpointer user_data)
320 {
321 return _ ("Balance");
322 }
323
324 static const char*
gnc_split_register_get_action_label(VirtualLocation virt_loc,gpointer user_data)325 gnc_split_register_get_action_label (VirtualLocation virt_loc,
326 gpointer user_data)
327 {
328 return _ ("Action");
329 }
330
331 static const char*
gnc_split_register_get_doclink_label(VirtualLocation virt_loc,gpointer user_data)332 gnc_split_register_get_doclink_label (VirtualLocation virt_loc,
333 gpointer user_data)
334 {
335 return C_ ("Column header for 'Document Link'", "L");
336 }
337
338 static const char*
gnc_split_register_get_xfrm_label(VirtualLocation virt_loc,gpointer user_data)339 gnc_split_register_get_xfrm_label (VirtualLocation virt_loc,
340 gpointer user_data)
341 {
342 return _ ("Account");
343 }
344
345 static const char*
gnc_split_register_get_mxfrm_label(VirtualLocation virt_loc,gpointer user_data)346 gnc_split_register_get_mxfrm_label (VirtualLocation virt_loc,
347 gpointer user_data)
348 {
349 return _ ("Transfer");
350 }
351
352 static const char*
gnc_split_register_get_memo_label(VirtualLocation virt_loc,gpointer user_data)353 gnc_split_register_get_memo_label (VirtualLocation virt_loc,
354 gpointer user_data)
355 {
356 return _ ("Memo");
357 }
358
359 static const char*
gnc_split_register_get_type_label(VirtualLocation virt_loc,gpointer user_data)360 gnc_split_register_get_type_label (VirtualLocation virt_loc,
361 gpointer user_data)
362 {
363 return _ ("Type");
364 }
365
366 static const char*
gnc_split_register_get_rate_label(VirtualLocation virt_loc,gpointer user_data)367 gnc_split_register_get_rate_label (VirtualLocation virt_loc,
368 gpointer user_data)
369 {
370 return _ ("Rate");
371 }
372
373 static const char*
gnc_split_register_get_debit_label(VirtualLocation virt_loc,gpointer user_data)374 gnc_split_register_get_debit_label (VirtualLocation virt_loc,
375 gpointer user_data)
376 {
377 SplitRegister* reg = user_data;
378
379 return gnc_split_register_get_debit_string (reg);
380 }
381
382 static const char*
gnc_split_register_get_credit_label(VirtualLocation virt_loc,gpointer user_data)383 gnc_split_register_get_credit_label (VirtualLocation virt_loc,
384 gpointer user_data)
385 {
386 SplitRegister* reg = user_data;
387
388 return gnc_split_register_get_credit_string (reg);
389 }
390
391 static const char*
gnc_split_register_get_price_label(VirtualLocation virt_loc,gpointer user_data)392 gnc_split_register_get_price_label (VirtualLocation virt_loc,
393 gpointer user_data)
394 {
395 SplitRegister* reg = user_data;
396 gnc_commodity* commod;
397
398 if (!gnc_split_register_use_security_cells (reg, virt_loc))
399 return NULL;
400
401 commod = gnc_split_register_get_split_commodity (reg, virt_loc);
402 if (!commod || !gnc_commodity_is_iso (commod))
403 return _ ("Price");
404 else
405 return _ ("Exch. Rate");
406 }
407
408 static const char*
gnc_split_register_get_shares_label(VirtualLocation virt_loc,gpointer user_data)409 gnc_split_register_get_shares_label (VirtualLocation virt_loc,
410 gpointer user_data)
411 {
412 SplitRegister* reg = user_data;
413 gnc_commodity* commod;
414
415 if (!gnc_split_register_use_security_cells (reg, virt_loc))
416 return NULL;
417
418 commod = gnc_split_register_get_split_commodity (reg, virt_loc);
419 if (!commod || !gnc_commodity_is_iso (commod))
420 return _ ("Shares");
421 else
422 return _ ("Oth. Curr.");
423 }
424
425 static const char*
gnc_split_register_get_tcredit_label(VirtualLocation virt_loc,gpointer user_data)426 gnc_split_register_get_tcredit_label (VirtualLocation virt_loc,
427 gpointer user_data)
428 {
429 SplitRegister* reg = user_data;
430 SRInfo* info = gnc_split_register_get_info (reg);
431
432 if (info->tcredit_str)
433 return info->tcredit_str;
434
435 {
436 const char* string = gnc_split_register_get_credit_string (reg);
437
438 if (string)
439 info->tcredit_str = g_strdup_printf (_ ("Tot %s"), string);
440 }
441
442 if (info->tcredit_str)
443 return info->tcredit_str;
444
445 info->tcredit_str = g_strdup (_ ("Tot Credit"));
446
447 return info->tcredit_str;
448 }
449
450 static const char*
gnc_split_register_get_tdebit_label(VirtualLocation virt_loc,gpointer user_data)451 gnc_split_register_get_tdebit_label (VirtualLocation virt_loc,
452 gpointer user_data)
453 {
454 SplitRegister* reg = user_data;
455 SRInfo* info = gnc_split_register_get_info (reg);
456
457 if (info->tdebit_str)
458 return info->tdebit_str;
459
460 {
461 const char* string = gnc_split_register_get_debit_string (reg);
462 if (string)
463 info->tdebit_str = g_strdup_printf (_ ("Tot %s"), string);
464 }
465
466 if (info->tdebit_str)
467 return info->tdebit_str;
468
469 info->tdebit_str = g_strdup (_ ("Tot Debit"));
470
471 return info->tdebit_str;
472 }
473
474 static const char*
gnc_split_register_get_tshares_label(VirtualLocation virt_loc,gpointer user_data)475 gnc_split_register_get_tshares_label (VirtualLocation virt_loc,
476 gpointer user_data)
477 {
478 return _ ("Tot Shares");
479 }
480
481 static const char*
gnc_split_register_get_tbalance_label(VirtualLocation virt_loc,gpointer user_data)482 gnc_split_register_get_tbalance_label (VirtualLocation virt_loc,
483 gpointer user_data)
484 {
485 return _ ("Balance");
486 }
487
488 static const char*
gnc_split_register_get_notes_label(VirtualLocation virt_loc,gpointer user_data)489 gnc_split_register_get_notes_label (VirtualLocation virt_loc,
490 gpointer user_data)
491 {
492 return _ ("Notes");
493 }
494
495 static const char*
gnc_split_register_get_fdebit_label(VirtualLocation virt_loc,gpointer user_data)496 gnc_split_register_get_fdebit_label (VirtualLocation virt_loc,
497 gpointer user_data)
498 {
499 return _ ("Debit Formula");
500 }
501
502 static const char*
gnc_split_register_get_fcredit_label(VirtualLocation virt_loc,gpointer user_data)503 gnc_split_register_get_fcredit_label (VirtualLocation virt_loc,
504 gpointer user_data)
505 {
506 return _ ("Credit Formula");
507 }
508
509
510 static char*
gnc_split_register_get_default_tooltip(VirtualLocation virt_loc,gpointer user_data)511 gnc_split_register_get_default_tooltip (VirtualLocation virt_loc,
512 gpointer user_data)
513 {
514 SplitRegister* reg = user_data;
515 const char* tooltip = gnc_table_get_entry (reg->table, virt_loc);
516
517 return g_strdup (tooltip);
518 }
519
520 static char*
gnc_split_register_get_recn_tooltip(VirtualLocation virt_loc,gpointer user_data)521 gnc_split_register_get_recn_tooltip (VirtualLocation virt_loc,
522 gpointer user_data)
523 {
524 SplitRegister* reg = user_data;
525 Split* split;
526
527 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
528 if (!split)
529 return NULL;
530
531 if (xaccSplitGetReconcile (split) == YREC)
532 {
533 char datebuff[MAX_DATE_LENGTH + 1];
534 time64 time = xaccSplitGetDateReconciled (split);
535 memset (datebuff, 0, sizeof (datebuff));
536 qof_print_date_buff (datebuff, MAX_DATE_LENGTH, time);
537 return g_strdup_printf (_ ("Reconciled on %s"), datebuff);
538 }
539 else if (xaccSplitGetReconcile (split) == VREC)
540 {
541 Transaction* trans = xaccSplitGetParent (split);
542 return g_strdup (xaccTransGetVoidReason (trans));
543 }
544 else
545 return NULL;
546 }
547
548 static char*
gnc_split_register_get_doclink_tooltip(VirtualLocation virt_loc,gpointer user_data)549 gnc_split_register_get_doclink_tooltip (VirtualLocation virt_loc,
550 gpointer user_data)
551 {
552 SplitRegister* reg = user_data;
553 Transaction* trans;
554 const char* uri;
555
556 trans = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
557 if (!trans)
558 return NULL;
559
560 // get the existing uri
561 uri = xaccTransGetDocLink (trans);
562
563 // Check for uri is empty or NULL
564 if (uri && *uri)
565 return gnc_doclink_get_unescaped_just_uri (uri);
566 else
567 return NULL;
568 }
569
570 static gnc_numeric
get_trans_total_amount(SplitRegister * reg,Transaction * trans)571 get_trans_total_amount (SplitRegister* reg, Transaction* trans)
572 {
573 Account* account = gnc_split_register_get_default_account (reg);
574 return xaccTransGetAccountAmount (trans, account);
575 }
576
577 static gnc_numeric
get_trans_total_balance(SplitRegister * reg,Transaction * trans)578 get_trans_total_balance (SplitRegister* reg, Transaction* trans)
579 {
580 Account* account;
581
582 account = gnc_split_register_get_default_account (reg);
583 if (!trans || !account) return gnc_numeric_zero();
584
585 return xaccTransGetAccountBalance (trans, account);
586 }
587
588 static gboolean
gnc_split_register_use_negative_color(VirtualLocation virt_loc,SplitRegister * reg)589 gnc_split_register_use_negative_color (VirtualLocation virt_loc,
590 SplitRegister* reg)
591 {
592 const char* cell_name;
593 gnc_numeric value = gnc_numeric_zero();
594 Split* split;
595
596 if (!use_red_for_negative)
597 return FALSE;
598
599 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
600 if (!split)
601 return FALSE;
602
603 cell_name = gnc_table_get_cell_name (reg->table, virt_loc);
604
605 if (gnc_cell_name_equal (cell_name, TSHRS_CELL))
606 value = get_trans_total_amount (reg, xaccSplitGetParent (split));
607 else if (gnc_cell_name_equal (cell_name, SHRS_CELL))
608 {
609 if (virt_cell_loc_equal (reg->table->current_cursor_loc.vcell_loc,
610 virt_loc.vcell_loc))
611 value = gnc_price_cell_get_value
612 ((PriceCell*) gnc_table_layout_get_cell (reg->table->layout,
613 SHRS_CELL));
614 else
615 value = xaccSplitGetAmount (split);
616 }
617 else if (gnc_cell_name_equal (cell_name, BALN_CELL))
618 value = xaccSplitGetBalance (split);
619 else if (gnc_cell_name_equal (cell_name, RBALN_CELL))
620 value = gnc_split_register_get_rbaln (virt_loc, reg, TRUE);
621 else if (gnc_cell_name_equal (cell_name, TBALN_CELL))
622 value = get_trans_total_balance (reg, xaccSplitGetParent (split));
623
624 if ((gnc_cell_name_equal (cell_name, BALN_CELL)) ||
625 (gnc_cell_name_equal (cell_name, RBALN_CELL)) ||
626 (gnc_cell_name_equal (cell_name, TBALN_CELL)))
627 {
628 Account* account = xaccSplitGetAccount (split);
629 if (gnc_reverse_balance (account))
630 value = gnc_numeric_neg (value);
631 }
632
633 if (gnc_numeric_negative_p (value))
634 return TRUE;
635
636 return FALSE;
637 }
638
639 static guint32
gnc_split_register_get_cell_color_internal(VirtualLocation virt_loc,SplitRegister * reg)640 gnc_split_register_get_cell_color_internal (VirtualLocation virt_loc,
641 SplitRegister* reg)
642 {
643 const char* cursor_name;
644 VirtualCell* vcell;
645 gboolean is_current;
646 guint32 colorbase = 0;
647
648 /* a bit of enum arithmetic */
649
650 if (gnc_split_register_use_negative_color (virt_loc, reg))
651 colorbase = COLOR_NEGATIVE; // Requires Negative fg color
652
653 if (!reg)
654 return (colorbase + COLOR_UNDEFINED);
655
656 if (gnc_table_virtual_location_in_header (reg->table, virt_loc))
657 return (colorbase + COLOR_HEADER);
658
659 vcell = gnc_table_get_virtual_cell (reg->table, virt_loc.vcell_loc);
660 if (!vcell || !vcell->cellblock)
661 return (colorbase + COLOR_UNDEFINED);
662
663 if ((virt_loc.phys_col_offset < vcell->cellblock->start_col) ||
664 (virt_loc.phys_col_offset > vcell->cellblock->stop_col))
665 return (colorbase + COLOR_UNDEFINED);
666
667 is_current = virt_cell_loc_equal (reg->table->current_cursor_loc.vcell_loc,
668 virt_loc.vcell_loc);
669
670 cursor_name = vcell->cellblock->cursor_name;
671
672 if (g_strcmp0 (cursor_name, CURSOR_SINGLE_JOURNAL) == 0 ||
673 g_strcmp0 (cursor_name, CURSOR_SINGLE_LEDGER) == 0)
674 {
675 if (is_current)
676 return vcell->start_primary_color ?
677 (colorbase + COLOR_PRIMARY_ACTIVE) :
678 (colorbase + COLOR_SECONDARY_ACTIVE);
679
680 return vcell->start_primary_color ?
681 (colorbase + COLOR_PRIMARY) : (colorbase + COLOR_SECONDARY);
682 }
683
684 if (g_strcmp0 (cursor_name, CURSOR_DOUBLE_JOURNAL) == 0 ||
685 g_strcmp0 (cursor_name, CURSOR_DOUBLE_JOURNAL_NUM_ACTN) == 0 ||
686 g_strcmp0 (cursor_name, CURSOR_DOUBLE_LEDGER) == 0 ||
687 g_strcmp0 (cursor_name, CURSOR_DOUBLE_LEDGER_NUM_ACTN) == 0)
688 {
689 if (is_current)
690 {
691 if (reg->double_alt_color)
692 return vcell->start_primary_color ?
693 (colorbase + COLOR_PRIMARY_ACTIVE) :
694 (colorbase + COLOR_SECONDARY_ACTIVE);
695
696 return (virt_loc.phys_row_offset % 2 == 0) ?
697 (colorbase + COLOR_PRIMARY_ACTIVE) :
698 (colorbase + COLOR_SECONDARY_ACTIVE);
699 }
700
701 if (reg->double_alt_color)
702 return vcell->start_primary_color ?
703 (colorbase + COLOR_PRIMARY) :
704 (colorbase + COLOR_SECONDARY);
705
706 return (virt_loc.phys_row_offset % 2 == 0) ?
707 (colorbase + COLOR_PRIMARY) :
708 (colorbase + COLOR_SECONDARY);
709 }
710
711 if (g_strcmp0 (cursor_name, CURSOR_SPLIT) == 0)
712 {
713 if (is_current)
714 return (colorbase + COLOR_SPLIT_ACTIVE);
715
716 return (colorbase + COLOR_SPLIT);
717 }
718
719 PWARN ("Unexpected cursor: %s\n", cursor_name);
720
721 return (colorbase + COLOR_UNDEFINED);
722 }
723
724 // Get Color for non numeric cells, no hatching required
725 static guint32
gnc_split_register_get_cell_color(VirtualLocation virt_loc,gboolean * hatching,gpointer user_data)726 gnc_split_register_get_cell_color (VirtualLocation virt_loc,
727 gboolean* hatching,
728 gpointer user_data)
729 {
730 SplitRegister* reg = user_data;
731
732 if (hatching)
733 *hatching = FALSE;
734
735 return gnc_split_register_get_cell_color_internal (virt_loc, reg);
736 }
737
738 // Get Color for numeric cells, update hatching
739 static guint32
gnc_split_register_get_debcred_color(VirtualLocation virt_loc,gboolean * hatching,gpointer user_data)740 gnc_split_register_get_debcred_color (VirtualLocation virt_loc,
741 gboolean* hatching,
742 gpointer user_data)
743 {
744 SplitRegister* reg = user_data;
745
746 if (hatching)
747 {
748 Transaction* trans;
749
750 trans = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
751
752 if (trans)
753 *hatching = !xaccTransIsBalanced (trans);
754 else
755 *hatching = FALSE;
756 }
757 return gnc_split_register_get_cell_color_internal (virt_loc, reg);
758 }
759
760 static void
gnc_split_register_get_border(VirtualLocation virt_loc,PhysicalCellBorders * borders,gpointer user_data)761 gnc_split_register_get_border (VirtualLocation virt_loc,
762 PhysicalCellBorders* borders,
763 gpointer user_data)
764 {
765 SplitRegister* reg = user_data;
766 CursorClass cursor_class;
767 VirtualCell* vcell;
768
769 vcell = gnc_table_get_virtual_cell (reg->table, virt_loc.vcell_loc);
770 if (!vcell || !vcell->cellblock)
771 return;
772
773 if (virt_loc.phys_col_offset < vcell->cellblock->start_col ||
774 virt_loc.phys_col_offset > vcell->cellblock->stop_col)
775 {
776 borders->top = CELL_BORDER_LINE_NONE;
777 borders->bottom = CELL_BORDER_LINE_NONE;
778 borders->left = CELL_BORDER_LINE_NONE;
779 borders->right = CELL_BORDER_LINE_NONE;
780 return;
781 }
782
783 cursor_class =
784 gnc_split_register_cursor_name_to_class (vcell->cellblock->cursor_name);
785
786 if (cursor_class == CURSOR_CLASS_SPLIT)
787 {
788 borders->top = CELL_BORDER_LINE_LIGHT;
789 borders->bottom = CELL_BORDER_LINE_LIGHT;
790 borders->left = MIN (borders->left, CELL_BORDER_LINE_LIGHT);
791 borders->right = MIN (borders->right, CELL_BORDER_LINE_LIGHT);
792
793 if (virt_loc.phys_col_offset == vcell->cellblock->start_col)
794 borders->left = CELL_BORDER_LINE_NORMAL;
795 if (virt_loc.phys_col_offset == vcell->cellblock->stop_col)
796 borders->right = CELL_BORDER_LINE_NORMAL;
797 }
798 }
799
800 static const char*
gnc_split_register_get_doclink_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)801 gnc_split_register_get_doclink_entry (VirtualLocation virt_loc,
802 gboolean translate,
803 gboolean* conditionally_changed,
804 gpointer user_data)
805 {
806 SplitRegister* reg = user_data;
807 Transaction* trans;
808 char link_flag;
809 const char* uri;
810 Doclinkcell *cell;
811
812 cell = (Doclinkcell *)gnc_table_layout_get_cell (reg->table->layout, DOCLINK_CELL);
813
814 if (!cell)
815 return NULL;
816
817 trans = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
818 if (!trans)
819 return NULL;
820
821 // get the existing uri
822 uri = xaccTransGetDocLink (trans);
823
824 // Check for uri is empty or NULL
825 if (uri && *uri)
826 {
827 gchar* scheme = gnc_uri_get_scheme (uri);
828
829 if (!scheme || g_strcmp0 (scheme, "file") == 0)
830 link_flag = FLINK;
831 else
832 link_flag = WLINK;
833
834 g_free (scheme);
835 }
836 else
837 link_flag = ' ';
838
839 if (gnc_doclink_get_use_glyphs (cell))
840 return gnc_doclink_get_glyph_from_flag (link_flag);
841
842 if (translate)
843 return gnc_get_doclink_str (link_flag);
844 else
845 {
846 static char s[2];
847
848 s[0] = link_flag;
849 s[1] = '\0';
850 return s;
851 }
852 }
853
854 static char *
gnc_split_register_get_doclink_help(VirtualLocation virt_loc,gpointer user_data)855 gnc_split_register_get_doclink_help (VirtualLocation virt_loc,
856 gpointer user_data)
857 {
858 // do not want contents displayed as help so return space
859 return g_strdup (" ");
860 }
861
862 #if 0
863 // this code is not used yet
864 static char
865 gnc_split_register_get_doclink_value (SplitRegister* reg,
866 VirtualLocation virt_loc)
867 {
868 Doclinkcell *cell;
869
870 cell = (Doclinkcell *)gnc_table_layout_get_cell (reg->table->layout, DOCLINK_CELL);
871 if (!cell)
872 return '\0';
873
874 return gnc_doclink_cell_get_flag (cell);
875 }
876 #endif
877
878 static const char*
gnc_split_register_get_type_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)879 gnc_split_register_get_type_entry (VirtualLocation virt_loc,
880 gboolean translate,
881 gboolean* conditionally_changed,
882 gpointer user_data)
883 {
884 SplitRegister* reg = user_data;
885 Transaction* trans;
886 char type;
887 static char s[2];
888
889 trans = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
890 if (!trans)
891 return NULL;
892
893 type = xaccTransGetTxnType (trans);
894
895 if (type == TXN_TYPE_NONE)
896 type = '?';
897
898 s[0] = type;
899 s[1] = '\0';
900
901 return s;
902 }
903
904 static char
gnc_split_register_get_type_value(SplitRegister * reg,VirtualLocation virt_loc)905 gnc_split_register_get_type_value (SplitRegister* reg,
906 VirtualLocation virt_loc)
907 {
908 RecnCell* cell;
909
910 cell = (RecnCell*)gnc_table_layout_get_cell (reg->table->layout, TYPE_CELL);
911 if (!cell)
912 return '\0';
913
914 return gnc_recn_cell_get_flag (cell);
915 }
916
917 static const char*
gnc_split_register_get_due_date_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)918 gnc_split_register_get_due_date_entry (VirtualLocation virt_loc,
919 gboolean translate,
920 gboolean* conditionally_changed,
921 gpointer user_data)
922 {
923 SplitRegister* reg = user_data;
924 Transaction* trans;
925 Split* split;
926 gboolean is_current;
927 char type;
928 static gchar dateBuff [MAX_DATE_LENGTH+1];
929
930 is_current = virt_cell_loc_equal (reg->table->current_cursor_loc.vcell_loc,
931 virt_loc.vcell_loc);
932
933 if (is_current)
934 {
935 type = gnc_split_register_get_type_value (reg, virt_loc);
936 }
937 else
938 {
939 const char* typestr =
940 gnc_split_register_get_type_entry (virt_loc, translate,
941 conditionally_changed, user_data);
942 if (typestr != NULL)
943 type = *typestr;
944 else
945 type = '\0';
946 }
947
948 /* Only print the due date for invoice transactions */
949 if (type != TXN_TYPE_INVOICE)
950 {
951 //PWARN ("returning NULL due_date entry");
952 return NULL;
953 }
954
955 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
956 trans = xaccSplitGetParent (split);
957 if (!trans)
958 {
959 //PWARN ("No transaction in due_date entry");
960 return NULL;
961 }
962
963 //PWARN ("returning valid due_date entry");
964
965 memset (dateBuff, 0, sizeof (dateBuff));
966 qof_print_date_buff (dateBuff, MAX_DATE_LENGTH, xaccTransRetDateDue (trans));
967 return dateBuff;
968 }
969
970 static const char*
gnc_split_register_get_date_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)971 gnc_split_register_get_date_entry (VirtualLocation virt_loc,
972 gboolean translate,
973 gboolean* conditionally_changed,
974 gpointer user_data)
975 {
976 SplitRegister* reg = user_data;
977 Transaction* trans;
978 Split* split;
979 static gchar dateBuff [MAX_DATE_LENGTH+1];
980
981 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
982 trans = xaccSplitGetParent (split);
983 if (!trans)
984 return NULL;
985
986 memset (dateBuff, 0, sizeof (dateBuff));
987 qof_print_date_buff (dateBuff, MAX_DATE_LENGTH, xaccTransRetDatePosted (trans));
988 return dateBuff;
989 }
990
991 static char*
gnc_split_register_get_date_help(VirtualLocation virt_loc,gpointer user_data)992 gnc_split_register_get_date_help (VirtualLocation virt_loc,
993 gpointer user_data)
994 {
995 SplitRegister* reg = user_data;
996 BasicCell* cell;
997 time64 cell_time;
998
999 cell = gnc_table_get_cell (reg->table, virt_loc);
1000 if (!cell || !cell->value || *cell->value == '\0')
1001 return NULL;
1002
1003 gnc_date_cell_get_date ((DateCell*) cell, &cell_time, FALSE);
1004
1005 /* Translators: This is a date format, see i.e.
1006 https://www.gnu.org/software/libc/manual/html_node/Formatting-Calendar-Time.html */
1007 return gnc_print_time64 (cell_time, _("%A %d %B %Y"));
1008 }
1009
1010 static const char*
gnc_split_register_get_inactive_date_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1011 gnc_split_register_get_inactive_date_entry (VirtualLocation virt_loc,
1012 gboolean translate,
1013 gboolean* conditionally_changed,
1014 gpointer user_data)
1015 {
1016 /* This seems to be the one that initially gets used, the InactiveDateCell
1017 is set to, and subsequently displayed. */
1018 return _ ("Scheduled");
1019 }
1020
1021 static const char*
gnc_split_register_get_num_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1022 gnc_split_register_get_num_entry (VirtualLocation virt_loc,
1023 gboolean translate,
1024 gboolean* conditionally_changed,
1025 gpointer user_data)
1026 {
1027 SplitRegister* reg = user_data;
1028 Transaction* trans;
1029 Split* split;
1030
1031 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1032 trans = xaccSplitGetParent (split);
1033
1034 return gnc_get_num_action (trans, split);
1035 }
1036
1037 static const char*
gnc_split_register_get_tran_num_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1038 gnc_split_register_get_tran_num_entry (VirtualLocation virt_loc,
1039 gboolean translate,
1040 gboolean* conditionally_changed,
1041 gpointer user_data)
1042 {
1043 SplitRegister* reg = user_data;
1044 Transaction* trans;
1045 Split* split;
1046
1047 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1048 trans = xaccSplitGetParent (split);
1049
1050 return gnc_get_num_action (trans, NULL);
1051 }
1052
1053 static char*
gnc_split_register_get_num_help(VirtualLocation virt_loc,gpointer user_data)1054 gnc_split_register_get_num_help (VirtualLocation virt_loc,
1055 gpointer user_data)
1056 {
1057 SplitRegister* reg = user_data;
1058 const char* help;
1059
1060 help = gnc_table_get_entry (reg->table, virt_loc);
1061 if (!help || *help == '\0')
1062 switch (reg->type)
1063 {
1064 case RECEIVABLE_REGISTER:
1065 case PAYABLE_REGISTER:
1066 help = reg->use_tran_num_for_num_field ?
1067 _ ("Enter a reference, such as an invoice or check number, "
1068 "common to all entry lines (splits)") :
1069 _ ("Enter a reference, such as an invoice or check number, "
1070 "unique to each entry line (split)");
1071 break;
1072 default:
1073 help = reg->use_tran_num_for_num_field ?
1074 _ ("Enter a reference, such as a check number, "
1075 "common to all entry lines (splits)") :
1076 _ ("Enter a reference, such as a check number, "
1077 "unique to each entry line (split)");
1078 break;
1079 }
1080
1081 return g_strdup (help);
1082 }
1083
1084 static char*
gnc_split_register_get_tran_num_help(VirtualLocation virt_loc,gpointer user_data)1085 gnc_split_register_get_tran_num_help (VirtualLocation virt_loc,
1086 gpointer user_data)
1087 {
1088 SplitRegister* reg = user_data;
1089 const char* help;
1090
1091 help = gnc_table_get_entry (reg->table, virt_loc);
1092 if (!help || *help == '\0')
1093 switch (reg->type)
1094 {
1095 case RECEIVABLE_REGISTER:
1096 case PAYABLE_REGISTER:
1097 help = _ ("Enter a transaction reference, such as an invoice "
1098 "or check number, common to all entry lines (splits)");
1099 break;
1100 default:
1101 help = _ ("Enter a transaction reference "
1102 "that will be common to all entry lines (splits)");
1103 break;
1104 }
1105
1106 return g_strdup (help);
1107 }
1108
1109 static const char*
gnc_split_register_get_desc_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1110 gnc_split_register_get_desc_entry (VirtualLocation virt_loc,
1111 gboolean translate,
1112 gboolean* conditionally_changed,
1113 gpointer user_data)
1114 {
1115 SplitRegister* reg = user_data;
1116 Transaction* trans;
1117 Split* split;
1118
1119 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1120 trans = xaccSplitGetParent (split);
1121
1122 return xaccTransGetDescription (trans);
1123 }
1124
1125 static char*
gnc_split_register_get_desc_help(VirtualLocation virt_loc,gpointer user_data)1126 gnc_split_register_get_desc_help (VirtualLocation virt_loc,
1127 gpointer user_data)
1128 {
1129 SplitRegister* reg = user_data;
1130 const char* help;
1131
1132 help = gnc_table_get_entry (reg->table, virt_loc);
1133 if (!help || *help == '\0')
1134 switch (reg->type)
1135 {
1136 case RECEIVABLE_REGISTER:
1137 help = _ ("Enter the name of the Customer");
1138 break;
1139 case PAYABLE_REGISTER:
1140 help = _ ("Enter the name of the Vendor");
1141 break;
1142 default:
1143 help = _ ("Enter a description of the transaction");
1144 break;
1145 }
1146 return g_strdup (help);
1147 }
1148
1149 static const char*
gnc_split_register_get_notes_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1150 gnc_split_register_get_notes_entry (VirtualLocation virt_loc,
1151 gboolean translate,
1152 gboolean* conditionally_changed,
1153 gpointer user_data)
1154 {
1155 SplitRegister* reg = user_data;
1156 Transaction* trans;
1157 Split* split;
1158
1159 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1160 trans = xaccSplitGetParent (split);
1161
1162 return xaccTransGetNotes (trans);
1163 }
1164
1165 static char*
gnc_split_register_get_notes_help(VirtualLocation virt_loc,gpointer user_data)1166 gnc_split_register_get_notes_help (VirtualLocation virt_loc,
1167 gpointer user_data)
1168 {
1169 SplitRegister* reg = user_data;
1170 const char* help;
1171
1172 help = gnc_table_get_entry (reg->table, virt_loc);
1173 if (!help || *help == '\0')
1174 help = _ ("Enter notes for the transaction");
1175
1176 return g_strdup (help);
1177 }
1178
1179 static const char*
gnc_split_register_get_vnotes_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1180 gnc_split_register_get_vnotes_entry (VirtualLocation virt_loc,
1181 gboolean translate,
1182 gboolean* conditionally_changed,
1183 gpointer user_data)
1184 {
1185 SplitRegister* reg = user_data;
1186 Transaction* trans;
1187 Split* split;
1188
1189 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1190 trans = xaccSplitGetParent (split);
1191
1192 if (trans == NULL)
1193 return NULL;
1194 else
1195 return xaccTransGetVoidReason (trans);
1196 }
1197
1198 static char*
gnc_split_register_get_vnotes_help(VirtualLocation virt_loc,gpointer user_data)1199 gnc_split_register_get_vnotes_help (VirtualLocation virt_loc,
1200 gpointer user_data)
1201 {
1202 SplitRegister* reg = user_data;
1203 const char* help;
1204
1205 help = gnc_table_get_entry (reg->table, virt_loc);
1206 if (!help || *help == '\0')
1207 help = _ ("Reason the transaction was voided");
1208
1209 return g_strdup (help);
1210 }
1211
1212 static const char*
gnc_split_register_get_rate_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1213 gnc_split_register_get_rate_entry (VirtualLocation virt_loc,
1214 gboolean translate,
1215 gboolean* conditionally_changed,
1216 gpointer user_data)
1217 {
1218 SplitRegister* reg = user_data;
1219 Split* split, *osplit;
1220 Transaction* txn;
1221 gnc_numeric amount, value, convrate;
1222 gnc_commodity* curr;
1223 SRInfo* info = gnc_split_register_get_info (reg);
1224
1225 if (info->rate_reset == RATE_RESET_REQD && info->auto_complete)
1226 return "0";
1227
1228 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1229 if (!split)
1230 return NULL;
1231
1232 /* If this is a basic, non-expanded ledger with exactly two splits,
1233 * and split->txn->curr == split->acc->comm, then use the OTHER
1234 * split for the rate.
1235 */
1236 osplit = xaccSplitGetOtherSplit (split);
1237 txn = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
1238 curr = xaccTransGetCurrency (xaccSplitGetParent (split));
1239 if (!gnc_split_register_current_trans_expanded (reg) && osplit &&
1240 !gnc_split_register_needs_conv_rate (reg, txn,
1241 xaccSplitGetAccount (split)))
1242 {
1243 split = osplit;
1244 }
1245
1246 amount = xaccSplitGetAmount (split);
1247 value = xaccSplitGetValue (split);
1248
1249 if (gnc_numeric_zero_p (value))
1250 return "0";
1251
1252 convrate = gnc_numeric_div (amount, value, GNC_DENOM_AUTO,
1253 GNC_HOW_DENOM_REDUCE);
1254
1255 return xaccPrintAmount (convrate, gnc_default_price_print_info (curr));
1256 }
1257
1258 static const char*
gnc_split_register_get_recn_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1259 gnc_split_register_get_recn_entry (VirtualLocation virt_loc,
1260 gboolean translate,
1261 gboolean* conditionally_changed,
1262 gpointer user_data)
1263 {
1264 SplitRegister* reg = user_data;
1265 Split* split;
1266
1267 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1268 if (!split)
1269 return NULL;
1270
1271 if (translate)
1272 return gnc_get_reconcile_str (xaccSplitGetReconcile (split));
1273 else
1274 {
1275 static char s[2];
1276
1277 s[0] = xaccSplitGetReconcile (split);
1278 s[1] = '\0';
1279
1280 return s;
1281 }
1282 }
1283
1284 static const char*
gnc_split_register_get_action_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1285 gnc_split_register_get_action_entry (VirtualLocation virt_loc,
1286 gboolean translate,
1287 gboolean* conditionally_changed,
1288 gpointer user_data)
1289 {
1290 SplitRegister* reg = user_data;
1291 Split* split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1292
1293 return gnc_get_num_action (NULL, split);
1294 }
1295
1296 static char*
gnc_split_register_get_action_help(VirtualLocation virt_loc,gpointer user_data)1297 gnc_split_register_get_action_help (VirtualLocation virt_loc,
1298 gpointer user_data)
1299 {
1300 SplitRegister* reg = user_data;
1301 const char* help;
1302
1303 help = gnc_table_get_entry (reg->table, virt_loc);
1304 if (!help || *help == '\0')
1305 help = reg->use_tran_num_for_num_field ?
1306 _ ("Enter an action type, or choose one from the list") :
1307 _ ("Enter a reference number, such as the next check number, or choose an action type from the list");
1308
1309 return g_strdup (help);
1310 }
1311
1312 static const char*
gnc_split_register_get_memo_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1313 gnc_split_register_get_memo_entry (VirtualLocation virt_loc,
1314 gboolean translate,
1315 gboolean* conditionally_changed,
1316 gpointer user_data)
1317 {
1318 SplitRegister* reg = user_data;
1319 Split* split;
1320
1321 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1322
1323 return xaccSplitGetMemo (split);
1324 }
1325
1326 static char*
gnc_split_register_get_memo_help(VirtualLocation virt_loc,gpointer user_data)1327 gnc_split_register_get_memo_help (VirtualLocation virt_loc,
1328 gpointer user_data)
1329 {
1330 SplitRegister* reg = user_data;
1331 const char* help;
1332
1333 help = gnc_table_get_entry (reg->table, virt_loc);
1334 if (!help || *help == '\0')
1335 help = _ ("Enter a description of the split");
1336 return g_strdup (help);
1337 }
1338
1339 static const char*
gnc_split_register_get_balance_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1340 gnc_split_register_get_balance_entry (VirtualLocation virt_loc,
1341 gboolean translate,
1342 gboolean* conditionally_changed,
1343 gpointer user_data)
1344 {
1345 SplitRegister* reg = user_data;
1346 SRInfo* info = gnc_split_register_get_info (reg);
1347 gnc_numeric balance;
1348 gboolean is_trans;
1349 Split* split;
1350 Account* account;
1351
1352 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1353 if (split == xaccSplitLookup (&info->blank_split_guid,
1354 gnc_get_current_book()))
1355 return NULL;
1356
1357 is_trans = gnc_cell_name_equal
1358 (gnc_table_get_cell_name (reg->table, virt_loc), TBALN_CELL);
1359
1360 if (is_trans)
1361 balance = get_trans_total_balance (reg, xaccSplitGetParent (split));
1362 else
1363 balance = xaccSplitGetBalance (split);
1364
1365 account = xaccSplitGetAccount (split);
1366 if (!account)
1367 account = gnc_split_register_get_default_account (reg);
1368
1369 if (gnc_reverse_balance (account))
1370 balance = gnc_numeric_neg (balance);
1371
1372 return xaccPrintAmount (balance, gnc_account_print_info (account,
1373 reg->mismatched_commodities));
1374 }
1375
1376 static const char*
gnc_split_register_get_price_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1377 gnc_split_register_get_price_entry (VirtualLocation virt_loc,
1378 gboolean translate,
1379 gboolean* conditionally_changed,
1380 gpointer user_data)
1381 {
1382 SplitRegister* reg = user_data;
1383 gnc_numeric price;
1384 gnc_commodity* curr;
1385 Split* split;
1386
1387 if (!gnc_split_register_use_security_cells (reg, virt_loc))
1388 return NULL;
1389
1390 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1391
1392 if (gnc_numeric_zero_p (xaccSplitGetAmount(split)) ||
1393 gnc_numeric_zero_p (xaccSplitGetValue(split)))
1394 return NULL;
1395
1396 price = xaccSplitGetSharePrice (split);
1397 curr = xaccTransGetCurrency (xaccSplitGetParent (split));
1398 return xaccPrintAmount (price, gnc_default_price_print_info (curr));
1399 }
1400
1401 static char*
gnc_split_register_get_price_help(VirtualLocation virt_loc,gpointer user_data)1402 gnc_split_register_get_price_help (VirtualLocation virt_loc,
1403 gpointer user_data)
1404 {
1405 SplitRegister* reg = user_data;
1406 const char* help;
1407
1408 help = gnc_table_get_entry (reg->table, virt_loc);
1409 if (!help || *help == '\0')
1410 help = _ ("Enter the effective share price");
1411
1412 return g_strdup (help);
1413 }
1414
1415 static const char*
gnc_split_register_get_shares_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1416 gnc_split_register_get_shares_entry (VirtualLocation virt_loc,
1417 gboolean translate,
1418 gboolean* conditionally_changed,
1419 gpointer user_data)
1420 {
1421 SplitRegister* reg = user_data;
1422 gnc_numeric shares;
1423 Split* split;
1424
1425 if (!gnc_split_register_use_security_cells (reg, virt_loc))
1426 return NULL;
1427
1428 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1429
1430 shares = xaccSplitGetAmount (split);
1431 if (gnc_numeric_zero_p (shares))
1432 return NULL;
1433
1434 return xaccPrintAmount (shares, gnc_split_amount_print_info (split, FALSE));
1435 }
1436
1437 static char*
gnc_split_register_get_shares_help(VirtualLocation virt_loc,gpointer user_data)1438 gnc_split_register_get_shares_help (VirtualLocation virt_loc,
1439 gpointer user_data)
1440 {
1441 SplitRegister* reg = user_data;
1442 const char* help;
1443
1444 help = gnc_table_get_entry (reg->table, virt_loc);
1445 if (!help || *help == '\0')
1446 help = _ ("Enter the number of shares bought or sold");
1447
1448 return g_strdup (help);
1449 }
1450
1451 static const char*
gnc_split_register_get_tshares_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1452 gnc_split_register_get_tshares_entry (VirtualLocation virt_loc,
1453 gboolean translate,
1454 gboolean* conditionally_changed,
1455 gpointer user_data)
1456 {
1457 SplitRegister* reg = user_data;
1458 gnc_numeric total;
1459 Split* split;
1460
1461 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1462
1463 total = get_trans_total_amount (reg, xaccSplitGetParent (split));
1464
1465 return xaccPrintAmount (total, gnc_split_amount_print_info (split, FALSE));
1466 }
1467
1468 static const char*
gnc_split_register_get_xfrm_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1469 gnc_split_register_get_xfrm_entry (VirtualLocation virt_loc,
1470 gboolean translate,
1471 gboolean* conditionally_changed,
1472 gpointer user_data)
1473 {
1474 static char* name = NULL;
1475
1476 SplitRegister* reg = user_data;
1477 Split* split;
1478
1479 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1480
1481 g_free (name);
1482
1483 name = gnc_get_account_name_for_split_register (xaccSplitGetAccount (split),
1484 reg->show_leaf_accounts);
1485
1486 return name;
1487 }
1488
1489 static char*
gnc_split_register_get_xfrm_help(VirtualLocation virt_loc,gpointer user_data)1490 gnc_split_register_get_xfrm_help (VirtualLocation virt_loc,
1491 gpointer user_data)
1492 {
1493 SplitRegister* reg = user_data;
1494 const char* help;
1495
1496 help = gnc_table_get_entry (reg->table, virt_loc);
1497 if (!help || *help == '\0')
1498 help = _ ("Enter the account to transfer from, "
1499 "or choose one from the list");
1500
1501 return g_strdup (help);
1502 }
1503
1504 static const char*
gnc_split_register_get_mxfrm_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1505 gnc_split_register_get_mxfrm_entry (VirtualLocation virt_loc,
1506 gboolean translate,
1507 gboolean* conditionally_changed,
1508 gpointer user_data)
1509 {
1510 static char* name = NULL;
1511
1512 SplitRegister* reg = user_data;
1513 Split* split;
1514 Split* s;
1515
1516 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1517 if (!split)
1518 return NULL;
1519
1520 s = xaccSplitGetOtherSplit (split);
1521
1522 g_free (name);
1523
1524 if (s)
1525 name = gnc_get_account_name_for_split_register (xaccSplitGetAccount (s),
1526 reg->show_leaf_accounts);
1527 else
1528 {
1529 /* For multi-split transactions and stock splits,
1530 * use a special value. */
1531 s = xaccTransGetSplit (xaccSplitGetParent (split), 1);
1532
1533 if (s)
1534 name = g_strdup (SPLIT_TRANS_STR);
1535 else if (g_strcmp0 ("stock-split", xaccSplitGetType (split)) == 0)
1536 name = g_strdup (STOCK_SPLIT_STR);
1537 else
1538 name = g_strdup ("");
1539 }
1540
1541 return name;
1542 }
1543
1544 static char*
gnc_split_register_get_mxfrm_help(VirtualLocation virt_loc,gpointer user_data)1545 gnc_split_register_get_mxfrm_help (VirtualLocation virt_loc,
1546 gpointer user_data)
1547 {
1548 const char* help;
1549
1550 SplitRegister* reg = user_data;
1551 Split* split;
1552 Split* s;
1553
1554 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1555 if (!split)
1556 return NULL;
1557
1558 s = xaccSplitGetOtherSplit (split);
1559
1560 if (s)
1561 {
1562 help = gnc_split_register_get_mxfrm_entry (virt_loc, FALSE,
1563 NULL, user_data);
1564 if (!help || *help == '\0')
1565 help = _ ("Enter the account to transfer from, "
1566 "or choose one from the list");
1567 }
1568 else
1569 {
1570 /* For multi-split transactions and stock splits,
1571 * use a special value. */
1572 s = xaccTransGetSplit (xaccSplitGetParent (split), 1);
1573
1574 if (s)
1575 help = _ ("This transaction has multiple splits; "
1576 "press the Split button to see them all");
1577 else if (g_strcmp0 ("stock-split", xaccSplitGetType (split)) == 0)
1578 help = _ ("This transaction is a stock split; "
1579 "press the Split button to see details");
1580 else
1581 help = "";
1582 }
1583
1584 return g_strdup (help);
1585 }
1586
1587 /* Return the total value in the register currency of the transaction
1588 * for splits of default account and all subaccounts of the register.
1589 */
1590 static gnc_numeric
get_trans_total_value_subaccounts(SplitRegister * reg,Transaction * trans)1591 get_trans_total_value_subaccounts (SplitRegister* reg, Transaction* trans)
1592 {
1593 GList* children, *child;
1594 Account* parent;
1595 gnc_numeric total = gnc_numeric_zero();
1596
1597 /* Get a list of all subaccounts for matching */
1598 parent = gnc_split_register_get_default_account (reg);
1599 if (!parent)
1600 /* Register has no account, perhaps it's the general journal. If it
1601 has no account then we have no way of picking out the desired splits,
1602 return zero. */
1603 return total;
1604
1605 children = gnc_account_get_descendants (parent);
1606 children = g_list_prepend (children, parent);
1607
1608 for (child = children; child; child = child->next)
1609 {
1610 total = gnc_numeric_add_fixed (total, xaccTransGetAccountValue (trans,
1611 child->data));
1612 }
1613
1614 g_list_free (children);
1615
1616 return total;
1617 }
1618
1619 static const char*
gnc_split_register_get_tdebcred_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1620 gnc_split_register_get_tdebcred_entry (VirtualLocation virt_loc,
1621 gboolean translate,
1622 gboolean* conditionally_changed,
1623 gpointer user_data)
1624 {
1625 SplitRegister* reg = user_data;
1626 const char* cell_name;
1627 gnc_numeric total;
1628 Split* split;
1629
1630 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1631 if (!split)
1632 return NULL;
1633
1634 cell_name = gnc_table_get_cell_name (reg->table, virt_loc);
1635
1636 switch (reg->type)
1637 {
1638 case GENERAL_JOURNAL:
1639 case INCOME_LEDGER:
1640 total = get_trans_total_value_subaccounts (reg, xaccSplitGetParent (split));
1641 break;
1642 default:
1643 total = get_trans_total_amount (reg, xaccSplitGetParent (split));
1644 break;
1645 }
1646
1647 if (gnc_numeric_zero_p (total))
1648 return NULL;
1649
1650 if (gnc_numeric_negative_p (total) &&
1651 gnc_cell_name_equal (cell_name, TDEBT_CELL))
1652 return NULL;
1653
1654 if (gnc_numeric_positive_p (total) &&
1655 gnc_cell_name_equal (cell_name, TCRED_CELL))
1656 return NULL;
1657
1658 total = gnc_numeric_abs (total);
1659
1660 return xaccPrintAmount (total, gnc_split_amount_print_info (split,
1661 reg->mismatched_commodities));
1662 }
1663
1664 /* return TRUE if we have a RATE_CELL; return FALSE if we do not.
1665 * (note: should match split-register-layout.c)
1666 */
1667 gboolean
gnc_split_reg_has_rate_cell(SplitRegisterType type)1668 gnc_split_reg_has_rate_cell (SplitRegisterType type)
1669 {
1670 switch (type)
1671 {
1672 case BANK_REGISTER:
1673 case CASH_REGISTER:
1674 case ASSET_REGISTER:
1675 case CREDIT_REGISTER:
1676 case LIABILITY_REGISTER:
1677 case INCOME_REGISTER:
1678 case EXPENSE_REGISTER:
1679 case EQUITY_REGISTER:
1680 case TRADING_REGISTER:
1681 case GENERAL_JOURNAL:
1682 case INCOME_LEDGER:
1683 case SEARCH_LEDGER:
1684 return TRUE;
1685
1686 case STOCK_REGISTER:
1687 case CURRENCY_REGISTER:
1688 case PORTFOLIO_LEDGER:
1689 case RECEIVABLE_REGISTER:
1690 case PAYABLE_REGISTER:
1691 default:
1692 return FALSE;
1693 }
1694 }
1695
1696 /* returns TRUE if you need to convert the split's value to the local
1697 * (account) display currency. Returns FALSE if you can just use the
1698 * split->value directly.
1699 */
1700 gboolean
gnc_split_register_needs_conv_rate(SplitRegister * reg,Transaction * txn,Account * acc)1701 gnc_split_register_needs_conv_rate (SplitRegister* reg,
1702 Transaction* txn, Account* acc)
1703 {
1704 gnc_commodity* txn_cur, *acc_com;
1705
1706 /* If there is not a RATE_CELL, then don't do anything */
1707 if (!gnc_split_reg_has_rate_cell (reg->type))
1708 return FALSE;
1709
1710 /* if txn->currency == acc->commodity, then return FALSE */
1711 acc_com = xaccAccountGetCommodity (acc);
1712 txn_cur = xaccTransGetCurrency (txn);
1713 if (txn_cur && acc_com && gnc_commodity_equal (txn_cur, acc_com))
1714 return FALSE;
1715
1716 return TRUE;
1717 }
1718
1719 static const char*
gnc_split_register_get_debcred_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1720 gnc_split_register_get_debcred_entry (VirtualLocation virt_loc,
1721 gboolean translate,
1722 gboolean* conditionally_changed,
1723 gpointer user_data)
1724 {
1725 SplitRegister* reg = user_data;
1726 gboolean is_debit;
1727 Split* split;
1728 Transaction* trans;
1729 gnc_commodity* currency;
1730
1731 is_debit = gnc_cell_name_equal
1732 (gnc_table_get_cell_name (reg->table, virt_loc), DEBT_CELL);
1733
1734 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1735 trans = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
1736
1737 currency = xaccTransGetCurrency (trans);
1738 if (!currency)
1739 currency = gnc_default_currency();
1740
1741 if (!split)
1742 {
1743 gnc_numeric imbalance;
1744 Account* acc;
1745
1746 imbalance = xaccTransGetImbalanceValue (trans);
1747
1748 if (gnc_numeric_zero_p (imbalance))
1749 return NULL;
1750
1751 if (xaccTransUseTradingAccounts (trans))
1752 {
1753 MonetaryList* imbal_list;
1754 gnc_monetary* imbal_mon;
1755 imbal_list = xaccTransGetImbalance (trans);
1756
1757 if (!imbal_list)
1758 {
1759 /* No commodity imbalance, there shouldn't be a value imablance. */
1760 return NULL;
1761 }
1762
1763 if (imbal_list->next)
1764 {
1765 /* Multiple currency imbalance. */
1766 gnc_monetary_list_free (imbal_list);
1767 return NULL;
1768 }
1769
1770 imbal_mon = imbal_list->data;
1771 if (!gnc_commodity_equal (gnc_monetary_commodity (*imbal_mon), currency))
1772 {
1773 /* Imbalance is in wrong currency */
1774 gnc_monetary_list_free (imbal_list);
1775 return NULL;
1776 }
1777
1778 if (!gnc_numeric_equal (gnc_monetary_value (*imbal_mon), imbalance))
1779 {
1780 /* Value and commodity imbalances differ */
1781 gnc_monetary_list_free (imbal_list);
1782 return NULL;
1783 }
1784
1785 /* Done with the imbalance list */
1786 gnc_monetary_list_free (imbal_list);
1787 }
1788
1789 imbalance = gnc_numeric_neg (imbalance);
1790
1791 if (gnc_numeric_negative_p (imbalance) && is_debit)
1792 return NULL;
1793
1794 if (gnc_numeric_positive_p (imbalance) && !is_debit)
1795 return NULL;
1796
1797 if (conditionally_changed)
1798 *conditionally_changed = TRUE;
1799
1800 imbalance = gnc_numeric_abs (imbalance);
1801
1802 acc = gnc_split_register_get_default_account (reg);
1803 if (gnc_split_register_needs_conv_rate (reg, trans, acc))
1804 {
1805 imbalance = gnc_numeric_mul (imbalance,
1806 xaccTransGetAccountConvRate (trans, acc),
1807 gnc_commodity_get_fraction (currency),
1808 GNC_HOW_RND_ROUND_HALF_UP);
1809 }
1810 else
1811 {
1812 imbalance = gnc_numeric_convert (imbalance,
1813 gnc_commodity_get_fraction (currency),
1814 GNC_HOW_RND_ROUND_HALF_UP);
1815 }
1816
1817 return xaccPrintAmount (imbalance, gnc_account_print_info (acc,
1818 reg->mismatched_commodities));
1819 }
1820
1821 {
1822 gnc_numeric amount;
1823 gnc_commodity* split_commodity;
1824 GNCPrintAmountInfo print_info;
1825 Account* account;
1826 gnc_commodity* commodity;
1827
1828 account = gnc_split_register_get_default_account (reg);
1829 commodity = xaccAccountGetCommodity (account);
1830 split_commodity = xaccAccountGetCommodity (xaccSplitGetAccount (split));
1831
1832 if (xaccTransUseTradingAccounts (trans))
1833 {
1834 gboolean use_symbol, is_current;
1835 is_current = virt_cell_loc_equal (reg->table->current_cursor_loc.vcell_loc,
1836 virt_loc.vcell_loc);
1837
1838 if (reg->type == STOCK_REGISTER ||
1839 reg->type == CURRENCY_REGISTER ||
1840 reg->type == PORTFOLIO_LEDGER)
1841 {
1842 gnc_commodity* amount_commodity;
1843 /* security register. If this split has price and shares columns,
1844 use the value, otherwise use the amount. */
1845 if (gnc_split_register_use_security_cells (reg, virt_loc))
1846 {
1847 amount = xaccSplitGetValue (split);
1848 amount_commodity = currency;
1849 }
1850 else
1851 {
1852 amount = xaccSplitGetAmount (split);
1853 amount_commodity = split_commodity;
1854 }
1855 /* Show the currency if it is not the default currency */
1856 if (is_current ||
1857 gnc_commodity_equiv (amount_commodity, gnc_default_currency()))
1858 use_symbol = FALSE;
1859 else
1860 use_symbol = TRUE;
1861 print_info = gnc_commodity_print_info (amount_commodity, use_symbol);
1862 }
1863 else
1864 {
1865 /* non-security register, always use the split amount. */
1866 amount = xaccSplitGetAmount (split);
1867 if (is_current ||
1868 gnc_commodity_equiv (split_commodity, commodity))
1869 use_symbol = FALSE;
1870 else
1871 use_symbol = TRUE;
1872 print_info = gnc_commodity_print_info (split_commodity, use_symbol);
1873 }
1874 }
1875 else
1876 {
1877 gboolean currency_match;
1878 switch (reg->type)
1879 {
1880 case STOCK_REGISTER:
1881 case CURRENCY_REGISTER:
1882 case PORTFOLIO_LEDGER:
1883 amount = xaccSplitGetValue (split);
1884 print_info = gnc_commodity_print_info (currency, reg->mismatched_commodities);
1885 break;
1886
1887 /* If the register is not a stock/fund register that
1888 * displays both amount and value, display the split value
1889 * in the register's currency instead of the transaction's
1890 * currency. Note that we don't want the split amount as
1891 * some splits will be in a different currency.
1892 */
1893 default:
1894 if (commodity && !gnc_commodity_equal (commodity, currency))
1895 /* Convert this to the "local" value */
1896 amount = xaccSplitConvertAmount(split, account);
1897 else
1898 amount = xaccSplitGetValue (split);
1899
1900 print_info = gnc_account_print_info (account, reg->mismatched_commodities);
1901 print_info.commodity = commodity;
1902 break;
1903 }
1904 }
1905
1906 if (gnc_numeric_zero_p (amount))
1907 return NULL;
1908
1909 if (gnc_numeric_negative_p (amount) && is_debit)
1910 return NULL;
1911
1912 if (gnc_numeric_positive_p (amount) && !is_debit)
1913 return NULL;
1914
1915 amount = gnc_numeric_abs (amount);
1916
1917 return xaccPrintAmount (amount, print_info);
1918 }
1919 }
1920
1921 /* Calculates the register balance for each split at runtime.
1922 * This works regardless of the sort order. */
1923 static const char*
gnc_split_register_get_rbaln_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)1924 gnc_split_register_get_rbaln_entry (VirtualLocation virt_loc,
1925 gboolean translate,
1926 gboolean* conditionally_changed,
1927 gpointer user_data)
1928 {
1929 SplitRegister* reg = user_data;
1930 SRInfo* info = gnc_split_register_get_info (reg);
1931 Split* split;
1932 Transaction* trans;
1933 gnc_numeric balance;
1934 Account* account;
1935
1936 /* Return NULL if this is a blank transaction. */
1937 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1938 if (split == xaccSplitLookup (&info->blank_split_guid,
1939 gnc_get_current_book()))
1940 return NULL;
1941
1942 trans = xaccSplitGetParent (split);
1943 if (!trans)
1944 return NULL;
1945
1946 balance = gnc_split_register_get_rbaln (virt_loc, user_data, TRUE);
1947
1948 account = xaccSplitGetAccount (split);
1949 if (!account)
1950 account = gnc_split_register_get_default_account (reg);
1951
1952 if (gnc_reverse_balance (account))
1953 balance = gnc_numeric_neg (balance);
1954
1955 return xaccPrintAmount (balance, gnc_account_print_info (account, FALSE));
1956 }
1957
1958 static gboolean
gnc_split_register_cursor_is_readonly(VirtualLocation virt_loc,gpointer user_data)1959 gnc_split_register_cursor_is_readonly (VirtualLocation virt_loc,
1960 gpointer user_data)
1961 {
1962 SplitRegister* reg = user_data;
1963 Split* split;
1964 Transaction* txn;
1965 char type;
1966
1967 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
1968
1969 if (!split) // this could be the blank split
1970 {
1971 txn = gnc_split_register_get_current_trans (reg);
1972
1973 if (txn) // get the current trans and see if read_only required
1974 {
1975 if (xaccTransGetReadOnly (txn)
1976 || xaccTransIsReadonlyByPostedDate (txn))
1977 return (TRUE);
1978 }
1979 return FALSE;
1980 }
1981
1982 txn = xaccSplitGetParent (split);
1983 if (!txn) return FALSE;
1984
1985 if (xaccTransGetReadOnly (txn)
1986 || xaccTransIsReadonlyByPostedDate (txn))
1987 return (TRUE);
1988
1989 type = xaccTransGetTxnType (txn);
1990 return (type == TXN_TYPE_INVOICE);
1991 }
1992
1993 static CellIOFlags
gnc_split_register_get_inactive_io_flags(VirtualLocation virt_loc,gpointer user_data)1994 gnc_split_register_get_inactive_io_flags (VirtualLocation virt_loc,
1995 gpointer user_data)
1996 {
1997 if (gnc_split_register_cursor_is_readonly (virt_loc, user_data))
1998 return XACC_CELL_ALLOW_READ_ONLY;
1999
2000 return XACC_CELL_ALLOW_NONE;
2001 }
2002
2003 static CellIOFlags
gnc_split_register_get_standard_io_flags(VirtualLocation virt_loc,gpointer user_data)2004 gnc_split_register_get_standard_io_flags (VirtualLocation virt_loc,
2005 gpointer user_data)
2006 {
2007 if (gnc_split_register_cursor_is_readonly (virt_loc, user_data))
2008 return XACC_CELL_ALLOW_READ_ONLY;
2009
2010 return XACC_CELL_ALLOW_ALL;
2011 }
2012
2013 static CellIOFlags
gnc_split_register_get_recn_io_flags(VirtualLocation virt_loc,gpointer user_data)2014 gnc_split_register_get_recn_io_flags (VirtualLocation virt_loc,
2015 gpointer user_data)
2016 {
2017 if (gnc_split_register_cursor_is_readonly (virt_loc, user_data))
2018 return XACC_CELL_ALLOW_READ_ONLY;
2019
2020 return XACC_CELL_ALLOW_ALL | XACC_CELL_ALLOW_EXACT_ONLY;
2021 }
2022
2023 static CellIOFlags
gnc_split_register_get_doclink_io_flags(VirtualLocation virt_loc,gpointer user_data)2024 gnc_split_register_get_doclink_io_flags (VirtualLocation virt_loc,
2025 gpointer user_data)
2026 {
2027 if (gnc_split_register_cursor_is_readonly (virt_loc, user_data))
2028 return XACC_CELL_ALLOW_READ_ONLY;
2029
2030 return XACC_CELL_ALLOW_ALL | XACC_CELL_ALLOW_EXACT_ONLY;
2031 }
2032
2033 static CellIOFlags
gnc_split_register_get_ddue_io_flags(VirtualLocation virt_loc,gpointer user_data)2034 gnc_split_register_get_ddue_io_flags (VirtualLocation virt_loc,
2035 gpointer user_data)
2036 {
2037 SplitRegister* reg = user_data;
2038 char type;
2039
2040 type = gnc_split_register_get_type_value (reg, virt_loc);
2041
2042 /* Only print the due date for invoice transactions */
2043 if (type != TXN_TYPE_INVOICE)
2044 {
2045 return XACC_CELL_ALLOW_NONE;
2046 }
2047
2048 return XACC_CELL_ALLOW_READ_ONLY;
2049 }
2050
2051 static CellIOFlags
gnc_split_register_get_rate_io_flags(VirtualLocation virt_loc,gpointer user_data)2052 gnc_split_register_get_rate_io_flags (VirtualLocation virt_loc,
2053 gpointer user_data)
2054 {
2055 return XACC_CELL_ALLOW_SHADOW;
2056 }
2057
2058 static CellIOFlags
gnc_split_register_get_debcred_io_flags(VirtualLocation virt_loc,gpointer user_data)2059 gnc_split_register_get_debcred_io_flags (VirtualLocation virt_loc,
2060 gpointer user_data)
2061 {
2062 SplitRegister* reg = user_data;
2063 Split* split;
2064
2065 if (gnc_split_register_cursor_is_readonly (virt_loc, user_data))
2066 return XACC_CELL_ALLOW_READ_ONLY;
2067
2068 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
2069
2070 if (g_strcmp0 ("stock-split", xaccSplitGetType (split)) == 0)
2071 return XACC_CELL_ALLOW_NONE;
2072
2073 return XACC_CELL_ALLOW_ALL;
2074 }
2075
2076 static CellIOFlags
gnc_split_register_get_security_io_flags(VirtualLocation virt_loc,gpointer user_data)2077 gnc_split_register_get_security_io_flags (VirtualLocation virt_loc,
2078 gpointer user_data)
2079 {
2080 SplitRegister* reg = user_data;
2081
2082 if (gnc_split_register_cursor_is_readonly (virt_loc, user_data))
2083 return XACC_CELL_ALLOW_READ_ONLY;
2084
2085 if (gnc_split_register_use_security_cells (reg, virt_loc))
2086 return XACC_CELL_ALLOW_ALL;
2087
2088 return XACC_CELL_ALLOW_SHADOW;
2089 }
2090
2091 static gboolean
xaccTransWarnReadOnly(GtkWidget * parent,Transaction * trans)2092 xaccTransWarnReadOnly (GtkWidget* parent, Transaction* trans)
2093 {
2094 GtkWidget* dialog;
2095 const gchar* reason;
2096 const gchar* format =
2097 _ ("Cannot modify or delete this transaction. This transaction is "
2098 "marked read-only because:\n\n'%s'");
2099
2100 if (!trans) return FALSE;
2101
2102 reason = xaccTransGetReadOnly (trans);
2103 if (reason)
2104 {
2105 dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
2106 0,
2107 GTK_MESSAGE_ERROR,
2108 GTK_BUTTONS_OK,
2109 format,
2110 reason);
2111 gtk_dialog_run (GTK_DIALOG (dialog));
2112 gtk_widget_destroy (dialog);
2113 return TRUE;
2114 }
2115 return FALSE;
2116 }
2117
reg_trans_has_reconciled_splits(SplitRegister * reg,Transaction * trans)2118 static gboolean reg_trans_has_reconciled_splits (SplitRegister* reg,
2119 Transaction* trans)
2120 {
2121 GList* node;
2122
2123 for (node = xaccTransGetSplitList (trans); node; node = node->next)
2124 {
2125 Split* split = node->data;
2126
2127 if (!xaccTransStillHasSplit (trans, split))
2128 continue;
2129
2130 if ((xaccSplitGetReconcile (split) == YREC) &&
2131 (g_list_index (reg->unrecn_splits, split) == -1))
2132 return TRUE;
2133 }
2134
2135 return FALSE;
2136 }
2137
2138 static gboolean
gnc_split_register_confirm(VirtualLocation virt_loc,gpointer user_data)2139 gnc_split_register_confirm (VirtualLocation virt_loc, gpointer user_data)
2140 {
2141 SplitRegister* reg = user_data;
2142 SRInfo* info = gnc_split_register_get_info (reg);
2143 Transaction* trans;
2144 Split* split;
2145 char recn;
2146 const char* cell_name;
2147 gboolean protected_split_cell, protected_trans_cell;
2148 const gchar* title = NULL;
2149 const gchar* message = NULL;
2150
2151 /* This assumes we reset the flag whenever we change splits.
2152 * This happens in gnc_split_register_move_cursor(). */
2153 if (info->change_confirmed)
2154 return TRUE;
2155
2156 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
2157 if (!split)
2158 return TRUE;
2159
2160 trans = xaccSplitGetParent (split);
2161 if (xaccTransWarnReadOnly (gnc_split_register_get_parent (reg), trans))
2162 return FALSE;
2163
2164 if (!reg_trans_has_reconciled_splits (reg, trans))
2165 return TRUE;
2166
2167 if (gnc_table_layout_get_cell_changed (reg->table->layout, RECN_CELL, FALSE))
2168 recn = gnc_recn_cell_get_flag
2169 ((RecnCell*) gnc_table_layout_get_cell (reg->table->layout, RECN_CELL));
2170 else if (g_list_index (reg->unrecn_splits, split) != -1)
2171 recn = NREC; /* A previous run of this function marked this split for unreconciling */
2172 else
2173 recn = xaccSplitGetReconcile (split);
2174
2175 /* What Cell are we in */
2176 cell_name = gnc_table_get_cell_name (reg->table, virt_loc);
2177
2178 /* if we change a transfer cell, we want the other split */
2179 if (g_strcmp0 (cell_name, "transfer") == 0)
2180 recn = xaccSplitGetReconcile (xaccSplitGetOtherSplit (split));
2181
2182 /* These cells can not be changed */
2183 protected_split_cell = (g_strcmp0 (cell_name, "account") == 0) ||
2184 (g_strcmp0 (cell_name, "transfer") == 0) ||
2185 (g_strcmp0 (cell_name, "debit") == 0) ||
2186 (g_strcmp0 (cell_name, "credit") == 0);
2187 protected_trans_cell = (g_strcmp0 (cell_name, "date") == 0) ||
2188 (g_strcmp0 (cell_name, "num") == 0) ||
2189 (g_strcmp0 (cell_name, "description") == 0);
2190
2191 PINFO ("Protected transaction cell %d, Protected split cell %d, Cell is %s",
2192 protected_trans_cell, protected_split_cell, cell_name);
2193
2194 if (protected_trans_cell)
2195 {
2196 GList* acc_g_list = NULL;
2197 gchar* acc_list = NULL;
2198 gchar* message_format;
2199
2200 for (GList *node = xaccTransGetSplitList (trans); node; node = node->next)
2201 {
2202 Split* split = node->data;
2203 if (xaccSplitGetReconcile (split) == YREC)
2204 {
2205 gchar* name = gnc_account_get_full_name (xaccSplitGetAccount (split));
2206 acc_g_list = g_list_prepend (acc_g_list, name);
2207 }
2208 }
2209 acc_list = gnc_g_list_stringjoin (acc_g_list, "\n");
2210 title = _ ("Change transaction containing a reconciled split?");
2211 message_format =
2212 _ ("The transaction you are about to change contains reconciled splits in the following accounts:\n%s"
2213 "\n\nAre you sure you want to continue with this change?");
2214
2215 message = g_strdup_printf (message_format, acc_list);
2216 g_list_free_full (acc_g_list, g_free);
2217 g_free (acc_list);
2218 }
2219
2220 if (protected_split_cell)
2221 {
2222 title = _ ("Change reconciled split?");
2223 message =
2224 _ ("You are about to change a protected field of a reconciled split. "
2225 "If you continue editing this split it will be unreconciled. "
2226 "This might make future reconciliation difficult! Continue with this change?");
2227 }
2228
2229 if ((recn == YREC && protected_split_cell) || protected_trans_cell)
2230 {
2231 GtkWidget* dialog, *window;
2232 gint response;
2233
2234 /* Does the user want to be warned? */
2235 window = gnc_split_register_get_parent (reg);
2236 dialog =
2237 gtk_message_dialog_new (GTK_WINDOW (window),
2238 GTK_DIALOG_DESTROY_WITH_PARENT,
2239 GTK_MESSAGE_WARNING,
2240 GTK_BUTTONS_CANCEL,
2241 "%s", title);
2242 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
2243 "%s", message);
2244
2245 if (protected_split_cell)
2246 gtk_dialog_add_button (GTK_DIALOG (dialog), _ ("Chan_ge Split"),
2247 GTK_RESPONSE_YES);
2248 else
2249 gtk_dialog_add_button (GTK_DIALOG (dialog), _ ("Chan_ge Transaction"),
2250 GTK_RESPONSE_YES);
2251 response = gnc_dialog_run (GTK_DIALOG (dialog),
2252 GNC_PREF_WARN_REG_RECD_SPLIT_MOD);
2253 gtk_widget_destroy (dialog);
2254 if (response != GTK_RESPONSE_YES)
2255 return FALSE;
2256
2257 // Response is Change, so record the splits
2258 if (recn == YREC && protected_split_cell)
2259 {
2260 if (g_list_index (reg->unrecn_splits, split) == -1)
2261 {
2262 reg->unrecn_splits = g_list_append (reg->unrecn_splits, split);
2263 gnc_recn_cell_set_flag
2264 ((RecnCell*) gnc_table_layout_get_cell (reg->table->layout, RECN_CELL),
2265 NREC);
2266 }
2267 }
2268
2269 PINFO ("Unreconcile split list length is %d",
2270 g_list_length (reg->unrecn_splits));
2271 info->change_confirmed = TRUE;
2272 }
2273 return TRUE;
2274 }
2275
2276 static gpointer
gnc_split_register_guid_malloc(void)2277 gnc_split_register_guid_malloc (void)
2278 {
2279 GncGUID* guid;
2280
2281 guid = guid_malloc();
2282
2283 *guid = *guid_null();
2284
2285 return guid;
2286 }
2287
2288 static const char*
gnc_template_register_get_xfrm_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)2289 gnc_template_register_get_xfrm_entry (VirtualLocation virt_loc,
2290 gboolean translate,
2291 gboolean* conditionally_changed,
2292 gpointer user_data)
2293 {
2294 static char* name = NULL;
2295
2296 SplitRegister* reg = user_data;
2297 Split* split;
2298 Account* account;
2299 GncGUID* guid = NULL;
2300
2301 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
2302 if (!split)
2303 return NULL;
2304 /* Caller either uses the return as a temporary in a boolean
2305 * expression or g_strdups it, so we keep it static and free the
2306 * old one on every call to avoid leaks. Ugly, but it works.
2307 */
2308 g_free (name);
2309 qof_instance_get (QOF_INSTANCE (split),
2310 "sx-account", &guid,
2311 NULL);
2312 account = xaccAccountLookup (guid, gnc_get_current_book());
2313 name = account ? gnc_get_account_name_for_split_register (account,
2314 reg->show_leaf_accounts) : NULL;
2315 return name;
2316 }
2317
2318 static const char*
gnc_template_register_get_fdebt_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)2319 gnc_template_register_get_fdebt_entry (VirtualLocation virt_loc,
2320 gboolean translate,
2321 gboolean* conditionally_changed,
2322 gpointer user_data)
2323 {
2324 SplitRegister* reg = user_data;
2325 Split* split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
2326 char* formula = NULL;
2327
2328 if (split)
2329 {
2330 qof_instance_get (QOF_INSTANCE (split),
2331 "sx-debit-formula", &formula,
2332 NULL);
2333 }
2334
2335 return formula;
2336 }
2337
2338 static char*
gnc_split_register_get_fdebt_help(VirtualLocation virt_loc,gpointer user_data)2339 gnc_split_register_get_fdebt_help (VirtualLocation virt_loc,
2340 gpointer user_data)
2341 {
2342 SplitRegister* reg = user_data;
2343 const char* help;
2344
2345 help = gnc_table_get_entry (reg->table, virt_loc);
2346 if (!help || *help == '\0')
2347 help = _ ("Enter debit formula for real transaction");
2348
2349 return g_strdup (help);
2350 }
2351
2352 static const char*
gnc_template_register_get_fcred_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)2353 gnc_template_register_get_fcred_entry (VirtualLocation virt_loc,
2354 gboolean translate,
2355 gboolean* conditionally_changed,
2356 gpointer user_data)
2357 {
2358 SplitRegister* reg = user_data;
2359 Split* split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
2360 char* formula = NULL;
2361
2362 if (split)
2363 {
2364 qof_instance_get (QOF_INSTANCE (split),
2365 "sx-credit-formula", &formula,
2366 NULL);
2367 }
2368
2369 return formula;
2370
2371 }
2372
2373 static char*
gnc_split_register_get_fcred_help(VirtualLocation virt_loc,gpointer user_data)2374 gnc_split_register_get_fcred_help (VirtualLocation virt_loc,
2375 gpointer user_data)
2376 {
2377 SplitRegister* reg = user_data;
2378 const char* help = gnc_table_get_entry (reg->table, virt_loc);
2379
2380 if (!help || *help == '\0')
2381 help = _ ("Enter credit formula for real transaction");
2382
2383 return g_strdup (help);
2384 }
2385
2386 static char*
gnc_split_register_get_default_help(VirtualLocation virt_loc,gpointer user_data)2387 gnc_split_register_get_default_help (VirtualLocation virt_loc,
2388 gpointer user_data)
2389 {
2390 SplitRegister* reg = user_data;
2391 const char* help = gnc_table_get_entry (reg->table, virt_loc);
2392
2393 return g_strdup (help);
2394 }
2395
2396 /* This function has been #if-zeroed for a year; in all released versions since
2397 * 2001 it has issued dire warnings about being wrong, and returned nothing
2398 * because it was querying a non-existent slot.
2399 *
2400 * Now it retrieves the sx-debit-numeric or sx-credit-numeric properties from
2401 * the split. I'm not sure that it's what was originally intended, but at least
2402 * it can do something now. <jralls, 8 June 2015>
2403 */
2404 static const char*
gnc_template_register_get_debcred_entry(VirtualLocation virt_loc,gboolean translate,gboolean * conditionally_changed,gpointer user_data)2405 gnc_template_register_get_debcred_entry (VirtualLocation virt_loc,
2406 gboolean translate,
2407 gboolean* conditionally_changed,
2408 gpointer user_data)
2409 {
2410 SplitRegister* reg = user_data;
2411 Split* split;
2412 gnc_numeric* amount, amount2;
2413 const char* cell_name;
2414
2415 split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
2416 if (!split)
2417 return gnc_split_register_get_debcred_entry (virt_loc,
2418 translate,
2419 conditionally_changed,
2420 user_data);
2421
2422 cell_name = gnc_table_get_cell_name (reg->table, virt_loc);
2423 if (gnc_cell_name_equal (cell_name, DEBT_CELL))
2424 qof_instance_get (QOF_INSTANCE (split),
2425 "sx-debit-numeric", &amount,
2426 NULL);
2427 else
2428 qof_instance_get (QOF_INSTANCE (split),
2429 "sx-credit-numeric", &amount,
2430 NULL);
2431 if (!amount)
2432 return "";
2433
2434 if (gnc_numeric_zero_p (*amount))
2435 {
2436 g_free (amount);
2437 return "";
2438 }
2439
2440 amount2 = gnc_numeric_abs (*amount);
2441 g_free (amount);
2442 return xaccPrintAmount (amount2,
2443 gnc_default_print_info (reg->mismatched_commodities));
2444 }
2445
2446 static void
gnc_split_register_guid_free(gpointer guid)2447 gnc_split_register_guid_free (gpointer guid)
2448 {
2449 guid_free (guid);
2450 }
2451
2452 static void
gnc_split_register_guid_copy(gpointer p_to,gconstpointer p_from)2453 gnc_split_register_guid_copy (gpointer p_to, gconstpointer p_from)
2454 {
2455 GncGUID* to = p_to;
2456 const GncGUID* from = p_from;
2457
2458 g_return_if_fail (to != NULL);
2459 *to = from ? *from : *guid_null();
2460 }
2461
2462
2463 static void
gnc_split_register_colorize_negative(gpointer gsettings,gchar * key,gpointer unused)2464 gnc_split_register_colorize_negative (gpointer gsettings, gchar* key,
2465 gpointer unused)
2466 {
2467 use_red_for_negative = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL,
2468 GNC_PREF_NEGATIVE_IN_RED);
2469 }
2470
2471
2472 static gpointer
gnc_split_register_model_add_hooks(gpointer unused)2473 gnc_split_register_model_add_hooks (gpointer unused)
2474 {
2475 gulong id = gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
2476 GNC_PREF_NEGATIVE_IN_RED,
2477 gnc_split_register_colorize_negative,
2478 NULL);
2479
2480 gnc_prefs_set_reg_negative_color_pref_id (id);
2481
2482 /* Get the initial value */
2483 use_red_for_negative = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL,
2484 GNC_PREF_NEGATIVE_IN_RED);
2485 return NULL;
2486 }
2487
2488
2489 TableModel*
gnc_split_register_model_new(void)2490 gnc_split_register_model_new (void)
2491 {
2492 TableModel* model;
2493 static GOnce once = G_ONCE_INIT;
2494
2495 g_once (&once, gnc_split_register_model_add_hooks, NULL);
2496
2497 model = gnc_table_model_new();
2498
2499 // entry handlers
2500 gnc_table_model_set_entry_handler (model,
2501 gnc_split_register_get_date_entry,
2502 DATE_CELL);
2503
2504 gnc_table_model_set_entry_handler (model,
2505 gnc_split_register_get_due_date_entry,
2506 DDUE_CELL);
2507
2508 gnc_table_model_set_entry_handler (model,
2509 gnc_split_register_get_num_entry,
2510 NUM_CELL);
2511
2512 gnc_table_model_set_entry_handler (model,
2513 gnc_split_register_get_tran_num_entry,
2514 TNUM_CELL);
2515
2516 gnc_table_model_set_entry_handler (model,
2517 gnc_split_register_get_desc_entry,
2518 DESC_CELL);
2519
2520 gnc_table_model_set_entry_handler (model,
2521 gnc_split_register_get_notes_entry,
2522 NOTES_CELL);
2523
2524 gnc_table_model_set_entry_handler (model,
2525 gnc_split_register_get_vnotes_entry,
2526 VNOTES_CELL);
2527
2528 gnc_table_model_set_entry_handler (model,
2529 gnc_split_register_get_rate_entry,
2530 RATE_CELL);
2531
2532 gnc_table_model_set_entry_handler (model,
2533 gnc_split_register_get_recn_entry,
2534 RECN_CELL);
2535
2536 gnc_table_model_set_entry_handler (model,
2537 gnc_split_register_get_action_entry,
2538 ACTN_CELL);
2539
2540 gnc_table_model_set_entry_handler (model,
2541 gnc_split_register_get_memo_entry,
2542 MEMO_CELL);
2543
2544 gnc_table_model_set_entry_handler (model,
2545 gnc_split_register_get_balance_entry,
2546 BALN_CELL);
2547
2548 gnc_table_model_set_entry_handler (model,
2549 gnc_split_register_get_balance_entry,
2550 TBALN_CELL);
2551
2552 gnc_table_model_set_entry_handler (model,
2553 gnc_split_register_get_price_entry,
2554 PRIC_CELL);
2555
2556 gnc_table_model_set_entry_handler (model,
2557 gnc_split_register_get_shares_entry,
2558 SHRS_CELL);
2559
2560 gnc_table_model_set_entry_handler (model,
2561 gnc_split_register_get_tshares_entry,
2562 TSHRS_CELL);
2563
2564 gnc_table_model_set_entry_handler (model,
2565 gnc_split_register_get_xfrm_entry,
2566 XFRM_CELL);
2567
2568 gnc_table_model_set_entry_handler (model,
2569 gnc_split_register_get_mxfrm_entry,
2570 MXFRM_CELL);
2571
2572 gnc_table_model_set_entry_handler (model,
2573 gnc_split_register_get_tdebcred_entry,
2574 TDEBT_CELL);
2575
2576 gnc_table_model_set_entry_handler (model,
2577 gnc_split_register_get_tdebcred_entry,
2578 TCRED_CELL);
2579
2580 gnc_table_model_set_entry_handler (model,
2581 gnc_split_register_get_doclink_entry,
2582 DOCLINK_CELL);
2583
2584 gnc_table_model_set_entry_handler (model,
2585 gnc_split_register_get_type_entry,
2586 TYPE_CELL);
2587
2588 gnc_table_model_set_entry_handler (model,
2589 gnc_split_register_get_debcred_entry,
2590 DEBT_CELL);
2591
2592 gnc_table_model_set_entry_handler (model,
2593 gnc_split_register_get_debcred_entry,
2594 CRED_CELL);
2595
2596 gnc_table_model_set_entry_handler (model,
2597 gnc_split_register_get_rbaln_entry,
2598 RBALN_CELL);
2599
2600 // label handlers
2601 gnc_table_model_set_label_handler (model,
2602 gnc_split_register_get_date_label,
2603 DATE_CELL);
2604
2605 gnc_table_model_set_label_handler (model,
2606 gnc_split_register_get_due_date_label,
2607 DDUE_CELL);
2608
2609 gnc_table_model_set_label_handler (model,
2610 gnc_split_register_get_num_label,
2611 NUM_CELL);
2612
2613 gnc_table_model_set_label_handler (model,
2614 gnc_split_register_get_tran_num_label,
2615 TNUM_CELL);
2616
2617 gnc_table_model_set_label_handler (model,
2618 gnc_split_register_get_desc_label,
2619 DESC_CELL);
2620
2621 gnc_table_model_set_label_handler (model,
2622 gnc_split_register_get_recn_label,
2623 RECN_CELL);
2624
2625 gnc_table_model_set_label_handler (model,
2626 gnc_split_register_get_baln_label,
2627 BALN_CELL);
2628
2629 gnc_table_model_set_label_handler (model,
2630 gnc_split_register_get_action_label,
2631 ACTN_CELL);
2632
2633 gnc_table_model_set_label_handler (model,
2634 gnc_split_register_get_xfrm_label,
2635 XFRM_CELL);
2636
2637 gnc_table_model_set_label_handler (model,
2638 gnc_split_register_get_memo_label,
2639 MEMO_CELL);
2640
2641 gnc_table_model_set_label_handler (model,
2642 gnc_split_register_get_debit_label,
2643 DEBT_CELL);
2644
2645 gnc_table_model_set_label_handler (model,
2646 gnc_split_register_get_credit_label,
2647 CRED_CELL);
2648
2649 gnc_table_model_set_label_handler (model,
2650 gnc_split_register_get_price_label,
2651 PRIC_CELL);
2652
2653 gnc_table_model_set_label_handler (model,
2654 gnc_split_register_get_rate_label,
2655 RATE_CELL);
2656
2657 gnc_table_model_set_label_handler (model,
2658 gnc_split_register_get_shares_label,
2659 SHRS_CELL);
2660
2661 gnc_table_model_set_label_handler (model,
2662 gnc_split_register_get_mxfrm_label,
2663 MXFRM_CELL);
2664
2665 gnc_table_model_set_label_handler (model,
2666 gnc_split_register_get_tcredit_label,
2667 TCRED_CELL);
2668
2669 gnc_table_model_set_label_handler (model,
2670 gnc_split_register_get_tdebit_label,
2671 TDEBT_CELL);
2672
2673 gnc_table_model_set_label_handler (model,
2674 gnc_split_register_get_tshares_label,
2675 TSHRS_CELL);
2676
2677 gnc_table_model_set_label_handler (model,
2678 gnc_split_register_get_tbalance_label,
2679 TBALN_CELL);
2680
2681 gnc_table_model_set_label_handler (model,
2682 gnc_split_register_get_doclink_label,
2683 DOCLINK_CELL);
2684
2685 gnc_table_model_set_label_handler (model,
2686 gnc_split_register_get_type_label,
2687 TYPE_CELL);
2688
2689 gnc_table_model_set_label_handler (model,
2690 gnc_split_register_get_notes_label,
2691 NOTES_CELL);
2692
2693 gnc_table_model_set_label_handler (model,
2694 gnc_split_register_get_fdebit_label,
2695 FDEBT_CELL);
2696
2697 gnc_table_model_set_label_handler (model,
2698 gnc_split_register_get_fcredit_label,
2699 FCRED_CELL);
2700
2701 gnc_table_model_set_label_handler (model,
2702 gnc_split_register_get_tbalance_label,
2703 RBALN_CELL);
2704
2705 // tooltip handlers
2706 // gnc_table_model_set_default_tooltip_handler(
2707 // model, gnc_split_register_get_default_tooltip);
2708
2709 gnc_table_model_set_tooltip_handler (model,
2710 gnc_split_register_get_recn_tooltip,
2711 RECN_CELL);
2712
2713 gnc_table_model_set_tooltip_handler (model,
2714 gnc_split_register_get_doclink_tooltip,
2715 DOCLINK_CELL);
2716
2717
2718 // help handlers
2719 gnc_table_model_set_default_help_handler (
2720 model, gnc_split_register_get_default_help);
2721
2722 gnc_table_model_set_help_handler (model,
2723 gnc_split_register_get_date_help,
2724 DATE_CELL);
2725
2726 gnc_table_model_set_help_handler (model,
2727 gnc_split_register_get_date_help,
2728 DDUE_CELL);
2729
2730 gnc_table_model_set_help_handler (model,
2731 gnc_split_register_get_num_help,
2732 NUM_CELL);
2733
2734 gnc_table_model_set_help_handler (model,
2735 gnc_split_register_get_tran_num_help,
2736 TNUM_CELL);
2737
2738 gnc_table_model_set_help_handler (model,
2739 gnc_split_register_get_desc_help,
2740 DESC_CELL);
2741
2742 gnc_table_model_set_help_handler (model,
2743 gnc_split_register_get_price_help,
2744 PRIC_CELL);
2745
2746 gnc_table_model_set_help_handler (model,
2747 gnc_split_register_get_shares_help,
2748 SHRS_CELL);
2749
2750 gnc_table_model_set_help_handler (model,
2751 gnc_split_register_get_action_help,
2752 ACTN_CELL);
2753
2754 gnc_table_model_set_help_handler (model,
2755 gnc_split_register_get_memo_help,
2756 MEMO_CELL);
2757
2758 gnc_table_model_set_help_handler (model,
2759 gnc_split_register_get_notes_help,
2760 NOTES_CELL);
2761
2762 gnc_table_model_set_help_handler (model,
2763 gnc_split_register_get_vnotes_help,
2764 VNOTES_CELL);
2765
2766 gnc_table_model_set_help_handler (model,
2767 gnc_split_register_get_xfrm_help,
2768 XFRM_CELL);
2769
2770 gnc_table_model_set_help_handler (model,
2771 gnc_split_register_get_mxfrm_help,
2772 MXFRM_CELL);
2773
2774 gnc_table_model_set_help_handler (model,
2775 gnc_split_register_get_fcred_help,
2776 FCRED_CELL);
2777
2778 gnc_table_model_set_help_handler (model,
2779 gnc_split_register_get_fdebt_help,
2780 FDEBT_CELL);
2781
2782 gnc_table_model_set_help_handler (model,
2783 gnc_split_register_get_doclink_help,
2784 DOCLINK_CELL);
2785
2786 // io flag handlers
2787 gnc_table_model_set_io_flags_handler (
2788 model, gnc_split_register_get_standard_io_flags, DATE_CELL);
2789
2790 /* FIXME: We really only need a due date for 'invoices', not for
2791 * 'payments' or 'receipts'. This implies we really only need the
2792 * due-date for transactions that credit the ACCT_TYPE_RECEIVABLE or
2793 * debit the ACCT_TYPE_PAYABLE account type.
2794 */
2795 gnc_table_model_set_io_flags_handler (
2796 model, gnc_split_register_get_rate_io_flags, RATE_CELL);
2797
2798 gnc_table_model_set_io_flags_handler (
2799 model, gnc_split_register_get_ddue_io_flags, DDUE_CELL);
2800
2801 gnc_table_model_set_io_flags_handler (
2802 model, gnc_split_register_get_standard_io_flags, NUM_CELL);
2803
2804 gnc_table_model_set_io_flags_handler (
2805 model, gnc_split_register_get_standard_io_flags, TNUM_CELL);
2806
2807 gnc_table_model_set_io_flags_handler (
2808 model, gnc_split_register_get_standard_io_flags, DESC_CELL);
2809
2810 gnc_table_model_set_io_flags_handler (
2811 model, gnc_split_register_get_standard_io_flags, ACTN_CELL);
2812
2813 gnc_table_model_set_io_flags_handler (
2814 model, gnc_split_register_get_standard_io_flags, XFRM_CELL);
2815
2816 gnc_table_model_set_io_flags_handler (
2817 model, gnc_split_register_get_standard_io_flags, MEMO_CELL);
2818
2819 gnc_table_model_set_io_flags_handler (
2820 model, gnc_split_register_get_standard_io_flags, MXFRM_CELL);
2821
2822 gnc_table_model_set_io_flags_handler (
2823 model, gnc_split_register_get_standard_io_flags, NOTES_CELL);
2824
2825 gnc_table_model_set_io_flags_handler (
2826 model, gnc_split_register_get_inactive_io_flags, VNOTES_CELL);
2827
2828 gnc_table_model_set_io_flags_handler (
2829 model, gnc_split_register_get_debcred_io_flags, CRED_CELL);
2830
2831 gnc_table_model_set_io_flags_handler (
2832 model, gnc_split_register_get_debcred_io_flags, DEBT_CELL);
2833
2834 gnc_table_model_set_io_flags_handler (
2835 model, gnc_split_register_get_recn_io_flags, RECN_CELL);
2836
2837 gnc_table_model_set_io_flags_handler (
2838 model, gnc_split_register_get_doclink_io_flags, DOCLINK_CELL);
2839
2840 gnc_table_model_set_io_flags_handler (
2841 model, gnc_split_register_get_recn_io_flags, TYPE_CELL);
2842
2843 gnc_table_model_set_io_flags_handler (
2844 model, gnc_split_register_get_security_io_flags, PRIC_CELL);
2845
2846 gnc_table_model_set_io_flags_handler (
2847 model, gnc_split_register_get_security_io_flags, SHRS_CELL);
2848
2849
2850 gnc_table_model_set_default_cell_color_handler (
2851 model, gnc_split_register_get_cell_color);
2852
2853 gnc_table_model_set_cell_color_handler (
2854 model, gnc_split_register_get_debcred_color, DEBT_CELL);
2855
2856 gnc_table_model_set_cell_color_handler (
2857 model, gnc_split_register_get_debcred_color, CRED_CELL);
2858
2859 gnc_table_model_set_cell_color_handler (
2860 model, gnc_split_register_get_debcred_color, TDEBT_CELL);
2861
2862 gnc_table_model_set_cell_color_handler (
2863 model, gnc_split_register_get_debcred_color, TCRED_CELL);
2864
2865 gnc_table_model_set_cell_color_handler (
2866 model, gnc_split_register_get_debcred_color, FCRED_CELL);
2867
2868 gnc_table_model_set_cell_color_handler (
2869 model, gnc_split_register_get_debcred_color, FDEBT_CELL);
2870
2871
2872 gnc_table_model_set_default_cell_border_handler (
2873 model, gnc_split_register_get_border);
2874
2875
2876 gnc_table_model_set_default_confirm_handler (
2877 model, gnc_split_register_confirm);
2878
2879 model->cell_data_allocator = gnc_split_register_guid_malloc;
2880 model->cell_data_deallocator = gnc_split_register_guid_free;
2881 model->cell_data_copy = gnc_split_register_guid_copy;
2882
2883 gnc_split_register_model_add_save_handlers (model);
2884
2885 return model;
2886 }
2887
2888 TableModel*
gnc_template_register_model_new(void)2889 gnc_template_register_model_new (void)
2890 {
2891 TableModel* model;
2892
2893 model = gnc_split_register_model_new();
2894
2895 gnc_table_model_set_entry_handler (
2896 model, gnc_split_register_get_inactive_date_entry, DATE_CELL);
2897
2898 gnc_table_model_set_entry_handler (
2899 model, gnc_split_register_get_inactive_date_entry, DDUE_CELL);
2900
2901 gnc_table_model_set_io_flags_handler (
2902 model, gnc_split_register_get_inactive_io_flags, DATE_CELL);
2903
2904 gnc_table_model_set_io_flags_handler (
2905 model, gnc_split_register_get_inactive_io_flags, DDUE_CELL);
2906
2907 gnc_table_model_set_entry_handler (
2908 model, gnc_template_register_get_xfrm_entry, XFRM_CELL);
2909
2910 gnc_table_model_set_entry_handler (
2911 model, gnc_template_register_get_fdebt_entry, FDEBT_CELL);
2912
2913 gnc_table_model_set_entry_handler (
2914 model, gnc_template_register_get_fcred_entry, FCRED_CELL);
2915
2916 gnc_table_model_set_entry_handler (
2917 model, gnc_template_register_get_debcred_entry, DEBT_CELL);
2918
2919 gnc_table_model_set_entry_handler (
2920 model, gnc_template_register_get_debcred_entry, CRED_CELL);
2921
2922 gnc_table_model_set_io_flags_handler (
2923 model, gnc_split_register_get_standard_io_flags, FCRED_CELL);
2924
2925 gnc_table_model_set_io_flags_handler (
2926 model, gnc_split_register_get_standard_io_flags, FDEBT_CELL);
2927
2928 gnc_template_register_model_add_save_handlers (model);
2929
2930 return model;
2931 }
2932