Commit 812bcde1 authored by Arturo Espinosa's avatar Arturo Espinosa

Minimal fixes before movies!

parent b7f5d377
1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/clipboard.c (clipboard_paste_region): After pasting, trigger
a recalculation.
1998-08-14 Jaka Mocnik <jaka.mocnik@kiss.uni-lj.si>
* src/clipboard.h: changed PASTE_ALL to PASTE_ALL_TYPES.
......
1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/clipboard.c (clipboard_paste_region): After pasting, trigger
a recalculation.
1998-08-14 Jaka Mocnik <jaka.mocnik@kiss.uni-lj.si>
* src/clipboard.h: changed PASTE_ALL to PASTE_ALL_TYPES.
......
1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/clipboard.c (clipboard_paste_region): After pasting, trigger
a recalculation.
1998-08-14 Jaka Mocnik <jaka.mocnik@kiss.uni-lj.si>
* src/clipboard.h: changed PASTE_ALL to PASTE_ALL_TYPES.
......
1998-08-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/clipboard.c (clipboard_paste_region): After pasting, trigger
a recalculation.
1998-08-14 Jaka Mocnik <jaka.mocnik@kiss.uni-lj.si>
* src/clipboard.h: changed PASTE_ALL to PASTE_ALL_TYPES.
......
......@@ -64,12 +64,61 @@ clipboard_copy_cell_range (Sheet *sheet, int start_col, int start_row, int end_c
return c.r;
}
static int
paste_cell (Sheet *dest_sheet, Cell *new_cell, int target_col, int target_row, int paste_flags)
{
sheet_cell_add (dest_sheet, new_cell, target_col, target_row);
if (!(paste_flags & PASTE_FORMULAS)){
if (new_cell->parsed_node){
expr_tree_unref (new_cell->parsed_node);
new_cell->parsed_node = NULL;
}
}
if (new_cell->parsed_node){
char *new_text, *formula;
if (paste_flags & PASTE_FORMULAS){
string_unref (new_cell->entered_text);
new_text = expr_decode_tree (
new_cell->parsed_node,
target_col, target_row);
formula = g_copy_strings ("=", new_text, NULL);
new_cell->entered_text = string_get (formula);
g_free (formula);
g_free (new_text);
cell_formula_changed (new_cell);
} else {
expr_tree_unref (new_cell->parsed_node);
new_cell->parsed_node = NULL;
}
}
if (!(paste_flags & PASTE_FORMULAS)){
char *rendered;
rendered = value_string (new_cell->value);
string_unref (new_cell->entered_text);
new_cell->entered_text = string_get (rendered);
g_free (rendered);
}
sheet_redraw_cell_region (dest_sheet,
target_col, target_row,
target_col, target_row);
return new_cell->parsed_node != 0;
}
void
clipboard_paste_region (CellRegion *region, Sheet *dest_sheet, int dest_col, int dest_row, int paste_flags)
{
CellCopyList *l;
int paste_formulas = paste_flags & PASTE_FORMULAS;
int paste_formats = paste_formulas & PASTE_FORMATS;
int formulas = 0;
g_return_if_fail (region != NULL);
g_return_if_fail (dest_sheet != NULL);
......@@ -81,10 +130,12 @@ clipboard_paste_region (CellRegion *region, Sheet *dest_sheet, int dest_col, int
dest_col + region->cols - 1,
dest_row + region->rows - 1);
sheet_redraw_cell_region (dest_sheet,
dest_col, dest_row,
dest_col + region->cols - 1,
dest_row + region->rows - 1);
/* If no operations are defined, we clear the area */
if (!(paste_flags & PASTE_OP_MASK))
sheet_redraw_cell_region (dest_sheet,
dest_col, dest_row,
dest_col + region->cols - 1,
dest_row + region->rows - 1);
/* Paste each element */
for (l = region->list; l; l = l->next){
......@@ -96,44 +147,13 @@ clipboard_paste_region (CellRegion *region, Sheet *dest_sheet, int dest_col, int
target_row = dest_row + c_copy->row_offset;
new_cell = cell_copy (c_copy->cell);
sheet_cell_add (dest_sheet, new_cell, target_col, target_row);
if (new_cell->parsed_node){
char *new_text, *formula;
if (paste_formulas){
string_unref (new_cell->entered_text);
new_text = expr_decode_tree (
new_cell->parsed_node,
target_col, target_row);
formula = g_copy_strings ("=", new_text, NULL);
new_cell->entered_text = string_get (formula);
g_free (formula);
g_free (new_text);
cell_formula_changed (new_cell);
} else {
expr_tree_unref (new_cell->parsed_node);
new_cell->parsed_node = NULL;
}
}
if (!paste_formulas){
char *rendered;
rendered = value_string (new_cell->value);
string_unref (new_cell->entered_text);
new_cell->entered_text = string_get (rendered);
g_free (rendered);
}
sheet_redraw_cell_region (dest_sheet,
target_col, target_row,
target_col, target_row);
formulas |= paste_cell (dest_sheet, new_cell, target_col, target_row, paste_flags);
}
/* Trigger a recompute */
if (formulas)
workbook_recalc (dest_sheet->workbook);
}
void
......@@ -192,8 +212,8 @@ dialog_paste_special (void)
{
GtkWidget *dialog, *hbox;
GtkWidget *f1, *f1v, *f2, *f2v;
GSList *group_type, *group_ops, *l;
int i, result;
GSList *group_type, *group_ops;
int result, i;
dialog = gnome_dialog_new (_("Paste special"),
GNOME_STOCK_BUTTON_OK,
......
......@@ -37,28 +37,17 @@ expr_parse_string (char *expr, int col, int row, char **error_msg)
return NULL;
}
/*
* eval_expr_release:
* @ExprTree: The tree to be released
*
* This releases all of the resources used by a tree.
* It is only used internally by eval_expr_unref
*/
void
eval_expr_release (ExprTree *tree)
static void
do_expr_tree_ref (ExprTree *tree)
{
g_return_if_fail (tree != NULL);
g_return_if_fail (tree->ref_count > 0);
tree->ref_count++;
switch (tree->oper){
case OP_VAR:
break;
case OP_CONSTANT:
value_release (tree->u.constant);
break;
case OP_FUNCALL:
symbol_unref (tree->u.function.symbol);
break;
case OP_EQUAL:
......@@ -73,24 +62,70 @@ eval_expr_release (ExprTree *tree)
case OP_DIV:
case OP_EXP:
case OP_CONCAT:
eval_expr_release (tree->u.binary.value_a);
eval_expr_release (tree->u.binary.value_b);
do_expr_tree_ref (tree->u.binary.value_a);
do_expr_tree_ref (tree->u.binary.value_b);
break;
case OP_NEG:
eval_expr_release (tree->u.value);
do_expr_tree_ref (tree->u.value);
break;
}
g_free (tree);
}
/*
* expr_tree_ref:
* Increments the ref_count for part of a tree
*/
void
expr_tree_ref (ExprTree *tree)
{
g_return_if_fail (tree != NULL);
g_return_if_fail (tree->ref_count > 0);
tree->ref_count++;
do_expr_tree_ref (tree);
}
static void
do_expr_tree_unref (ExprTree *tree)
{
tree->ref_count--;
switch (tree->oper){
case OP_VAR:
break;
case OP_CONSTANT:
if (tree->ref_count == 0)
value_release (tree->u.constant);
break;
case OP_FUNCALL:
if (tree->ref_count == 0)
symbol_unref (tree->u.function.symbol);
break;
case OP_EQUAL:
case OP_GT:
case OP_LT:
case OP_GTE:
case OP_LTE:
case OP_NOT_EQUAL:
case OP_ADD:
case OP_SUB:
case OP_MULT:
case OP_DIV:
case OP_EXP:
case OP_CONCAT:
do_expr_tree_unref (tree->u.binary.value_a);
do_expr_tree_unref (tree->u.binary.value_b);
break;
case OP_NEG:
do_expr_tree_unref (tree->u.value);
break;
}
if (tree->ref_count == 0)
g_free (tree);
}
void
......@@ -99,9 +134,7 @@ expr_tree_unref (ExprTree *tree)
g_return_if_fail (tree != NULL);
g_return_if_fail (tree->ref_count > 0);
tree->ref_count--;
if (tree->ref_count == 0)
eval_expr_release (tree);
do_expr_tree_unref (tree);
}
void
......
......@@ -143,9 +143,6 @@ char *expr_decode_tree (ExprTree *tree, int col, int row);
void expr_tree_ref (ExprTree *tree);
void expr_tree_unref (ExprTree *tree);
/* Do not use this routine, it is intended to be used internally */
void eval_expr_release (ExprTree *tree);
Value *eval_expr (void *asheet, ExprTree *tree,
int col, int row,
char **error_string);
......
......@@ -36,12 +36,10 @@ gtk_radio_group_get_selected (GSList *radio_group)
c = g_slist_length (radio_group);
for (i = 0, l = radio_group; l; l = l->next, i++){
for (i = 0; radio_group; radio_group = radio_group->next, i++){
GtkRadioButton *button = radio_group->data;
GtkRadioButton *button = l->data;
if (GTK_TOGGLE_BUTTON (button)->active){
if (GTK_TOGGLE_BUTTON (button)->active)
return c - i - 1;
}
}
return 0;
......
......@@ -36,12 +36,10 @@ gtk_radio_group_get_selected (GSList *radio_group)
c = g_slist_length (radio_group);
for (i = 0, l = radio_group; l; l = l->next, i++){
for (i = 0; radio_group; radio_group = radio_group->next, i++){
GtkRadioButton *button = radio_group->data;
GtkRadioButton *button = l->data;
if (GTK_TOGGLE_BUTTON (button)->active){
if (GTK_TOGGLE_BUTTON (button)->active)
return c - i - 1;
}
}
return 0;
......
......@@ -427,44 +427,53 @@ item_grid_event (GnomeCanvasItem *item, GdkEvent *event)
gnome_canvas_item_ungrab (item, event->button.time);
return 1;
}
break;
case GDK_MOTION_NOTIFY:
scroll_x = scroll_y = 0;
if (event->motion.x < 0){
event->motion.x = 0;
scroll_x = 1;
} if (event->motion.y < 0){
event->motion.y = 0;
scroll_y = 1;
}
convert (canvas, event->motion.x, event->motion.y, &x, &y);
if (!item_grid->selecting)
if (event->button == 1){
scroll_x = scroll_y = 0;
if (event->motion.x < 0){
event->motion.x = 0;
scroll_x = 1;
} if (event->motion.y < 0){
event->motion.y = 0;
scroll_y = 1;
}
convert (canvas, event->motion.x, event->motion.y, &x, &y);
if (!item_grid->selecting)
return 1;
col = find_col (item_grid, event->motion.x, NULL);
row = find_row (item_grid, event->motion.y, NULL);
sheet_selection_extend_to (sheet, col, row);
return 1;
col = find_col (item_grid, event->motion.x, NULL);
row = find_row (item_grid, event->motion.y, NULL);
sheet_selection_extend_to (sheet, col, row);
return 1;
}
break;
case GDK_BUTTON_PRESS:
convert (canvas, event->button.x, event->button.y, &x, &y);
col = find_col (item_grid, event->button.x, NULL);
row = find_row (item_grid, event->button.y, NULL);
gnumeric_sheet_accept_pending_output (gsheet);
gnumeric_sheet_cursor_set (gsheet, col, row);
if (!(event->button.state & GDK_SHIFT_MASK))
sheet_selection_clear_only (sheet);
item_grid->selecting = 1;
sheet_selection_append (sheet, col, row);
gnome_canvas_item_grab (item,
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL,
event->button.time);
return 1;
switch (event->button){
case 1:
convert (canvas, event->button.x, event->button.y, &x, &y);
col = find_col (item_grid, event->button.x, NULL);
row = find_row (item_grid, event->button.y, NULL);
gnumeric_sheet_accept_pending_output (gsheet);
gnumeric_sheet_cursor_set (gsheet, col, row);
if (!(event->button.state & GDK_SHIFT_MASK))
sheet_selection_clear_only (sheet);
item_grid->selecting = 1;
sheet_selection_append (sheet, col, row);
gnome_canvas_item_grab (item,
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL,
event->button.time);
return 1;
case 3:
}
default:
return 0;
}
......
......@@ -91,6 +91,7 @@ exp: NUMBER { $$ = $1 }
| CONSTANT { $$ = $1 }
| exp '+' exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_ADD;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -98,6 +99,7 @@ exp: NUMBER { $$ = $1 }
| exp '-' exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_SUB;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -105,6 +107,7 @@ exp: NUMBER { $$ = $1 }
| exp '*' exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_MULT;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -112,6 +115,7 @@ exp: NUMBER { $$ = $1 }
| exp '/' exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_DIV;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -119,18 +123,21 @@ exp: NUMBER { $$ = $1 }
| exp '=' exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_EQUAL;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
}
| exp '<' exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_LT;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
}
| exp '>' exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_GT;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -138,6 +145,7 @@ exp: NUMBER { $$ = $1 }
| exp GTE exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_GTE;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -145,6 +153,7 @@ exp: NUMBER { $$ = $1 }
| exp NE exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_NOT_EQUAL;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -152,6 +161,7 @@ exp: NUMBER { $$ = $1 }
| exp LTE exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_LTE;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -159,16 +169,19 @@ exp: NUMBER { $$ = $1 }
| '(' exp ')' {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$ = $2;
}
| '-' exp %prec NEG {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_NEG;
$$->u.value = $2;
}
| exp '&' exp {
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_CONCAT;
$$->u.binary.value_a = $1;
$$->u.binary.value_b = $3;
......@@ -182,6 +195,7 @@ exp: NUMBER { $$ = $1 }
b = $3->u.constant->v.cell;
$$ = p_new (ExprTree);
$$->ref_count = 1;
$$->oper = OP_CONSTANT;
$$->u.constant = v_new ();
$$->u.constant->type = VALUE_CELLRANGE;
......@@ -253,6 +267,7 @@ return_cellref (char *p)
/* Ok, parsed successfully, create the return value */
e = p_new (ExprTree);
e->ref_count = 1;
v = v_new ();
e->oper = OP_VAR;
......@@ -286,7 +301,8 @@ return_symbol (char *string)
ExprTree *e = p_new (ExprTree);
Symbol *sym;
int type;
e->ref_count = 1;
sym = symbol_lookup (string);
type = STRING;
......@@ -360,7 +376,8 @@ int yylex (void)
case '6': case '7': case '8': case '9': case '.': {
ExprTree *e = p_new (ExprTree);
Value *v = v_new ();
e->ref_count = 1;
is_float = c == '.';
p = parser_expr-1;
tmp = parser_expr;
......@@ -597,7 +614,7 @@ static void
forget_tree (ExprTree *tree)
{
forget (ALLOC_BUFFER, tree);
eval_expr_release (tree);
expr_tree_unref (tree);
}
/*
......
#include <glib.h>
#include <ctype.h>
#include "numbers.h"
#include "token.h"
#include "string.h"
#define CANSKIP(x) ((x) == ' ' || (x) == '\t')
int
token_get_next (char **str, token_result_t *res)
{
char *p, *q, *start;
int mp_res, len;
g_return_val_if_fail (str != NULL, TOKEN_ERROR);
g_return_val_if_fail (*str != NULL, TOKEN_ERROR);
g_return_val_if_fail (res != NULL, TOKEN_ERROR);
p = *str;
while (*p && CANSKIP (*p))
p++;
if (*p == '.' && *(p+1) == '.'){
*str = p+2;
return TOKEN_ELLIPSIS;
}
if (*p == '\''|| isalpha (*p)){
q = p+1;
if (*p == '\''){
start = p + 1;
while (*q && *q != '\'')
q++;
q++;
} else {
start = p;
while (*q && isalnum (*q))
q++;
}
/* Store result */
len = q - p;
if (len < SMALL_STR_TOKEN)
res->v.str_value = res->str_inline;
else
res->v.str_value = g_new (char, len + 1);
res->type = R_STRING;
strncpy (res->v.str_value, p, len);
res->v.str_value [len] = 0;
*str = q;
return TOKEN_IDENTIFIER;
}
if (isdigit (*p)){
int is_float = 0;
char *copy;
/* Scan for the whole number */
q = p;
while (isdigit (*q) || *q == '.'){
if (*q == '.')
is_float = 1;
q++;
}
copy = alloca (q - p + 1);
strncpy (copy, p, q - p);
copy [q-p] = 0;
/* Convert to MP number */
if (is_float){
res->type = R_FLOAT;
mp_res = mpf_init_set_str (res->v.float_value, copy, 10);
} else {
res->type = R_INTEGER;
mp_res = mpz_init_set_str (res->v.int_value, copy, 10);
}
*str = q;
return TOKEN_NUMBER;
}
if (*p)
*str = p + 1;
else
*str = p;
res->type = R_CHAR;
return *p;
}
/*
* Should be invoked when a token has been used
*/
void
token_done (token_result_t *r)
{
g_return_if_fail (r != NULL);
if (r->type == R_STRING){
if (r->v.str_value != &r->str_inline)
g_free (r->v.str_value);
} else if (r->type == R_FLOAT)
mpf_clear (r->v.float_value);
else if (r->type == R_INTEGER)
mpz_clear (r->v.int_value);
r->type = R_NONE;
}
#ifndef TOKEN_H
#define TOKEN_H
typedef enum {
TOKEN_IDENTIFIER = -1,
TOKEN_NUMBER = -2,
TOKEN_ELLIPSIS = -4,
TOKEN_ERROR = -5
} TokenType;
#define SMALL_STR_TOKEN 20
typedef enum {
R_NONE,
R_CHAR,
R_INTEGER,
R_STRING,
R_FLOAT
} token_tag_t;
typedef struct {
token_tag_t type;
union {
mpz_t int_value;
char *str_value;
mpf_t float_value;
} v;
char str_inline [SMALL_STR_TOKEN+1];
} token_result_t;
int token_get_next (char **str, token_result_t *res);
void token_done (token_result_t *res);
#endif