GnuCash c935c2f+
Loading...
Searching...
No Matches
pricecell-gnome.c
1/********************************************************************\
2 * This program is free software; you can redistribute it and/or *
3 * modify it under the terms of the GNU General Public License as *
4 * published by the Free Software Foundation; either version 2 of *
5 * the License, or (at your option) any later version. *
6 * *
7 * This program is distributed in the hope that it will be useful, *
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
10 * GNU General Public License for more details. *
11 * *
12 * You should have received a copy of the GNU General Public License*
13 * along with this program; if not, contact: *
14 * *
15 * Free Software Foundation Voice: +1-617-542-5942 *
16 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
17 * Boston, MA 02110-1301, USA gnu@gnu.org *
18 * *
19\********************************************************************/
20
21/* pricecell-gnome.c
22 *
23 * Implements gnome dependent price cell functions :
24 *
25 * Often the decimal key in the keypad is not mapped to the correct locale
26 * decimal point, the function PriceDirect handle this case.
27 */
28
29#include <config.h>
30
31#include <locale.h>
32#include <gdk/gdkkeysyms.h>
33
34#include "gnc-locale-utils.h"
35#include "gnc-exp-parser.h"
36#include "gnc-ui-util.h"
37#include "pricecell.h"
38#include "pricecell-gnome.h"
39#include "gnucash-sheet.h"
40#include "gnucash-sheetP.h"
41#include "table-allgui.h"
42
43#ifdef G_OS_WIN32
44# include <gdk/gdkwin32.h>
45#endif
46
47static gboolean
48gnc_price_cell_direct_update (BasicCell *bcell,
49 int *cursor_position,
50 int *start_selection,
51 int *end_selection,
52 void *gui_data)
53{
54 PriceCell *cell = (PriceCell *) bcell;
55 GdkEventKey *event = gui_data;
56 struct lconv *lc;
57 gboolean is_return;
58
59 if (event->type != GDK_KEY_PRESS)
60 return FALSE;
61
62 lc = gnc_localeconv ();
63
64 is_return = FALSE;
65
66 switch (event->keyval)
67 {
68 case GDK_KEY_Escape:
69 if (bcell->changed)
70 {
71 GnucashSheet *sheet = (GnucashSheet *) bcell->gui_private;
72 const char *value = gnc_table_get_model_entry (sheet->table, bcell->cell_name);
73
74 gnc_basic_cell_set_value_internal (bcell, value);
75 bcell->changed = FALSE;
76 *cursor_position = 0;
77 *start_selection = 0;
78 *end_selection = -1;
79 return TRUE;
80 }
81 return FALSE;
82
83 case GDK_KEY_Return:
84 if (!(event->state &
85 (GDK_MODIFIER_INTENT_DEFAULT_MOD_MASK)))
86 is_return = TRUE;
87 /* fall through */
88
89 case GDK_KEY_KP_Enter:
90 {
91 char *error_loc;
92 gnc_numeric amount;
93 gboolean parse_ok;
94 gboolean changed = FALSE;
95
96 if (!cell->need_to_parse)
97 return FALSE;
98
99 parse_ok = gnc_exp_parser_parse (cell->cell.value,
100 &amount, &error_loc);
101
102 if (parse_ok)
103 changed = gnc_price_cell_set_value (cell, amount);
104 else if (!cell->cell.value || cell->cell.value[0] == '\0')
105 changed = gnc_price_cell_set_value (cell,
106 gnc_numeric_zero ());
107 else
108 *cursor_position = error_loc - cell->cell.value;
109
110 /* If there is a problem with the parse, swallow
111 * the key so we stay put. */
112 if (!parse_ok)
113 return TRUE;
114
115 /* If nothing has changed, let the key cause a
116 * cursor activation no matter what. */
117 if (!changed)
118 return FALSE;
119
120 /* If it's not a plain return, stay put. This
121 * allows a 'calculator' style operation using
122 * keypad enter where you can keep entering more
123 * items to add, say. */
124 return !is_return;
125 }
126
127 case GDK_KEY_KP_Decimal:
128 break;
129
130 default:
131 return FALSE;
132 }
133
134 /* This point is only reached when the KP_Decimal key is pressed. */
135 gnc_basic_cell_insert_decimal(bcell,
136 cell->print_info.monetary
137 ? lc->mon_decimal_point[0]
138 : lc->decimal_point[0],
139 cursor_position,
140 start_selection,
141 end_selection);
142
143 cell->need_to_parse = TRUE;
144
145 return TRUE;
146}
147
148BasicCell *
149gnc_price_cell_gnome_new (void)
150{
151 BasicCell *cell;
152
153 cell = gnc_price_cell_new ();
154
155 cell->direct_update = gnc_price_cell_direct_update;
156
157 return cell;
158}
159
160void
161gnc_basic_cell_insert_decimal(BasicCell *bcell,
162 char decimal_point,
163 int *cursor_position,
164 int *start_selection,
165 int *end_selection)
166{
167 GString *newval_gs;
168 gint start, end;
169 gchar *buf;
170
171 /* allocate space for newval_ptr : oldval + one letter ( the
172 decimal_point ) */
173 newval_gs = g_string_new("");
174
175 start = MIN(*start_selection, *end_selection);
176 end = MAX(*start_selection, *end_selection);
177
178 /* length in bytes, not chars. do not use g_utf8_strlen. */
179 buf = g_malloc0(strlen(bcell->value) + 1);
180 g_utf8_strncpy(buf, bcell->value, start);
181 g_string_append(newval_gs, buf);
182 g_free(buf);
183
184 g_string_append_unichar(newval_gs, decimal_point);
185
186 buf = g_utf8_offset_to_pointer(bcell->value, end);
187 g_string_append(newval_gs, buf);
188
189 /* update the cursor position */
190 *cursor_position = start + 1;
191
192 gnc_basic_cell_set_value_internal (bcell, newval_gs->str);
193
194 g_string_free (newval_gs, TRUE);
195}
196
utility functions for the GnuCash UI
Private declarations for GnucashSheet class.
Public declarations of GnucashRegister class.
gboolean gnc_price_cell_set_value(PriceCell *cell, gnc_numeric amount)
updates amount, returns TRUE if string representation actually changed
Definition pricecell.c:219
BasicCell * gnc_price_cell_new(void)
installs a callback to handle price recording
Definition pricecell.c:168
The PriceCell object implements a cell handler that stores a single double-precision value,...
Definition pricecell.h:55
gboolean need_to_parse
amount printing context
Definition pricecell.h:61
GNCPrintAmountInfo print_info
controls printing of zero values
Definition pricecell.h:60
Declarations for the Table object.