GnuCash c935c2f+
Loading...
Searching...
No Matches
numcell.c
1/********************************************************************\
2 * numcell.c -- number handling cell incl. accelerator key support *
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/*
24 * FILE:
25 * numcell.c
26 *
27 * FUNCTION:
28 * implements a gui-independent number handling cell.
29 *
30 * HISTORY:
31 * Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu>
32 */
33
34#include <config.h>
35
36#include <limits.h>
37#include <stdlib.h>
38#include <string.h>
39
40#include "numcell.h"
41#include "gnc-engine.h"
42
43static const QofLogModule log_module = G_LOG_DOMAIN;
44
45/* This static indicates the debugging module that this .o belongs to. */
46/* static short module = MOD_REGISTER; */
47
48static void gnc_num_cell_init (NumCell *cell);
49static gboolean gnc_num_cell_enter (BasicCell *cell, int *cursor_position,
50 int *start_selection, int *end_selection);
51
52/* Parses the string value and returns true if it is a
53 * number. In that case, *num is set to the value parsed. */
54static gboolean
55gnc_parse_num (const char *string, long int *num)
56{
57 long int number;
58
59 if (string == NULL)
60 return FALSE;
61
62 if (!gnc_strisnum (string))
63 return FALSE;
64
65 number = strtol (string, NULL, 10);
66
67 if ((number == LONG_MIN) || (number == LONG_MAX))
68 return FALSE;
69
70 if (num != NULL)
71 *num = number;
72
73 return TRUE;
74}
75
76static void
77gnc_num_cell_modify_verify (BasicCell *_cell,
78 const char *change,
79 int change_len,
80 const char *newval,
81 int new_val_len,
82 int *cursor_position,
83 int *start_selection,
84 int *end_selection)
85{
86 NumCell *cell = (NumCell *) _cell;
87 gboolean accel = FALSE;
88 gboolean is_num;
89 long int number = 0;
90 gunichar uc;
91 glong change_chars;
92
93 if (change == NULL) /* if we are deleting */
94 /* then just accept the proposed change */
95 {
96 gnc_basic_cell_set_value_internal (&cell->cell, newval);
97 // Remove any selection.
98 *end_selection = *start_selection = *cursor_position;
99 return;
100 }
101
102 change_chars = g_utf8_strlen (change, -1);
103
104 if ((change_chars == 0) || /* if we are deleting */
105 (change_chars > 1)) /* or entering > 1 char */
106 /* then just accept the proposed change */
107 {
108 gnc_basic_cell_set_value_internal (&cell->cell, newval);
109 return;
110 }
111
112 /* otherwise, it may be an accelerator key. */
113
114 is_num = gnc_parse_num (_cell->value, &number);
115
116 if (is_num && (number < 0))
117 is_num = FALSE;
118
119 uc = g_utf8_get_char (change);
120 switch (uc)
121 {
122 case '+':
123 case '=':
124 number++;
125 accel = TRUE;
126 break;
127
128 case '_':
129 case '-':
130 number--;
131 accel = TRUE;
132 break;
133
134 case '}':
135 case ']':
136 number += 10;
137 accel = TRUE;
138 break;
139
140 case '{':
141 case '[':
142 number -= 10;
143 accel = TRUE;
144 break;
145 }
146
147 if (number < 0)
148 number = 0;
149
150 /* If there is already a non-number there, don't accelerate. */
151 if (accel && !is_num && (g_strcmp0(_cell->value, "") != 0))
152 accel = FALSE;
153
154 if (accel)
155 {
156 char buff[128];
157
158 if (!is_num)
159 number = cell->next_num;
160
161 strcpy (buff, "");
162 snprintf (buff, sizeof(buff), "%ld", number);
163
164 if (g_strcmp0 (buff, "") == 0)
165 return;
166
167 gnc_basic_cell_set_value_internal (&cell->cell, buff);
168
169 *cursor_position = -1;
170
171 return;
172 }
173
174 gnc_basic_cell_set_value_internal (&cell->cell, newval);
175}
176
177BasicCell *
178gnc_num_cell_new (void)
179{
180 NumCell *cell;
181
182 cell = g_new0 (NumCell, 1);
183
184 gnc_num_cell_init (cell);
185
186 return &cell->cell;
187}
188
189static void
190gnc_num_cell_set_value_internal (BasicCell *_cell, const char *str)
191{
192 NumCell *cell = (NumCell *) _cell;
193
194 if (!cell->next_num_set)
195 {
196 long int number;
197
198 if (gnc_parse_num (str, &number))
199 cell->next_num = number + 1;
200 }
201
202 gnc_basic_cell_set_value_internal (_cell, str);
203}
204
205void
206gnc_num_cell_set_value (NumCell *cell, const char *str)
207{
208 if (!cell)
209 return;
210
211 gnc_num_cell_set_value_internal (&cell->cell, str);
212}
213
214gboolean
215gnc_num_cell_set_last_num (NumCell *cell, const char *str)
216{
217 long int number;
218
219 if (!cell)
220 return FALSE;
221
222 if (gnc_parse_num (str, &number))
223 {
224 cell->next_num = number + 1;
225 cell->next_num_set = TRUE;
226 return TRUE;
227 }
228
229 return FALSE;
230}
231
232static void
233gnc_num_cell_init (NumCell *cell)
234{
235 gnc_basic_cell_init (&(cell->cell));
236
237 cell->next_num = 0;
238 cell->next_num_set = FALSE;
239
240 cell->cell.modify_verify = gnc_num_cell_modify_verify;
241 cell->cell.set_value = gnc_num_cell_set_value_internal;
242 cell->cell.enter_cell = gnc_num_cell_enter;
243}
244
245static gboolean
246gnc_num_cell_enter (BasicCell *cell, int *cursor_position,
247 int *start_selection, int *end_selection)
248{
249 DEBUG("%d, %d, %d", *cursor_position, *start_selection, *end_selection);
250 *cursor_position = -1;
251 *start_selection = 0;
252 *end_selection = -1;
253 return TRUE;
254}
All type declarations for the whole Gnucash engine.
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264
gboolean gnc_strisnum(const gchar *s)
Returns true if string s is a number, possibly surrounded by whitespace.
Definition qofutil.cpp:187
The NumCell object implements a number handling cell.
Definition numcell.h:40