cell.c 5.55 KB
Newer Older
1
#include <config.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
2
#include <gnome.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
3
4
#include "gnumeric.h"
#include "eval.h"
5
#include "format.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
6

7
8
9
10
11
12
13
14
15
16
void
cell_formula_changed (Cell *cell)
{
	g_return_if_fail (cell != NULL);
	
	sheet_cell_formula_link (cell);
	cell_add_dependencies (cell);
	cell_queue_recalc (cell);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
17
18
19
20
void
cell_set_formula (Cell *cell, char *text)
{
	char *error_msg = NULL;
Arturo Espinosa's avatar
Arturo Espinosa committed
21

Arturo Espinosa's avatar
Arturo Espinosa committed
22
23
	g_return_if_fail (cell != NULL);
	g_return_if_fail (text != NULL);
24

Arturo Espinosa's avatar
Arturo Espinosa committed
25
26
27
28
29
30
31
32
33
34
	cell->parsed_node = expr_parse_string (&text [1],
					       cell->col->pos,
					       cell->row->pos,
					       &error_msg);
	if (cell->parsed_node == NULL){
		if (cell->text)
			string_unref_ptr (&cell->text);
		cell->text = string_get (error_msg);
		return;
	}
35
	cell_formula_changed (cell);
Arturo Espinosa's avatar
Arturo Espinosa committed
36
}
Arturo Espinosa's avatar
Arturo Espinosa committed
37

Miguel de Icaza's avatar
Miguel de Icaza committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
 * cell_set_alignment:
 *
 * @cell: the cell to change the alignment of
 * @halign: the horizontal alignemnt
 * @valign: the vertical alignemnt
 * @orient: the text orientation
 *
 * This routine changes the alignment of a cell to those specified.
 */
void
cell_set_alignment (Cell *cell, int halign, int valign, int orient)
{
	g_return_if_fail (cell != NULL);
	g_return_if_fail (cell->style != NULL);

	if ((cell->style->halign == halign) &&
	    (cell->style->halign == valign) &&
	    (cell->style->orientation == orient))
		return;

	cell->style->halign = halign;
	cell->style->valign = valign;
	cell->style->orientation = orient;

	cell_queue_redraw (cell);
}

/*
 * cell_calc_dimensions
 * @cell:  The cell
 *
 * This routine updates the dimensions of the the rendered text of a cell
 */
Arturo Espinosa's avatar
Arturo Espinosa committed
72
void
73
cell_calc_dimensions (Cell *cell)
Arturo Espinosa's avatar
Arturo Espinosa committed
74
75
{
	char    *rendered_text;
76
77
78
79
80
81
82
83
84
85
86
87
88
	GdkFont *font;

	g_return_if_fail (cell != NULL);
	
	rendered_text = CELL_TEXT_GET (cell);
	
	font = cell->style->font->font;
	
	cell->width = cell->col->margin_a + cell->col->margin_b + 
		gdk_text_width (font, rendered_text, strlen (rendered_text));
	cell->height = font->ascent + font->descent;
}

Miguel de Icaza's avatar
Miguel de Icaza committed
89
90
91
92
93
94
95
96
/*
 * cell_set_rendered_text
 * @cell:          the cell we will modify
 * @rendered_text: the text we will display
 *
 * This routine sets the rendered text field of the cell
 * it recomputes the bounding box for the cell as well
 */
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
97
98
99
100
101
102
103
104
105
106
107
108
109
void
cell_set_rendered_text (Cell *cell, char *rendered_text)
{
	g_return_if_fail (cell != NULL);
	g_return_if_fail (rendered_text != NULL);
	
	if (cell->text)
		string_unref (cell->text);

	cell->text = string_get (rendered_text);
	cell_calc_dimensions (cell);
}

Miguel de Icaza's avatar
Miguel de Icaza committed
110
111
112
113
114
115
/*
 * cell_render_value
 * @cell: The cell whose value needs to be rendered
 *
 * The value of the cell is formated according to the format style
 */
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
116
117
118
119
120
121
122
123
void
cell_render_value (Cell *cell)
{
	char *str;
	
	g_return_if_fail (cell != NULL);
	g_return_if_fail (cell->value != NULL);

124
	str = format_value (cell->style->format, cell->value, NULL);
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
125
126
127
128
	cell_set_rendered_text (cell, str);
	g_free (str);
}

129
130
131
void
cell_set_text (Cell *cell, char *text)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
132
133
134
135
	GList   *deps;
	
	g_return_if_fail (cell != NULL);
	g_return_if_fail (text != NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
136

Arturo Espinosa's avatar
Arturo Espinosa committed
137
138
	/* The value entered */
	if (cell->entered_text)
139
140
		string_unref (cell->entered_text);

Arturo Espinosa's avatar
Arturo Espinosa committed
141
142
143
144
	cell->entered_text = string_get (text);
	
	if (cell->parsed_node){
		cell_drop_dependencies (cell);
145
		sheet_cell_formula_unlink (cell);
146

Arturo Espinosa's avatar
Arturo Espinosa committed
147
		expr_tree_unref (cell->parsed_node);
148
		cell->parsed_node = NULL;
Arturo Espinosa's avatar
Arturo Espinosa committed
149
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
150
	
Miguel de Icaza's avatar
Miguel de Icaza committed
151
 	if (text [0] == '='){
Arturo Espinosa's avatar
Arturo Espinosa committed
152
153
154
155
156
157
158
159
160
161
162
		cell_set_formula (cell, text); 
	} else {
		Value *v = g_new (Value, 1);
		int is_text = 0, is_float = 0;
		char *p;
		
		for (p = text; *p && !is_text; p++){
			switch (*p){
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9':
				break;
163
164
165
166
167

			case '-':
				if (p == text)
					break;
				/* falldown */
Arturo Espinosa's avatar
Arturo Espinosa committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
				
			case 'E': case 'e': case '+': case ':': case '.':
				is_float = 1;
				break;
			default:
				is_text = 1;
			}
		}
		if (is_text){
			v->type = VALUE_STRING;
			v->v.str = string_get (text);
		} else {
			if (is_float){
				v->type = VALUE_FLOAT;
				float_get_from_range (text, text+strlen(text),
						      &v->v.v_float);
			} else {
				v->type = VALUE_INTEGER;
				int_get_from_range (text, text+strlen (text),
						    &v->v.v_int);
			}
		}
		cell->value = v;
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
191
192
		
		cell_render_value (cell);
Arturo Espinosa's avatar
Arturo Espinosa committed
193
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
194

Arturo Espinosa's avatar
Arturo Espinosa committed
195
196
197
198
199
200
	/* Queue all of the dependencies for this cell */
	deps = cell_get_dependencies (cell->sheet,
				      cell->col->pos,
				      cell->row->pos);
	if (deps)
		cell_queue_recalc_list (deps);
Arturo Espinosa's avatar
Arturo Espinosa committed
201
}
Arturo Espinosa's avatar
Arturo Espinosa committed
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

/*
 * Makes a copy of a Cell
 */
Cell *
cell_copy (Cell *cell)
{
	Cell *new_cell;

	g_return_val_if_fail (cell != NULL, NULL);

	new_cell = g_new (Cell, 1);

	/* bitmap copy first */
	*new_cell = *cell;

	/* now copy propertly the rest */
	string_ref      (new_cell->entered_text);
220
221
	if (new_cell->parsed_node)
		expr_tree_ref   (new_cell->parsed_node);
Arturo Espinosa's avatar
Arturo Espinosa committed
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
	string_ref      (new_cell->text);
	
	new_cell->style = style_duplicate (new_cell->style);
	new_cell->value = value_duplicate (new_cell->value);

	return new_cell;
}

void
cell_destroy (Cell *cell)
{
	g_return_if_fail (cell != NULL);

	if (cell->parsed_node){
		expr_tree_unref (cell->parsed_node);
	}

	string_unref    (cell->entered_text);
	string_unref    (cell->text);
	style_destroy   (cell->style);
	value_release   (cell->value);
}
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
244
245
246
247

void
cell_queue_redraw (Cell *cell)
{
248
249
	g_return_if_fail (cell != NULL);
	
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
250
251
252
253
254
255
256
257
	sheet_redraw_cell_region (cell->sheet,
				  cell->col->pos, cell->row->pos,
				  cell->col->pos, cell->row->pos);
}

void
cell_set_format (Cell *cell, char *format)
{
258
259
260
	g_return_if_fail (cell != NULL);
	g_return_if_fail (format != NULL);
	
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
261
262
263
264
265
266
267
268
269
	if (strcmp (format, cell->style->format->format) == 0)
		return;

	/* Change the format */
	style_format_unref (cell->style->format);
	cell->style->format = style_format_new (format);

	/* re-render the cell text */
	cell_render_value (cell);
270
	cell_queue_redraw (cell);
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
271
}
272