/********************************************************************
This file is part of the abs 0.907 distribution. abs is a spreadsheet
with graphical user interface.
Copyright (C) 1998-2001 André Bertin (Andre.Bertin@ping.be)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version if in the same spirit as version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Concact: abs@pi.be
http://home.pi.be/bertin/abs.shtml
*********************************************************************/
#include "cell.h"
#include "worksheet.h"
#include "workbook.h"
#include "style.h"
#include "y.tab.h"
#include "memory.h"
#include "date.h"
#include "cell_vb.h"
#include "gram_ext.h"
#include "application.h"
#include <string.h>
static int updating = 0;
static int parsing = 0;
static int setting_formula = 0;
static int ncell = 0;
static int parsingmacro;
static Cell **toredraw = NULL;
static int ntoredraw = 0;
static char tmpbuf[256];
Cell *ActiveCell;
Cell *
cell_activate (Cell * cell)
{
ActiveCell = cell;
if (ActiveWorksheet != NULL)
{
ActiveWorksheet->activecell = cell;
if (ActiveWorksheet->cur_r != cell->r && ActiveWorksheet->cur_c != cell->c)
worksheet_setcursor (ActiveWorksheet, cell->r, cell->c);
}
return ActiveCell;
}
Cell *
newcell (r, c)
int r, c;
{
Cell *nc;
nc = (Cell *) absmalloc (sizeof (Cell), "newcell:Cell ");
if (nc == NULL)
{
fprintf (stderr, "Cell: not allocated!");
return NULL;
}
nc->val.rec.d = 0.0;
nc->val.type = DOUBLE;
nc->formula = NULL;
nc->style = NULL;
nc->r = r;
nc->c = c;
nc->familly = NULL;
nc->worksheet = ActiveWorksheet;
nc->tree = NULL;
nc->type = undef;
nc->objnum = ncell++;
return nc;
}
int
clear_cell (Cell * cell)
{
if (cell == NULL)
return 1;
if (cell->val.type == STRING_CONSTANT && cell->val.rec.s != cell->formula + 1)
if (cell->val.rec.s != NULL)
absfree (cell->val.rec.s, "freecell:cell->val.rec.s ");
if (cell->formula != NULL)
absfree (cell->formula, "freecell:cell->formula ");
if (cell->tree != NULL)
{
freenode (cell->tree);
cell->tree = NULL;
}
if (cell->style != NULL)
{
freestyle (cell->style);
cell->style = NULL;
}
cell->val.rec.d = 0.0;
cell->val.type = DOUBLE;
cell->formula = NULL;
cell_isnew (cell);
nupdate2 (cell, 1);
cell->type = undef;
return 0;
}
int
freecell (cell)
Cell *cell;
{
if (cell == NULL)
return 1;
if (cell->val.type == STRING_CONSTANT && cell->val.rec.s != cell->formula + 1)
if (cell->val.rec.s != NULL)
absfree (cell->val.rec.s, "freecell:cell->val.rec.s ");
if (cell->formula != NULL)
absfree (cell->formula, "freecell:cell->formula ");
if (cell->tree != NULL)
{
freenode (cell->tree);
cell->tree = NULL;
}
if (cell->style != NULL)
{
freestyle (cell->style);
cell->style = NULL;
}
absfree (cell, "freecell:cell ");
return 0;
}
int
cell_write (cell, fp)
Cell *cell;
FILE *fp;
{
int deci, format;
char *end = NULL;
char chr[2];
int len = 0;
int i;
if (cell == NULL)
return -1;
if (cell->type == constant)
{
fprintf (fp, "absnc(%d,%d,\"", cell->r, cell->c);
fprintf (fp, "%g", cell_getvalue (cell));
fprintf (fp, "\")\n");
}
else if (cell->type == text || cell->type == formula)
{
fprintf (fp, "absnc(%d,%d,\"", cell->r, cell->c);
if (cell->formula != NULL)
{
chr[1] = '\0';
end = strchr (cell->formula, '\n');
if (end != NULL)
end[0] = '\0';
len = strlen (cell->formula);
if (cell->formula[0] != '\'' && cell->formula[0] != '-'
&& cell->formula[0] != '=' && cell->formula[0] != '+'
&& !('0' <= cell->formula[0] && cell->formula[0] <= '9'))
fprintf (fp, "=");
for (i = 0; i < len; i++)
{
if (cell->formula[i] == '\"')
fprintf (fp, "\"");
chr[0] = cell->formula[i];
fprintf (fp, "%s", chr);
}
fprintf (fp, "\")\n");
}
}
if (cell->style != NULL)
{
if (getstyle (cell->style, STY_BORDER_TOP) &&
getstyle (cell->style, STY_BORDER_BOT) &&
getstyle (cell->style, STY_BORDER_RIG) &&
getstyle (cell->style, STY_BORDER_LEF)
)
{
fprintf (fp, "Cells(%d,%d).Borders.LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
}
else
{
if (getstyle (cell->style, STY_BORDER_TOP))
fprintf (fp, "Cells(%d,%d).Borders(xlEdgeTop).LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
if (getstyle (cell->style, STY_BORDER_BOT))
fprintf (fp, "Cells(%d,%d).Borders(xlEdgeBottom).LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
if (getstyle (cell->style, STY_BORDER_RIG))
fprintf (fp, "Cells(%d,%d).Borders(xlEdgeRight).LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
if (getstyle (cell->style, STY_BORDER_LEF))
fprintf (fp, "Cells(%d,%d).Borders(xlEdgeLeft).LineStyle = xlLineStyleContinuous\n", cell->r, cell->c);
}
if (getstyle (cell->style, STY_FONT) != getstyle (ActiveWorkbook->style, STY_FONT))
switch (getstyle (cell->style, STY_FONT))
{
case 0:
fprintf (fp, "Cells(%d,%d).Font.Name = \"Fixed\"\n", cell->r, cell->c);
break;
case 1:
fprintf (fp, "Cells(%d,%d).Font.Name = \"Courier\"\n", cell->r, cell->c);
break;
case 2:
fprintf (fp, "Cells(%d,%d).Font.Name = \"Helvetica\"\n", cell->r, cell->c);
break;
case 3:
fprintf (fp, "Cells(%d,%d).Font.Name = \"Times\"\n", cell->r, cell->c);
break;
case 4:
fprintf (fp, "Cells(%d,%d).Font.Name = \"Symbol\"\n", cell->r, cell->c);
break;
}
if (getstyle (cell->style, STY_FONTS) != getstyle (ActiveWorkbook->style, STY_FONTS))
switch (getstyle (cell->style, STY_FONTS))
{
case 0:
fprintf (fp, "Cells(%d,%d).Font.Size = 6\n", cell->r, cell->c);
break;
case 1:
fprintf (fp, "Cells(%d,%d).Font.Size = 8\n", cell->r, cell->c);
break;
case 2:
fprintf (fp, "Cells(%d,%d).Font.Size = 10\n", cell->r, cell->c);
break;
case 3:
fprintf (fp, "Cells(%d,%d).Font.Size = 12\n", cell->r, cell->c);
break;
case 4:
fprintf (fp, "Cells(%d,%d).Font.Size = 14\n", cell->r, cell->c);
break;
case 5:
fprintf (fp, "Cells(%d,%d).Font.Size = 18\n", cell->r, cell->c);
break;
case 6:
fprintf (fp, "Cells(%d,%d).Font.Size = 24\n", cell->r, cell->c);
break;
}
if (getstyle (cell->style, STY_FONTW) == 1 || getstyle (cell->style, STY_FONTW) == 3)
fprintf (fp, "Cells(%d,%d).Font.Bold = True \n", cell->r, cell->c);
if (getstyle (cell->style, STY_FONTW) == 2 || getstyle (cell->style, STY_FONTW) == 3)
fprintf (fp, "Cells(%d,%d).Font.Italic = True \n", cell->r, cell->c);
if (getstyle (cell->style, STY_JUSTIF) != getstyle (ActiveWorkbook->style, STY_JUSTIF))
switch (getstyle (cell->style, STY_JUSTIF))
{
case 0:
fprintf (fp, "Cells(%d,%d).HorizontalAlignment = xlLeft\n",
cell->r, cell->c);
break;
case 1:
fprintf (fp, "Cells(%d,%d).HorizontalAlignment = xlCenter\n",
cell->r, cell->c);
break;
case 2:
fprintf (fp, "Cells(%d,%d).HorizontalAlignment = xlRight\n",
cell->r, cell->c);
break;
}
if (getstyle (cell->style, STY_BG) != getstyle (ActiveWorkbook->style, STY_BG))
fprintf (fp, "Cells(%d,%d).Interior.ColorIndex = %d\n",
cell->r, cell->c, getstyle (cell->style, STY_BG) - 5);
if (getstyle (cell->style, STY_FG) != getstyle (ActiveWorkbook->style, STY_FG))
fprintf (fp, "Cells(%d,%d).Font.ColorIndex = %d\n",
cell->r, cell->c, getstyle (cell->style, STY_FG) - 5);
format = getstyle (cell->style, STY_FORMAT);
deci = getstyle (cell->style, STY_DECIMAL);
if ((format != getstyle (ActiveWorkbook->style, STY_FORMAT) ||
deci != getstyle (ActiveWorkbook->style, STY_DECIMAL)) &&
format != 0)
{
if (format >= 2 && format <= 4)
{
fprintf (fp, "Cells(%d,%d).NumberFormat = \"0", cell->r, cell->c);
if (deci)
fprintf (fp, ".");
while (deci > 0)
{
fprintf (fp, "0");
deci--;
};
}
switch (format)
{
case 2:
fprintf (fp, "\"\n");
break;
case 3:
fprintf (fp, "E+00\"\n");
break;
case 4:
fprintf (fp, "%%\"\n");
break;
case 5:
{
fprintf (fp, "Cells(%d,%d).NumberFormat = \"", cell->r, cell->c);
fprintf (fp, "dd/mm/yy\"\n");
break;
}
default:
fprintf (fp, "\"\n");
}
}
}
return 0;
}
int
cell_setnumberformat (cell, buf)
Cell *cell;
char *buf;
{
int deci = 0;
char *dot;
char *token;
if (strstr (buf, "General"))
return 0;
token = strchr (buf, ';');
if (token != NULL)
{
token[0] = '\0';
token++;
}
if (buf == NULL)
return 1;
if (strchr (buf, '/'))
{
cell_setformat (cell, 5, 0);
return 0;
}
dot = strchr (buf, '.');
if (dot != NULL)
while (dot[deci + 1] == '0' && deci < strlen (dot))
{
deci++;
}
if (strchr (buf, 'E') || strchr (buf, 'e'))
{
cell_setformat (cell, 3, deci);
}
else if (strchr (buf, '%'))
{
cell_setformat (cell, 4, deci);
}
else
{
cell_setformat (cell, 2, deci);
}
return 0;
}
int
cell_setformula (cell, str)
Cell *cell;
char *str;
{
int format, deci, date;
int ret;
int len;
int second = 0;
char *buf = NULL;
if (cell == NULL)
{
return 1;
}
if (cell->formula != NULL)
{
if (str != NULL)
if (strcmp (cell->formula, str) == 0)
return 1;
if (cell->val.type == STRING_CONSTANT &&
cell->val.rec.s == cell->formula + 1)
cell->val.rec.s = NULL;
absfree (cell->formula, "cell_setformula:cell->formula ");
cell->formula = NULL;
}
if (cell->tree != NULL)
{
freenode (cell->tree);
cell->tree = NULL;
};
cell_isnew (cell);
if (str == NULL)
{
cell->formula = NULL;
cell->val.rec.d = 0.0;
cell->val.type = DOUBLE;
cell->type = undef;
return -1;
};
while (str[0] == ' ' && str[0] != '\0' && str[0] != '\n')
str++;
len = strlen (str);
if (len < 1)
{
cell->formula = NULL;
cell->val.rec.d = 0.0;
cell->val.type = DOUBLE;
cell->type = undef;
return -1;
};
{
buf = (char *) absmalloc (sizeof (char) * (len + 3), "cell_setformula:buf");
if (len > 1)
if ('0' <= str[1] && str[1] <= '9')
{
second = 1;
}
if (str[0] == '=' ||
str[0] == '+' ||
str[0] == '-' ||
str[0] == '\'' ||
('0' <= str[0] && str[0] <= '9') ||
(len > 1 && str[0] == '.' && second == 1)
)
{
strcpy (buf, str);
}
else
{
buf[0] = '\'';
strcpy (buf + 1, str);
}
cell->formula = (char *) absmalloc (sizeof (char) * (strlen (buf) + 5), "cell_setformula:cell->formula ");
if (cell->formula == NULL)
{
fprintf (stderr, "formula not allocated\n");
absfree (buf, "cell_setformula:buf");
return -2;
}
cell_getformat (cell, &format, &deci);
if (format == 5)
{
date = scandate (buf);
if (date)
sprintf (buf, "%d\n", date);
};
len = strlen (buf);
strcpy (cell->formula, buf);
cell->formula[len] = '\0';
if (strncmp (cell->formula, "'", 1) == 0)
{
cell->val.type = STRING_CONSTANT;
cell->val.rec.s = cell->formula + 1;
cell->type = text;
nupdate2 (cell, 1);
absfree (buf, "cell_setformula:buf");
return 1;
}
cell->type = constant;
ActiveCell = cell;
setting_formula = 1;
ret = parsecell (cell);
if (ret)
{
cell->val.type = STRING_CONSTANT;
cell->val.rec.s = "ERR!";
cell->type = text;
}
else
{
if (cell_is_constant (cell))
{
freenode (cell->tree);
cell->tree = NULL;
absfree (cell->formula, "cell_setformula:cell->formula ");
cell->formula = NULL;
}
else
{
execcelltree (cell);
cell->type = formula;
}
}
setting_formula = 0;
nupdate2 (cell, 1);
absfree (buf, "cell_setformula:buf");
return 0;
}
cell->formula = NULL;
cell->val.type = STRING_CONSTANT;
cell->val.rec.s = NULL;
cell->type = text;
absfree (buf, "cell_setformula:buf");
return 0;
}
int
cell_settext (cell, buf)
Cell *cell;
char *buf;
{
char *end;
char *first;
if (cell == NULL)
{
return 1;
}
if (cell->val.type == STRING_CONSTANT)
if (cell->val.rec.s != NULL)
{
absfree (cell->val.rec.s, "cell_settext:cell->val.rec.s ");
cell->val.rec.s = NULL;
}
if (strlen (buf) > 0)
{
end = strchr (buf, '\n');
if (end != NULL)
end = '\0';
cell->val.rec.s = (char *) absmalloc (sizeof (char) * (strlen (buf) + 5), "cell_settext:cell->formula ");
if (cell->val.rec.s == NULL)
fprintf (stderr, "val.rec.s not allocated\n");
first = buf;
while (*first == ' ' && first < buf + strlen (buf))
first++;
if (*first == '\'')
{
strcpy (cell->val.rec.s, "'");
strcat (cell->val.rec.s, first + 1);
cell->formula = cell->val.rec.s;
cell->val.rec.s = cell->formula + 1;
}
else
strcpy (cell->val.rec.s, buf);
}
else
cell->val.rec.s = NULL;
cell->val.type = STRING_CONSTANT;
cell->type = text;
return 0;
}
char *
cell_getformula (cell)
Cell *cell;
{
if (cell != NULL)
switch (cell->type)
{
case constant:
{
double val = cell_getvalue (cell);
if (val != 0.0)
{
sprintf (tmpbuf, "%g", cell_getvalue (cell));
return tmpbuf;
}
break;
}
case text:
return cell->formula;
case formula:
return cell->formula;
case undef:
return NULL;
}
return NULL;
}
char *
cell_getnumberformat (cell)
Cell *cell;
{
return NULL;
}
double
cell_setvalue (cell, val)
Cell *cell;
double val;
{
if (cell != NULL)
{
obj o;
o.rec.d = val;
o.type = DOUBLE;
cell_setobj (cell, o);
}
return 0.0;
}
obj
cell_setobj (cell, o)
Cell *cell;
obj o;
{
char tmp[64];
char *buf;
if (o.type == STRING)
o.type = STRING_CONSTANT;
if (cell != NULL)
{
switch (o.type)
{
case STRING_CONSTANT:
{
if (o.rec.s == NULL)
{
clear_cell (cell);
return o;
}
buf = absmalloc (sizeof (char) * (strlen (o.rec.s) + 2), "cell_setobj:buf");
if (o.rec.s[0] == '\'')
strcpy (buf, o.rec.s);
else
sprintf (buf, "'%s", o.rec.s);
cell_setformula (cell, buf);
absfree (buf, "cell_setobj:buf");
break;
};
case DOUBLE:
sprintf (tmp, "%f", o.rec.d);
cell_setformula (cell, tmp);
break;
case INTEGER:
sprintf (tmp, "%d", o.rec.i);
cell_setformula (cell, tmp);
break;
}
}
return o;
}
obj
cell_setresval (cell, o)
Cell *cell;
obj o;
{
int len = 0;
if (o.type == STRING)
o.type = STRING_CONSTANT;
if (cell != NULL)
{
if (o.type == STRING_CONSTANT && o.rec.s != NULL)
{
len = strlen (o.rec.s);
}
if (o.type == STRING_CONSTANT && len == 0)
{
if (cell->val.type == STRING_CONSTANT && cell->val.rec.s != NULL)
absfree (cell->val.rec.s, "cell->val.rec.s:null_str");
cell->val.rec.s = NULL;
cell->val.type = STRING_CONSTANT;
return o;
}
if (cell->val.type == STRING_CONSTANT)
{
if (o.type == STRING_CONSTANT)
{
cell->val.rec.s = (char *) absrealloc (cell->val.rec.s, (len + 1) * sizeof (char),
"cell_setresobj::val.rec.s");
strcpy (cell->val.rec.s, o.rec.s);
return cell->val;
}
else
{
if (cell->val.rec.s != NULL)
absfree (cell->val.rec.s, "cell_setresobj::val.rec.s");
cell->val.rec.s = NULL;
}
}
if (o.type == STRING_CONSTANT)
{
cell->val.type = STRING_CONSTANT;
cell->val.rec.s = (char *) absmalloc ((len + 1) * sizeof (char), "cell_setresobj::val.rec.s");
strcpy (cell->val.rec.s, o.rec.s);
return cell->val;
};
cell->val = o;
return cell->val;
}
return o;
}
double
cell_getvalue (cell)
Cell *cell;
{
if (cell == NULL)
{
return 0.0;
}
switch (cell->val.type)
{
case DOUBLE:
return cell->val.rec.d;
case INTEGER:
{
double val = cell->val.rec.i;
return val;
}
}
return 0.0;
}
obj
cell_getobj (cell)
Cell *cell;
{
if (cell == NULL)
{
obj o;
printf ("getvalue for NULL cell\n");
o.type = INTEGER;
o.rec.i = 0;
return o;
}
return cell->val;
}
int
cell_istext (cell)
Cell *cell;
{
if (cell == NULL)
return 0;
if (cell->type == text)
return 1;
return 0;
}
char *
cell_gettext (cell)
Cell *cell;
{
char form[8];
int format, deci;
int dd, mm, yy;
double value;
if (cell == NULL)
{
return NULL;
}
if (cell->type != constant && cell->formula == NULL)
{
return NULL;
}
if (cell->type == text || cell->val.type == STRING_CONSTANT)
return cell->val.rec.s;
cell_getformat (cell, &format, &deci);
value = cell_getvalue (cell);
switch (format)
{
case 1:
{
sprintf (form, "%%g");
sprintf (tmpbuf, form, value);
break;
}
case 2:
{
sprintf (form, "%%.%dlf", deci);
sprintf (tmpbuf, form, value);
break;
}
case 3:
{
sprintf (form, "%%.%de", deci);
sprintf (tmpbuf, form, value);
break;
}
case 4:
{
sprintf (form, "%%.%dlf%%%%", deci);
sprintf (tmpbuf, form, value * 100.);
break;
}
case 5:
{
int date = value;
num2date (date, &dd, &mm, &yy);
sprintf (tmpbuf, "%2d/%2d/%4d", dd, mm, yy);
break;
}
}
return tmpbuf;
}
int
cell_setfg (cell, f)
Cell *cell;
int f;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
setstyle (cell->style, STY_FG, f + 5);
return 0;
}
int
cell_getfg (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_FG);
return getstyle (cell->style, STY_FG);
}
int
cell_setbg (cell, f)
Cell *cell;
int f;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
setstyle (cell->style, STY_BG, f + 5);
return 0;
}
int
cell_getbg (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_BG);
return getstyle (cell->style, STY_BG);
}
int
cell_gettop (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_BORDER_TOP);
return getstyle (cell->style, STY_BORDER_TOP);
}
int
cell_getbot (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_BORDER_BOT);
return getstyle (cell->style, STY_BORDER_BOT);
}
int
cell_getrig (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_BORDER_RIG);
return getstyle (cell->style, STY_BORDER_RIG);
}
int
cell_getlef (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_BORDER_LEF);
return getstyle (cell->style, STY_BORDER_LEF);
}
int
cell_settop (cell, v)
Cell *cell;
int v;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
setstyle (cell->style, STY_BORDER_TOP, v);
return 0;
}
int
cell_setbot (cell, v)
Cell *cell;
int v;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
setstyle (cell->style, STY_BORDER_BOT, v);
return 0;
}
int
cell_setrig (cell, v)
Cell *cell;
int v;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
setstyle (cell->style, STY_BORDER_RIG, v);
return 0;
}
int
cell_setlef (cell, v)
Cell *cell;
int v;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
setstyle (cell->style, STY_BORDER_LEF, v);
return 0;
}
int
cell_setformat (cell, format, deci)
Cell *cell;
int format, deci;
{
double date;
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
if (format == 5 && getstyle (cell->style, STY_FORMAT) != 5)
{
date = scandate (cell_getformula (cell));
if (date)
cell_setvalue (cell, date);
}
setstyle (cell->style, STY_FORMAT, format);
setstyle (cell->style, STY_DECIMAL, deci);
return 0;
}
int
cell_getformat (cell, format, decimal)
Cell *cell;
int *format, *decimal;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
{
*format = getstyle (ActiveWorkbook->style, STY_FORMAT);
*decimal = getstyle (ActiveWorkbook->style, STY_DECIMAL);
return 0;
}
*format = getstyle (cell->style, STY_FORMAT);
*decimal = getstyle (cell->style, STY_DECIMAL);
return 0;
}
int
cell_setjust (cell, just)
Cell *cell;
int just;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
setstyle (cell->style, STY_JUSTIF, just);
return 0;
}
int
cell_getjust (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_JUSTIF);
return getstyle (cell->style, STY_JUSTIF);
}
int
cell_setfont (cell, font, weight, size)
Cell *cell;
int font;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
if (font >= 0)
setstyle (cell->style, STY_FONT, font);
if (weight >= 0)
setstyle (cell->style, STY_FONTW, weight);
if (size >= 0)
setstyle (cell->style, STY_FONTS, size);
return 0;
}
int
cell_fontname (Cell * cell, char *name)
{
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
if (!strcasecmp (name, "fixed"))
setstyle (cell->style, STY_FONT, 0);
if (!strcasecmp (name, "courier"))
setstyle (cell->style, STY_FONT, 1);
if (!strcasecmp (name, "helvetica"))
setstyle (cell->style, STY_FONT, 2);
if (!strcasecmp (name, "times"))
setstyle (cell->style, STY_FONT, 3);
if (!strcasecmp (name, "symbol"))
setstyle (cell->style, STY_FONT, 4);
return 0;
}
int
cell_fontsize (cell, v)
Cell *cell;
int v;
{
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
switch (v)
{
case 6:
setstyle (cell->style, STY_FONTS, 0);
break;
case 8:
setstyle (cell->style, STY_FONTS, 1);
break;
case 10:
setstyle (cell->style, STY_FONTS, 2);
break;
case 12:
setstyle (cell->style, STY_FONTS, 3);
break;
case 14:
setstyle (cell->style, STY_FONTS, 4);
break;
case 18:
setstyle (cell->style, STY_FONTS, 5);
break;
case 24:
setstyle (cell->style, STY_FONTS, 6);
break;
}
return 0;
}
int
cell_fontbold (cell, v)
Cell *cell;
int v;
{
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
if (v == 0)
{
if (getstyle (cell->style, STY_FONTW) > 1)
setstyle (cell->style, STY_FONTW, 2);
else
setstyle (cell->style, STY_FONTW, 0);
}
else
{
if (getstyle (cell->style, STY_FONTW) > 1)
setstyle (cell->style, STY_FONTW, 3);
else
setstyle (cell->style, STY_FONTW, 1);
}
return 0;
}
int
cell_fontitalic (cell, v)
Cell *cell;
int v;
{
int w;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
w = getstyle (cell->style, STY_FONTW);
if (v == 0)
{
if (w == 1 || w == 3)
setstyle (cell->style, STY_FONTW, 1);
else
setstyle (cell->style, STY_FONTW, 0);
}
else
{
if (w == 1 || w == 3)
setstyle (cell->style, STY_FONTW, 3);
else
setstyle (cell->style, STY_FONTW, 2);
}
return 0;
}
int
cell_getfont (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_FONT);
return getstyle (cell->style, STY_FONT);
return 0;
}
int
cell_getfontw (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_FONTW);
return getstyle (cell->style, STY_FONTW);
return 0;
}
int
cell_getfonts (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_FONTS);
return getstyle (cell->style, STY_FONTS);
return 0;
}
int
cell_setborders (cell, border, type)
Cell *cell;
int border;
int type;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
if (border == 8 || border == 0)
setstyle (cell->style, STY_BORDER_TOP, type);
if (border == 7 || border == 0)
setstyle (cell->style, STY_BORDER_LEF, type);
if (border == 9 || border == 0)
setstyle (cell->style, STY_BORDER_BOT, type);
if (border == 10 || border == 0)
setstyle (cell->style, STY_BORDER_RIG, type);
return 0;
}
int
cell_setborder (cell, border)
Cell *cell;
int border;
{
if (cell == NULL)
return -1;
if (cell->style == NULL)
cell->style = newstyle (STY_CELL);
setstyle (cell->style, STY_BORDER, border);
return 0;
}
int
cell_getborder (cell)
Cell *cell;
{
if (cell == NULL || cell->style == NULL)
return getstyle (ActiveWorkbook->style, STY_BORDER);
return getstyle (cell->style, STY_BORDER);
return 0;
}
int
parsecell (cell)
Cell *cell;
{
ActiveCell = cell;
if (cell == NULL)
return -1;
if (cell->formula == NULL)
return -2;
cell->tree = parseexpression (cell->formula);
if (cell->tree == NULL)
return 1;
setcelltree (cell->tree);
return 0;
}
int
copymod (ii, jj, i, j, incr)
int i, j, ii, jj, incr;
{
Cell *cell1;
Cell *cell2;
cell1 = (Cell *) applicationcell (i, j, 1);
cell2 = (Cell *) applicationcell (ii, jj, 1);
return copymod2 (cell1, cell2, i, j, (i - ii) * incr, (j - jj) * incr);
}
int
copymod2 (cell1, cell2, _curi, _curj, _di, _dj)
Cell *cell1;
Cell *cell2;
int _curi, _curj, _di, _dj;
{
setdi (_di);
setdj (_dj);
cell_setformula (cell1, cell_getformula (cell2));
setdi (0);
setdj (0);
return 0;
}
int
copymod3 (cell1, cell2, incr)
Cell *cell1;
Cell *cell2;
int incr;
{
if (cell1 == NULL || cell2 == NULL)
return -1;
setdi ((cell1->r - cell2->r) * incr);
setdj ((cell1->c - cell2->c) * incr);
cell_setformula (cell1, cell_getformula (cell2));
setdi (0);
setdj (0);
return 0;
return 0;
}
char *
tolower (char *s)
{
int j;
int len;
len = strlen (s);
for (j = 0; j < len; j++)
if (s[j] >= 'A' && s[j] <= 'Z')
s[j] = 'a' + s[j] - 'A';
return s;
}
char *
sstrcasestr_ (char *str1, char *str2)
{
char *s1;
char *s2;
char *pos = NULL;
int l1;
s1 = strdup (str1);
if (s1 == NULL)
return NULL;
s2 = strdup (str2);
if (s2 == NULL)
{
free (s1);
return NULL;
}
tolower (s1);
tolower (s2);
pos = strstr (s1, s2);
l1 = pos - s1;
free (s1);
free (s2);
if (pos == NULL)
return NULL;
return str1 + l1;
}
int
cell_chgwksname (Cell * cell, char *oldname, char *newname)
{
int len = 0;
int i = 0;
int diffsize;
char *newformula = NULL;
char *old, *pos, *end;
if (cell == NULL)
return -1;
if (cell->formula == NULL)
return 0;
if (cell->tree == NULL)
return 0;
if (oldname == NULL || newname == NULL)
return -1;
if (strlen (oldname) < 1 || strlen (newname) < 1)
return -1;
if (!strcmp (oldname, newname))
return 0;
if (sstrcasestr_ (cell->formula, oldname) == NULL)
return 0;
diffsize = strlen (oldname) - strlen (newname);
old = absmalloc ((strlen (oldname) + 2) * sizeof (char), "cell_chgwksname:old");
sprintf (old, "%s!", oldname);
pos = sstrcasestr_ (cell->formula, old);
while (pos != NULL)
{
len = strlen (cell->formula);
newformula = (char *) absmalloc ((len + 1 + diffsize) * sizeof (char), "cell_chgwksname:newformula");
end = strchr (pos, '!');
pos[0] = '\0';
i = strlen (cell->formula) + strlen (newname) + 1;
sprintf (newformula, "%s%s%s", cell->formula, newname, end);
absfree (cell->formula, "cell_chgwksname:cell->formula");
cell->formula = newformula;
end = sstrcasestr_ (cell->formula, old);
if (end > cell->formula + i)
pos = end;
else
pos = NULL;
}
return 0;
}
int
cell1isfcell2 (cell1, cell2)
Cell *cell1;
Cell *cell2;
{
int numpar1;
int numchi2;
int k;
Cell **tmp;
if (cell1 == cell2)
return 1;
if (cell1->familly == NULL)
{
cell1->familly = (Familly *) absmalloc (sizeof (Familly), "cell1isfcell2:cell1->familly ");
if (cell1->familly == NULL)
fprintf (stderr, "cell1->familly not allocated!\n");
cell1->familly->numpar = 0;
cell1->familly->dimparlist = 0;
cell1->familly->parentlist = NULL;
cell1->familly->numchi = 0;
cell1->familly->dimchilist = 0;
cell1->familly->childlist = NULL;
}
if (cell2->familly == NULL)
{
cell2->familly = (Familly *) absmalloc (sizeof (Familly), "cell1isfcell2:cell2->familly ");
if (cell2->familly == NULL)
fprintf (stderr, "cell2->familly not allocated!\n");
cell2->familly->numpar = 0;
cell2->familly->dimparlist = 0;
cell2->familly->parentlist = NULL;
cell2->familly->numchi = 0;
cell2->familly->dimchilist = 0;
cell2->familly->childlist = NULL;
}
numpar1 = cell1->familly->numpar;
numchi2 = cell2->familly->numchi;
if (cell1->familly->dimparlist < numpar1 + 1)
{
tmp = (Cell **) absmalloc (sizeof (Cell *) * (2 * numpar1 + 2), "cell1isfcell2:tmp ");
if (tmp == NULL)
fprintf (stderr, "tmp not allocated!\n");
for (k = 0; k < numpar1; k++)
tmp[k] = cell1->familly->parentlist[k];
if (cell1->familly->parentlist != NULL)
absfree (cell1->familly->parentlist, "cell1isfcell2:cell1->familly->parentlist ");
cell1->familly->parentlist = tmp;
cell1->familly->dimparlist = 2 * numpar1 + 2;
}
if (cell2->familly->dimchilist < numchi2 + 1)
{
tmp = (Cell **) absmalloc (sizeof (Cell *) * (2 * numchi2 + 2), "cell1isfcell2:tmp ");
if (tmp == NULL)
fprintf (stderr, "tmp not allocated!\n");
for (k = 0; k < numchi2; k++)
{
tmp[k] = cell2->familly->childlist[k];
}
if (cell2->familly->dimchilist > 0 && cell2->familly->childlist != NULL)
absfree (cell2->familly->childlist, "cell1isfcell2:cell2->familly->childlist ");
cell2->familly->childlist = tmp;
cell2->familly->dimchilist = 2 * numchi2 + 2;
}
for (k = 0; k < numpar1; k++)
{
if (cell2 == cell1->familly->parentlist[k])
return 2;
}
cell1->familly->parentlist[numpar1] = cell2;
cell1->familly->numpar++;
cell2->familly->childlist[numchi2] = cell1;
cell2->familly->numchi++;
return 0;
}
int
pfamilly2 (cell)
Cell *cell;
{
int k;
Cell *cell2;
if (cell == NULL)
fprintf (stderr, "pfamilly of null cell\n");
if (cell->familly == NULL)
return 1;
printf ("cell %d (r=%d c=%d)\n", cell->objnum, cell->r, cell->c);
for (k = 0; k < cell->familly->numchi; k++)
{
cell2 = cell->familly->childlist[k];
if (cell2)
printf (" - child %d: %d (wks=%s r=%d c=%d)\n", k, cell2->objnum, cell2->worksheet->Name, cell2->r, cell2->c);
else
printf (" - child %d: NULL\n", k);
}
for (k = 0; k < cell->familly->numpar; k++)
{
cell2 = cell->familly->parentlist[k];
if (cell2)
printf (" - parent %d: %d (wks=%s r=%d c=%d)\n", k, cell2->objnum, cell2->worksheet->Name, cell2->r, cell2->c);
else
printf (" - parent %d: NULL\n", k);
}
return 0;
}
void
cell_auditcell (Cell * cell)
{
pfamilly2 (cell);
}
int
cell_isnew (cell)
Cell *cell;
{
int k;
Cell *i2j2;
int l, found;
if (updating || parsing)
return 1;
if (cell->familly == NULL)
return 2;
for (k = 0; k < cell->familly->numpar; k++)
{
i2j2 = cell->familly->parentlist[k];
found = 0;
if (i2j2->familly != NULL)
{
for (l = 0; l < i2j2->familly->numchi; l++)
{
if (i2j2->familly->childlist[l] == cell)
found = 1;
if (found)
{
i2j2->familly->childlist[l] = i2j2->familly->childlist[l + 1];
}
}
i2j2->familly->numchi--;
}
}
if (cell->familly->numpar > 0)
{
cell->familly->numpar = 0;
absfree (cell->familly->parentlist, "cell_isnew:cell->familly->parentlist ");
cell->familly->parentlist = NULL;
cell->familly->dimparlist = 0;
}
cell->familly->numpar = 0;
if (cell->familly->numchi == 0)
{
if (cell->familly->dimchilist > 0)
absfree (cell->familly->childlist, "cell_isnew:cell->familly->childlist ");
absfree (cell->familly, "cell_isnew:cell->familly ");
cell->familly = NULL;
}
return 0;
}
extern int xdrawcell ();
static Cell *iterbase;
int
nupdate2 (Cell * cell, int redraw)
{
int k;
Cell *cell2;
if (parsing)
return 1;
if (cell == NULL)
return 2;
if (cell->familly == NULL)
{
return 3;
}
if (updating == 0)
iterbase = cell;
else if (cell == iterbase)
{
fprintf (stderr, "circular reference in cell %d %d\n", cell->r, cell->c);
return 0;
}
updating++;
for (k = 0; k < cell->familly->numchi; k++)
{
cell2 = cell->familly->childlist[k];
if (cell2->formula != NULL && cell2->tree != NULL)
{
int exist = 0;
int i;
execcelltree (cell2);
nupdate2 (cell2, redraw);
if (redraw)
for (i = 0; i < ntoredraw; i++)
{
if (toredraw[i] == cell2)
{
exist = 1;
i = ntoredraw;
}
}
if (!exist)
{
toredraw = (Cell **) absrealloc (toredraw, sizeof (Cell *) * (ntoredraw + 1), "nupdate2:toredraw ");
toredraw[ntoredraw] = cell2;
ntoredraw++;
}
}
}
updating--;
if (updating == 0 && ntoredraw > 0)
{
for (k = 0; k < ntoredraw; k++)
xdrawcell (toredraw[k]->r, toredraw[k]->c, 0);
absfree (toredraw, "nupdate2:toredraw ");
toredraw = NULL;
ntoredraw = 0;
}
return 0;
}
extern char *obj2string (obj o);
extern obj getidval3 (int i);
extern int findid (char *s);
char *
textparsing (buf)
char *buf;
{
Cell *cell;
Cell *activecell = ActiveCell;
if (parsingmacro)
{
sprintf (tmpbuf, "to update");
return tmpbuf;
}
cell = newcell (0, 1);
cell_setformula (cell, buf);
strcpy (tmpbuf, cell_gettext (cell));
cell_isnew (cell);
freecell (cell);
ActiveCell = activecell;
return tmpbuf;
}
Cell *
cell_cpy (cell1, cell2)
Cell *cell1;
Cell *cell2;
{
int len;
if (cell1 == NULL || cell2 == NULL)
return NULL;
if (cell2->val.type == DOUBLE)
{
cell1->val.rec.d = cell2->val.rec.d;
cell1->val.type = DOUBLE;
}
if (cell2->val.type == INTEGER)
{
cell1->val.rec.i = cell2->val.rec.i;
cell1->val.type = INTEGER;
}
if (cell2->formula != NULL)
{
len = strlen (cell2->formula);
if (len > 0)
{
cell1->formula = (char *) absmalloc (sizeof (char) * len, "cell_cpy:cell1->formula ");
if (cell1->formula == NULL)
fprintf (stderr, "cell1->formula not allocated!\n");
strcpy (cell1->formula, cell2->formula);
cell1->formula[len] = '\0';
}
}
cell1->type = cell2->type;
if (cell2->style != NULL)
{
if (cell1->style == NULL)
cell1->style = newstyle (STY_CELL);
style_cpy (cell1->style, cell2->style);
}
else
{
if (cell1->style != NULL)
{
freestyle (cell1->style);
cell1->style = NULL;
}
}
return cell1;
}
Cell *
cell_stycpy (cell1, cell2)
Cell *cell1;
Cell *cell2;
{
if (cell1 == NULL || cell2 == NULL)
return NULL;
if (cell2->style != NULL)
{
if (cell1->style == NULL)
cell1->style = newstyle (STY_CELL);
style_cpy (cell1->style, cell2->style);
}
else
{
if (cell1->style != NULL)
{
freestyle (cell1->style);
cell1->style = NULL;
}
}
return cell1;
}
int
cell_calculate (Cell * cell)
{
return nupdate2 (cell, 0);
}
int
cell_print (Cell * cell)
{
if (cell == NULL)
fprintf (stderr, "cell is NULL!\n");
else
fprintf (stderr, "cell %d %d formula %s\n", cell->r, cell->c, cell_getformula (cell));
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1