Commit 8ec8acb1 authored by Jody Goldberg's avatar Jody Goldberg Committed by Morten Welinder

(MW's hand-pathced version of Jody's changes.)


1999-08-01  Jody Goldberg  <jgoldberg@home.com>

	* src/fn-date.c (get_serial_date): Constify.  Improve handling of
 	date_serial 0.
	(gnumeric_networkdays): Add partial implementation.  (MW: turned
 	off.)

	* src/eval.c (add_value_deps): Handle empty value.

	* src/collect.c (callback_function_collect): Ignore empty values.

	* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet) : Support
	<C-PgUp> <C-PgDown> moving through the sheets.

	* src/Gnumeric.idl : Add VALUE_ERROR, VALUE_BOOLEAN, VALUE_EMPTY
	in a few more places.

	* src/corba-sheet.c : Ditto.

	* src/value.c (value_new_empty): New function.
	(value_dump, value_copy_to, value_get_as_bool,
 	value_get_as_string, value_get_as_int, value_get_as_float): Handle
 	empty value.
parent f99b2346
1999-08-01 Jody Goldberg <jgoldberg@home.com>
* src/fn-date.c (get_serial_date): Constify. Improve handling of
date_serial 0.
(gnumeric_networkdays): Add partial implementation. (MW: turned
off.)
* src/eval.c (add_value_deps): Handle empty value.
* src/collect.c (callback_function_collect): Ignore empty values.
* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet) : Support
<C-PgUp> <C-PgDown> moving through the sheets.
* src/Gnumeric.idl : Add VALUE_ERROR, VALUE_BOOLEAN, VALUE_EMPTY
in a few more places.
* src/corba-sheet.c : Ditto.
* src/value.c (value_new_empty): New function.
(value_dump, value_copy_to, value_get_as_bool,
value_get_as_string, value_get_as_int, value_get_as_float): Handle
empty value.
1999-08-01 Morten Welinder <terra@diku.dk>
* src/expr-name.c (expr_name_add): Fix bogus check.
......
1999-08-01 Jody Goldberg <jgoldberg@home.com>
* src/fn-date.c (get_serial_date): Constify. Improve handling of
date_serial 0.
(gnumeric_networkdays): Add partial implementation. (MW: turned
off.)
* src/eval.c (add_value_deps): Handle empty value.
* src/collect.c (callback_function_collect): Ignore empty values.
* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet) : Support
<C-PgUp> <C-PgDown> moving through the sheets.
* src/Gnumeric.idl : Add VALUE_ERROR, VALUE_BOOLEAN, VALUE_EMPTY
in a few more places.
* src/corba-sheet.c : Ditto.
* src/value.c (value_new_empty): New function.
(value_dump, value_copy_to, value_get_as_bool,
value_get_as_string, value_get_as_int, value_get_as_float): Handle
empty value.
1999-08-01 Morten Welinder <terra@diku.dk>
* src/expr-name.c (expr_name_add): Fix bogus check.
......
......@@ -15,7 +15,7 @@
#define DAY_SECONDS (3600*24)
static float_t
get_serial_date (Value *v)
get_serial_date (const Value *v)
{
float_t serial;
......@@ -33,6 +33,12 @@ get_serial_date (Value *v)
return floor (serial);
}
static GDate *
get_date (const Value *v)
{
float_t serial = get_serial_date (v);
return (serial > 0.0) ? g_date_new_serial (serial) : NULL;
}
static float_t
get_serial_time (Value *v)
......@@ -372,10 +378,12 @@ static char *help_year = {
static Value *
gnumeric_year (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1900;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_year (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -397,10 +405,12 @@ static char *help_month = {
static Value *
gnumeric_month (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_month (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -422,10 +432,12 @@ static char *help_day = {
static Value *
gnumeric_day (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_day (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -447,10 +459,12 @@ static char *help_weekday = {
static Value *
gnumeric_weekday (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = (g_date_weekday (date) + 1) % 7;
g_date_free (date);
}
return value_new_int (res);
}
......@@ -568,9 +582,9 @@ gnumeric_eomonth (FunctionEvalInfo *ei, Value **argv)
{
Value *res;
int months = 0;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
GDate *date = get_date (argv[0]);
if (!g_date_valid(date))
if (date == NULL || !g_date_valid(date))
return value_new_error (&ei->pos, gnumeric_err_VALUE);
if (argv[1] != NULL)
......@@ -612,9 +626,9 @@ gnumeric_workday (FunctionEvalInfo *ei, Value **argv)
Value *res;
int days;
GDateWeekday weekday;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
GDate *date = get_date (argv[0]);
if (!g_date_valid(date))
if (date == NULL || !g_date_valid(date))
return value_new_error (&ei->pos, gnumeric_err_VALUE);
weekday = g_date_weekday(date);
......@@ -652,6 +666,66 @@ gnumeric_workday (FunctionEvalInfo *ei, Value **argv)
/***************************************************************************/
static char * help_networkdays = {
N_("@FUNCTION=NETWORKDAYS\n"
"@SYNTAX=NETWORKDAYS (start_date,end_date,holidays)\n"
"@DESCRIPTION="
"Returns the number of non-weekend non-holidays between @start_date "
"and @end_date. Holidays optionaly supplied in @holidays."
"\n"
"Returns #NUM if start_date or end_date are invalid"
"\n"
""
"@SEEALSO=WORKDAY")
};
/* A utility routine to return the 1st weekend >= the serial if its valid */
static int
get_serial_weekday (Value const * v)
{
GDate * date;
int serial = get_serial_date (v);
if (serial <= 0)
return serial;
date = g_date_new_serial (serial);
if (g_date_valid(date)) {
GDateWeekday weekday = g_date_weekday(date);
if (weekday == G_DATE_SATURDAY)
serial += 2;
else if (weekday == G_DATE_SUNDAY)
serial += 1;
}
g_date_free (date);
return serial;
}
static Value *
gnumeric_networkdays (FunctionEvalInfo *ei, Value **argv)
{
int start_serial = get_serial_weekday (argv[0]);
int end_serial = get_serial_weekday (argv[1]);
int res, mult = 1;
if (start_serial < 0 || end_serial < 0)
return value_new_error (&ei->pos, gnumeric_err_NUM);
return value_new_error (&ei->pos, "We're working on it");
res = end_serial - start_serial;
if (res < 0) {
res = -res;
mult = -1;
}
/* FIXME : Remove weekends */
res -= ((res/7)*2);
return value_new_int (res*mult);
}
/***************************************************************************/
void
date_functions_init(void)
{
......@@ -675,6 +749,8 @@ date_functions_init(void)
gnumeric_minute );
function_add_args (cat, "month", "?", "date", &help_month,
gnumeric_month);
function_add_args (cat, "networkdays", "??|?", "start_date,end_date,holidays",
&help_networkdays, &gnumeric_networkdays );
function_add_args (cat, "now", "", "", &help_now,
gnumeric_now );
function_add_args (cat, "second", "?", "time", &help_second,
......@@ -687,7 +763,7 @@ date_functions_init(void)
gnumeric_today );
function_add_args (cat, "weekday", "?", "date", &help_weekday,
gnumeric_weekday);
function_add_args (cat, "workday", "?f|A", "date,days,holidays",
function_add_args (cat, "workday", "?f|?", "date,days,holidays",
&help_workday, &gnumeric_workday);
function_add_args (cat, "year", "?", "date", &help_year,
gnumeric_year);
......
......@@ -13,11 +13,16 @@ module GNOME {
const short VALUE_FLOAT = 2;
const short VALUE_CELLRANGE = 3;
const short VALUE_ARRAY = 4;
const short VALUE_BOOLEAN = 5;
const short VALUE_ERROR = 6;
const short VALUE_EMPTY = 7;
union Value switch(short) {
case VALUE_BOOLEAN: boolean v_bool;
case VALUE_FLOAT: double v_float;
case VALUE_INTEGER: long v_int;
case VALUE_STRING: string str;
case VALUE_ERROR: string error;
case VALUE_ARRAY: string array;
case VALUE_CELLRANGE: CellRange cell_range;
};
......
......@@ -24,6 +24,9 @@ callback_function_collect (const EvalPosition *ep, Value *value, void *closure)
collect_floats_t *cl = (collect_floats_t *)closure;
switch (value->type) {
case VALUE_EMPTY:
return NULL;
case VALUE_BOOLEAN:
if (cl->flags & COLLECT_IGNORE_BOOLS)
return NULL;
......
......@@ -264,6 +264,18 @@ Sheet_cell_set_value (PortableServer_Servant servant,
cell = sheet_cell_fetch (sheet, col, row);
switch (value->_d){
case GNOME_Gnumeric_VALUE_EMPTY:
v = value_new_empty ();
break;
case GNOME_Gnumeric_VALUE_BOOLEAN:
v = value_new_bool (value->_u.v_bool);
break;
case GNOME_Gnumeric_VALUE_ERROR:
v = value_new_error (NULL, value->_u.error);
break;
case GNOME_Gnumeric_VALUE_STRING:
v = value_new_string (value->_u.str);
break;
......@@ -315,6 +327,20 @@ fill_corba_value (GNOME_Gnumeric_Value *value, Sheet *sheet, CORBA_long col, COR
cell = sheet_cell_get (sheet, col, row);
if (cell && cell->value){
switch (cell->value->type){
case VALUE_EMPTY:
value->_d = GNOME_Gnumeric_VALUE_EMPTY;
break;
case VALUE_BOOLEAN:
value->_d = GNOME_Gnumeric_VALUE_BOOLEAN;
value->_u.v_bool = cell->value->v.v_bool;
break;
case VALUE_ERROR:
value->_d = GNOME_Gnumeric_VALUE_ERROR;
value->_u.error = CORBA_string_dup (cell->value->v.error.msg.str->str);
break;
case VALUE_STRING:
value->_d = GNOME_Gnumeric_VALUE_STRING;
value->_u.str = CORBA_string_dup (cell->value->v.str->str);
......
......@@ -171,6 +171,7 @@ static void
add_value_deps (Cell *cell, const Value *value)
{
switch (value->type){
case VALUE_EMPTY:
case VALUE_STRING:
case VALUE_INTEGER:
case VALUE_FLOAT:
......
......@@ -171,6 +171,7 @@ static void
add_value_deps (Cell *cell, const Value *value)
{
switch (value->type){
case VALUE_EMPTY:
case VALUE_STRING:
case VALUE_INTEGER:
case VALUE_FLOAT:
......
......@@ -15,7 +15,7 @@
#define DAY_SECONDS (3600*24)
static float_t
get_serial_date (Value *v)
get_serial_date (const Value *v)
{
float_t serial;
......@@ -33,6 +33,12 @@ get_serial_date (Value *v)
return floor (serial);
}
static GDate *
get_date (const Value *v)
{
float_t serial = get_serial_date (v);
return (serial > 0.0) ? g_date_new_serial (serial) : NULL;
}
static float_t
get_serial_time (Value *v)
......@@ -372,10 +378,12 @@ static char *help_year = {
static Value *
gnumeric_year (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1900;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_year (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -397,10 +405,12 @@ static char *help_month = {
static Value *
gnumeric_month (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_month (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -422,10 +432,12 @@ static char *help_day = {
static Value *
gnumeric_day (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_day (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -447,10 +459,12 @@ static char *help_weekday = {
static Value *
gnumeric_weekday (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = (g_date_weekday (date) + 1) % 7;
g_date_free (date);
}
return value_new_int (res);
}
......@@ -568,9 +582,9 @@ gnumeric_eomonth (FunctionEvalInfo *ei, Value **argv)
{
Value *res;
int months = 0;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
GDate *date = get_date (argv[0]);
if (!g_date_valid(date))
if (date == NULL || !g_date_valid(date))
return value_new_error (&ei->pos, gnumeric_err_VALUE);
if (argv[1] != NULL)
......@@ -612,9 +626,9 @@ gnumeric_workday (FunctionEvalInfo *ei, Value **argv)
Value *res;
int days;
GDateWeekday weekday;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
GDate *date = get_date (argv[0]);
if (!g_date_valid(date))
if (date == NULL || !g_date_valid(date))
return value_new_error (&ei->pos, gnumeric_err_VALUE);
weekday = g_date_weekday(date);
......@@ -652,6 +666,66 @@ gnumeric_workday (FunctionEvalInfo *ei, Value **argv)
/***************************************************************************/
static char * help_networkdays = {
N_("@FUNCTION=NETWORKDAYS\n"
"@SYNTAX=NETWORKDAYS (start_date,end_date,holidays)\n"
"@DESCRIPTION="
"Returns the number of non-weekend non-holidays between @start_date "
"and @end_date. Holidays optionaly supplied in @holidays."
"\n"
"Returns #NUM if start_date or end_date are invalid"
"\n"
""
"@SEEALSO=WORKDAY")
};
/* A utility routine to return the 1st weekend >= the serial if its valid */
static int
get_serial_weekday (Value const * v)
{
GDate * date;
int serial = get_serial_date (v);
if (serial <= 0)
return serial;
date = g_date_new_serial (serial);
if (g_date_valid(date)) {
GDateWeekday weekday = g_date_weekday(date);
if (weekday == G_DATE_SATURDAY)
serial += 2;
else if (weekday == G_DATE_SUNDAY)
serial += 1;
}
g_date_free (date);
return serial;
}
static Value *
gnumeric_networkdays (FunctionEvalInfo *ei, Value **argv)
{
int start_serial = get_serial_weekday (argv[0]);
int end_serial = get_serial_weekday (argv[1]);
int res, mult = 1;
if (start_serial < 0 || end_serial < 0)
return value_new_error (&ei->pos, gnumeric_err_NUM);
return value_new_error (&ei->pos, "We're working on it");
res = end_serial - start_serial;
if (res < 0) {
res = -res;
mult = -1;
}
/* FIXME : Remove weekends */
res -= ((res/7)*2);
return value_new_int (res*mult);
}
/***************************************************************************/
void
date_functions_init(void)
{
......@@ -675,6 +749,8 @@ date_functions_init(void)
gnumeric_minute );
function_add_args (cat, "month", "?", "date", &help_month,
gnumeric_month);
function_add_args (cat, "networkdays", "??|?", "start_date,end_date,holidays",
&help_networkdays, &gnumeric_networkdays );
function_add_args (cat, "now", "", "", &help_now,
gnumeric_now );
function_add_args (cat, "second", "?", "time", &help_second,
......@@ -687,7 +763,7 @@ date_functions_init(void)
gnumeric_today );
function_add_args (cat, "weekday", "?", "date", &help_weekday,
gnumeric_weekday);
function_add_args (cat, "workday", "?f|A", "date,days,holidays",
function_add_args (cat, "workday", "?f|?", "date,days,holidays",
&help_workday, &gnumeric_workday);
function_add_args (cat, "year", "?", "date", &help_year,
gnumeric_year);
......
......@@ -15,7 +15,7 @@
#define DAY_SECONDS (3600*24)
static float_t
get_serial_date (Value *v)
get_serial_date (const Value *v)
{
float_t serial;
......@@ -33,6 +33,12 @@ get_serial_date (Value *v)
return floor (serial);
}
static GDate *
get_date (const Value *v)
{
float_t serial = get_serial_date (v);
return (serial > 0.0) ? g_date_new_serial (serial) : NULL;
}
static float_t
get_serial_time (Value *v)
......@@ -372,10 +378,12 @@ static char *help_year = {
static Value *
gnumeric_year (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1900;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_year (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -397,10 +405,12 @@ static char *help_month = {
static Value *
gnumeric_month (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_month (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -422,10 +432,12 @@ static char *help_day = {
static Value *
gnumeric_day (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_day (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -447,10 +459,12 @@ static char *help_weekday = {
static Value *
gnumeric_weekday (FunctionEvalInfo *ei, Value **argv)
{
int res;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = (g_date_weekday (date) + 1) % 7;
g_date_free (date);
}
return value_new_int (res);
}
......@@ -568,9 +582,9 @@ gnumeric_eomonth (FunctionEvalInfo *ei, Value **argv)
{
Value *res;
int months = 0;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
GDate *date = get_date (argv[0]);
if (!g_date_valid(date))
if (date == NULL || !g_date_valid(date))
return value_new_error (&ei->pos, gnumeric_err_VALUE);
if (argv[1] != NULL)
......@@ -612,9 +626,9 @@ gnumeric_workday (FunctionEvalInfo *ei, Value **argv)
Value *res;
int days;
GDateWeekday weekday;
GDate *date = g_date_new_serial (get_serial_date (argv[0]));
GDate *date = get_date (argv[0]);
if (!g_date_valid(date))
if (date == NULL || !g_date_valid(date))
return value_new_error (&ei->pos, gnumeric_err_VALUE);
weekday = g_date_weekday(date);
......@@ -652,6 +666,66 @@ gnumeric_workday (FunctionEvalInfo *ei, Value **argv)
/***************************************************************************/
static char * help_networkdays = {
N_("@FUNCTION=NETWORKDAYS\n"
"@SYNTAX=NETWORKDAYS (start_date,end_date,holidays)\n"
"@DESCRIPTION="
"Returns the number of non-weekend non-holidays between @start_date "
"and @end_date. Holidays optionaly supplied in @holidays."
"\n"
"Returns #NUM if start_date or end_date are invalid"
"\n"
""
"@SEEALSO=WORKDAY")
};
/* A utility routine to return the 1st weekend >= the serial if its valid */
static int
get_serial_weekday (Value const * v)
{
GDate * date;
int serial = get_serial_date (v);
if (serial <= 0)
return serial;
date = g_date_new_serial (serial);
if (g_date_valid(date)) {
GDateWeekday weekday = g_date_weekday(date);
if (weekday == G_DATE_SATURDAY)
serial += 2;
else if (weekday == G_DATE_SUNDAY)
serial += 1;
}
g_date_free (date);
return serial;
}
static Value *
gnumeric_networkdays (FunctionEvalInfo *ei, Value **argv)
{
int start_serial = get_serial_weekday (argv[0]);
int end_serial = get_serial_weekday (argv[1]);
int res, mult = 1;
if (start_serial < 0 || end_serial < 0)
return value_new_error (&ei->pos, gnumeric_err_NUM);
return value_new_error (&ei->pos, "We're working on it");
res = end_serial - start_serial;
if (res < 0) {
res = -res;
mult = -1;
}
/* FIXME : Remove weekends */
res -= ((res/7)*2);
return value_new_int (res*mult);
}
/***************************************************************************/
void
date_functions_init(void)
{
......@@ -675,6 +749,8 @@ date_functions_init(void)
gnumeric_minute );
function_add_args (cat, "month", "?", "date", &help_month,
gnumeric_month);
function_add_args (cat, "networkdays", "??|?", "start_date,end_date,holidays",
&help_networkdays, &gnumeric_networkdays );
function_add_args (cat, "now", "", "", &help_now,
gnumeric_now );
function_add_args (cat, "second", "?", "time", &help_second,
......@@ -687,7 +763,7 @@ date_functions_init(void)
gnumeric_today );
function_add_args (cat, "weekday", "?", "date", &help_weekday,
gnumeric_weekday);
function_add_args (cat, "workday", "?f|A", "date,days,holidays",
function_add_args (cat, "workday", "?f|?", "date,days,holidays",
&help_workday, &gnumeric_workday);
function_add_args (cat, "year", "?", "date", &help_year,
gnumeric_year);
......
......@@ -713,12 +713,18 @@ gnumeric_sheet_key_mode_sheet (GnumericSheet *gsheet, GdkEventKey *event)
case GDK_KP_Page_Up:
case GDK_Page_Up:
(*movefn_vertical)(gsheet, -(gsheet->last_visible_row-gsheet->top_row));
if ((event->state & GDK_CONTROL_MASK) != 0)
gtk_notebook_prev_page (GTK_NOTEBOOK (wb->notebook));
else
(*movefn_vertical)(gsheet, -(gsheet->last_visible_row-gsheet->top_row));
break;
case GDK_KP_Page_Down:
case GDK_Page_Down:
(*movefn_vertical)(gsheet, gsheet->last_visible_row-gsheet->top_row);
if ((event->state & GDK_CONTROL_MASK) != 0)
gtk_notebook_next_page (GTK_NOTEBOOK (wb->notebook));
else
(*movefn_vertical)(gsheet, gsheet->last_visible_row-gsheet->top_row);
break;
case GDK_KP_Home:
......
......@@ -713,12 +713,18 @@ gnumeric_sheet_key_mode_sheet (GnumericSheet *gsheet, GdkEventKey *event)
case GDK_KP_Page_Up:
case GDK_Page_Up:
(*movefn_vertical)(gsheet, -(gsheet->last_visible_row-gsheet->top_row));
if ((event->state & GDK_CONTROL_MASK) != 0)
gtk_notebook_prev_page (GTK_NOTEBOOK (wb->notebook));
else
(*movefn_vertical)(gsheet, -(gsheet->last_visible_row-gsheet->top_row));
break;
case GDK_KP_Page_Down:
case GDK_Page_Down:
(*movefn_vertical)(gsheet, gsheet->last_visible_row-gsheet->top_row);
if ((event->state & GDK_CONTROL_MASK) != 0)
gtk_notebook_next_page (GTK_NOTEBOOK (wb->notebook));
else
(*movefn_vertical)(gsheet, gsheet->last_visible_row-gsheet->top_row);
break;