GnuCash  5.6-150-g038405b370+
formulacell.c
1 /********************************************************************\
2  * formulacell.c -- Formula entry/display cell *
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 #include <config.h>
23 
24 #include <glib/gi18n.h>
25 
26 #include "gnc-exp-parser.h"
27 #include "gnc-engine.h"
28 #include "gnc-ui-util.h"
29 #include "gnc-ui.h"
30 
31 #include "basiccell.h"
32 #include "formulacell.h"
33 #include <qoflog.h>
34 
35 #undef G_LOG_DOMAIN
36 #define G_LOG_DOMAIN "gnc.register.core.formulacell"
37 static const QofLogModule log_module = G_LOG_DOMAIN;
38 
39 static void gnc_formula_cell_init( FormulaCell *fc );
40 
41 static gboolean gnc_formula_cell_enter( BasicCell *_cell,
42  int *cursor_position,
43  int *start_selection,
44  int *end_selection );
45 
46 static void gnc_formula_cell_leave( BasicCell *_cell );
47 
48 static void gnc_formula_cell_modify_verify( BasicCell *_cell,
49  const char *change,
50  int change_len,
51  const char *newval,
52  int newval_len,
53  int *cursor_position,
54  int *start_selection,
55  int *end_selection );
56 
57 static void gnc_formula_cell_set_value_internal( BasicCell *_cell,
58  const char *str );
59 
60 
61 
62 BasicCell*
63 gnc_formula_cell_new(void)
64 {
65  FormulaCell *fc = g_new0( FormulaCell, 1 );
66  gnc_formula_cell_init( fc );
67  return &fc->cell;
68 }
69 
70 static
71 void
72 gnc_formula_cell_init( FormulaCell *fc )
73 {
74  gnc_basic_cell_init (&(fc->cell));
75 
76  fc->print_info = gnc_default_print_info (FALSE);
77 
78  fc->cell.enter_cell = gnc_formula_cell_enter;
79  fc->cell.modify_verify = gnc_formula_cell_modify_verify;
80  fc->cell.set_value = gnc_formula_cell_set_value_internal;
81  fc->cell.leave_cell = gnc_formula_cell_leave;
82 }
83 
84 void
85 gnc_formula_cell_set_value( FormulaCell *fc,
86  const char *newVal )
87 {
88  DEBUG("got value [%s]", newVal);
89  gnc_formula_cell_set_value_internal( &fc->cell, newVal );
90 }
91 
92 static
93 gboolean
94 gnc_formula_cell_enter( BasicCell *_cell,
95  int *cursor_position,
96  int *start_selection,
97  int *end_selection )
98 {
99  DEBUG("%d, %d, %d", *cursor_position, *start_selection, *end_selection);
100  *cursor_position = -1;
101  *start_selection = 0;
102  *end_selection = -1;
103  return TRUE;
104 }
105 
106 static void
107 gnc_formula_cell_leave(BasicCell *_cell)
108 {
109  char *str;
110  FormulaCell *fc = (FormulaCell*)_cell;
111  str = fc->cell.value;
112  {
113  char *error_location = NULL;
114  gnc_numeric amount;
115  if (str != NULL
116  && strlen(str) != 0
117  && !gnc_exp_parser_parse(str, &amount, &error_location))
118  {
119  gint error_position = error_location - str;
120  gnc_warning_dialog (gnc_ui_get_main_window (NULL),
121  _("An error occurred while processing '%s' at position %d"),
122  str, error_position);
123  }
124  }
125 
126  gnc_basic_cell_set_value_internal( &fc->cell, str );
127 }
128 
129 static
130 void
131 gnc_formula_cell_modify_verify( BasicCell *_cell,
132  const char *change,
133  int change_len,
134  const char *newval,
135  int newval_len,
136  int *cursor_position,
137  int *start_selection,
138  int *end_selection)
139 {
140  FormulaCell *fc = (FormulaCell *)_cell;
141  const char *toks = "+-*/=()_:";
142  char *validated_newval = NULL;
143 
144  DEBUG("%s, %d, %s, %d, %d, %d, %d",
145  change ? (gchar *)change : "(null)", change_len,
146  newval ? (gchar *)newval : "(null)", newval_len,
147  *cursor_position, *start_selection, *end_selection);
148 
149  /* accept the newval string if user action was delete */
150  if (change == NULL)
151  {
152  gnc_basic_cell_set_value_internal (&fc->cell, newval);
153  // Remove any selection.
154  *end_selection = *start_selection = *cursor_position;
155  return;
156  }
157 
158  validated_newval = gnc_basic_cell_validate (_cell, fc->print_info,
159  change, newval, toks,
160  cursor_position);
161 
162  if (!validated_newval)
163  return;
164 
165  gnc_basic_cell_set_value_internal (_cell, validated_newval);
166  g_free (validated_newval);
167 }
168 
169 static
170 void
171 gnc_formula_cell_set_value_internal( BasicCell *_cell,
172  const char *str )
173 {
174  FormulaCell *fc = (FormulaCell*)_cell;
175  DEBUG("internal string: [%s]", str);
176  gnc_basic_cell_set_value_internal( &fc->cell, str );
177 }
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
utility functions for the GnuCash UI
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
All type declarations for the whole Gnucash engine.
The FormulaCell is a register-table cell which can contain a formula involving numbers, formula markup and strings denoting either functions or variables.
Definition: formulacell.h:42
GNCPrintAmountInfo print_info
The print-info for numeric values.
Definition: formulacell.h:47