cell.c 3.64 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"
Arturo Espinosa's avatar
Arturo Espinosa committed
5

Arturo Espinosa's avatar
Arturo Espinosa committed
6 7
static void
cell_formula_link (Cell *cell)
Arturo Espinosa's avatar
Arturo Espinosa committed
8
{
Arturo Espinosa's avatar
Arturo Espinosa committed
9
	Sheet *sheet = cell->sheet;
Arturo Espinosa's avatar
Arturo Espinosa committed
10

Arturo Espinosa's avatar
Arturo Espinosa committed
11 12
	sheet->formula_cell_list = g_list_prepend (sheet->formula_cell_list, cell);
}
Arturo Espinosa's avatar
Arturo Espinosa committed
13

Arturo Espinosa's avatar
Arturo Espinosa committed
14 15 16 17 18 19 20
static void
cell_formula_unlink (Cell *cell)
{
	Sheet *sheet = cell->sheet;
	
	sheet->formula_cell_list = g_list_remove (sheet->formula_cell_list, cell);
}
Arturo Espinosa's avatar
Arturo Espinosa committed
21

Arturo Espinosa's avatar
Arturo Espinosa committed
22 23 24 25
void
cell_set_formula (Cell *cell, char *text)
{
	char *error_msg = NULL;
Arturo Espinosa's avatar
Arturo Espinosa committed
26

Arturo Espinosa's avatar
Arturo Espinosa committed
27 28
	g_return_if_fail (cell != NULL);
	g_return_if_fail (text != NULL);
29

Arturo Espinosa's avatar
Arturo Espinosa committed
30 31 32 33 34 35 36 37 38 39
	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;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
40

Arturo Espinosa's avatar
Arturo Espinosa committed
41 42 43 44
	cell_formula_link (cell);
	cell_add_dependencies (cell);
	cell_queue_recalc (cell);
}
Arturo Espinosa's avatar
Arturo Espinosa committed
45

Arturo Espinosa's avatar
Arturo Espinosa committed
46
void
47
cell_calc_dimensions (Cell *cell)
Arturo Espinosa's avatar
Arturo Espinosa committed
48 49
{
	char    *rendered_text;
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
	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;
}

void
cell_set_text (Cell *cell, char *text)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
66 67 68 69
	GList   *deps;
	
	g_return_if_fail (cell != NULL);
	g_return_if_fail (text != NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
70

Arturo Espinosa's avatar
Arturo Espinosa committed
71 72
	/* The value entered */
	if (cell->entered_text)
73 74
		string_unref (cell->entered_text);

Arturo Espinosa's avatar
Arturo Espinosa committed
75 76 77 78
	cell->entered_text = string_get (text);
	
	if (cell->parsed_node){
		cell_drop_dependencies (cell);
79 80
		cell_formula_unlink (cell);

Arturo Espinosa's avatar
Arturo Espinosa committed
81
		expr_tree_unref (cell->parsed_node);
82
		cell->parsed_node = NULL;
Arturo Espinosa's avatar
Arturo Espinosa committed
83
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
84 85 86 87 88 89 90 91 92
	
	if (text [0] == '='){
		cell_set_formula (cell, text); 
	} else {
		Value *v = g_new (Value, 1);
		int is_text = 0, is_float = 0;
		char *p;
		
		if (cell->text)
93
			string_unref (cell->text);
Arturo Espinosa's avatar
Arturo Espinosa committed
94

Arturo Espinosa's avatar
Arturo Espinosa committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
		cell->text = string_get (text);

		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;
				
			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);
			}
			/* FIXME: */
			/* In this case we need to format the text */
		}
		cell->value = v;
127
		cell_calc_dimensions (cell);
Arturo Espinosa's avatar
Arturo Espinosa committed
128
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
129

Arturo Espinosa's avatar
Arturo Espinosa committed
130 131 132 133 134 135
	/* 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
136

Arturo Espinosa's avatar
Arturo Espinosa committed
137 138 139
	
	/* Finish setting the values for this cell */
	cell->flags = 0;
Arturo Espinosa's avatar
Arturo Espinosa committed
140
}
Arturo Espinosa's avatar
Arturo Espinosa committed
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182

/*
 * 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);
	expr_tree_ref   (new_cell->parsed_node);
	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){
		cell_formula_unlink (cell);
		expr_tree_unref (cell->parsed_node);
	}

	string_unref    (cell->entered_text);
	string_unref    (cell->text);
	style_destroy   (cell->style);
	value_release   (cell->value);
}