GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 [email protected] *
20 \********************************************************************/
21 
22 #include "config.h"
23 
24 #include <glib/gi18n.h>
25 
26 #include "gnc-exp-parser.h"
27 #include "gnc-locale-utils.h"
28 #include "gnc-engine.h"
29 #include "gnc-ui-util.h"
30 #include "gnc-ui.h"
31 
32 #include "basiccell.h"
33 #include "formulacell.h"
34 
35 #undef G_LOG_DOMAIN
36 #define G_LOG_DOMAIN "gnc.register.core.formulacell"
37 
38 static void gnc_formula_cell_init( FormulaCell *fc );
39 
40 static gboolean gnc_formula_cell_enter( BasicCell *_cell,
41  int *cursor_position,
42  int *start_selection,
43  int *end_selection );
44 
45 static void gnc_formula_cell_leave( BasicCell *_cell );
46 
47 static void gnc_formula_cell_modify_verify( BasicCell *_cell,
48  const char *change,
49  int change_len,
50  const char *newval,
51  int newval_len,
52  int *cursor_position,
53  int *start_selection,
54  int *end_selection );
55 
56 static void gnc_formula_cell_set_value_internal( BasicCell *_cell,
57  const char *str );
58 
59 
60 
61 BasicCell*
62 gnc_formula_cell_new(void)
63 {
64  FormulaCell *fc = g_new0( FormulaCell, 1 );
65  gnc_formula_cell_init( fc );
66  return &fc->cell;
67 }
68 
69 static
70 void
71 gnc_formula_cell_init( FormulaCell *fc )
72 {
73  gnc_basic_cell_init (&(fc->cell));
74 
75  fc->print_info = gnc_default_print_info (FALSE);
76 
77  fc->cell.enter_cell = gnc_formula_cell_enter;
78  fc->cell.modify_verify = gnc_formula_cell_modify_verify;
79  fc->cell.set_value = gnc_formula_cell_set_value_internal;
80  fc->cell.leave_cell = gnc_formula_cell_leave;
81 }
82 
83 void
84 gnc_formula_cell_set_value( FormulaCell *fc,
85  const char *newVal )
86 {
87  g_debug("got value [%s]", newVal);
88  gnc_formula_cell_set_value_internal( &fc->cell, newVal );
89 }
90 
91 static
92 gboolean
93 gnc_formula_cell_enter( BasicCell *_cell,
94  int *cursor_position,
95  int *start_selection,
96  int *end_selection )
97 {
98  g_debug("%d, %d, %d", *cursor_position, *start_selection, *end_selection);
99  *cursor_position = -1;
100  *start_selection = 0;
101  *end_selection = -1;
102  return TRUE;
103 }
104 
105 static void
106 gnc_formula_cell_leave(BasicCell *_cell)
107 {
108  char *str;
109  FormulaCell *fc = (FormulaCell*)_cell;
110  str = fc->cell.value;
111  {
112  char *error_location = NULL;
113  gnc_numeric amount;
114  if (str != NULL
115  && strlen(str) != 0
116  && !gnc_exp_parser_parse(str, &amount, &error_location))
117  {
118  gnc_warning_dialog(NULL, _("An error occurred while processing %s."),
119  str);//, (error_location - str));
120  }
121  }
122 
123  gnc_basic_cell_set_value_internal( &fc->cell, str );
124 }
125 
126 static
127 void
128 gnc_formula_cell_modify_verify( BasicCell *_cell,
129  const char *change,
130  int change_len,
131  const char *newval,
132  int newval_len,
133  int *cursor_position,
134  int *start_selection,
135  int *end_selection )
136 {
137  FormulaCell *cell = (FormulaCell *)_cell;
138  struct lconv *lc = gnc_localeconv ();
139  const char *toks = "+-*/=()_:";
140  gunichar decimal_point;
141  gunichar thousands_sep;
142  const char *c;
143  gunichar uc;
144 
145  g_debug("%s, %d, %s, %d, %d, %d, %d",
146  change ? (gchar *)change : "(null)", change_len,
147  newval ? (gchar *)newval : "(null)", newval_len,
148  *cursor_position, *start_selection, *end_selection);
149 
150  /* accept the newval string if user action was delete */
151  if (change == NULL)
152  {
153  gnc_basic_cell_set_value_internal( &cell->cell, newval );
154  return;
155  }
156 
157  if (cell->print_info.monetary)
158  decimal_point = g_utf8_get_char(lc->mon_decimal_point);
159  else
160  decimal_point = g_utf8_get_char(lc->decimal_point);
161 
162  if (cell->print_info.monetary)
163  thousands_sep = g_utf8_get_char(lc->mon_thousands_sep);
164  else
165  thousands_sep = g_utf8_get_char(lc->thousands_sep);
166 
167  c = change;
168  while (*c)
169  {
170  uc = g_utf8_get_char (c);
171  if (!g_unichar_isdigit (uc) &&
172  !g_unichar_isspace (uc) &&
173  !g_unichar_isalpha (uc) &&
174  (decimal_point != uc) &&
175  (thousands_sep != uc) &&
176  (g_utf8_strchr (toks, -1, uc) == NULL))
177  return;
178  c = g_utf8_next_char (c);
179  }
180 
181  gnc_basic_cell_set_value_internal( &cell->cell, newval );
182 }
183 
184 static
185 void
186 gnc_formula_cell_set_value_internal( BasicCell *_cell,
187  const char *str )
188 {
189  FormulaCell *fc = (FormulaCell*)_cell;
190  g_debug("internal string: [%s]", str);
191  gnc_basic_cell_set_value_internal( &fc->cell, str );
192 }
utility functions for the GnuCash UI
GNCPrintAmountInfo print_info
Definition: formulacell.h:50
All type declarations for the whole Gnucash engine.