campo-sirio/include/msksheet.cpp
villa 3a6fa88f87 *** empty log message ***
git-svn-id: svn://10.65.10.50/trunk@20 c028cbd2-c16b-5b4b-a496-9718f37d4682
1994-08-17 09:32:34 +00:00

1074 lines
23 KiB
C++
Executable File

#include <msksheet.h>
#include <real.h>
#include <urldefid.h>
#include <utility.h>
const short FIRST_FIELD = 101;
#if XVT_OS == XVT_OS_WIN
#include <xil.h>
#include <colors.h>
///////////////////////////////////////////////////////////
// TSpreadsheet
// /////////////////////////////////////////////////////////
#define K_PLUS '+'
class TSpreadsheet:public TWindow
{
enum
{
ITF_CID = 0, LIST_CID = 1
};
TArray _str; // Array di TToken_strings
TBit_array _column_disabled;
TArray _disabled; // Array di TBit_array
TMask _mask;
int _columns;
bool _dirty;
XI_OBJ *_list;
SPREADSHEET_NOTIFY _notify;
static void xiev_handler (XI_OBJ * itf, XI_EVENT * xiev);
void init ();
protected:
void list_handler (XI_EVENT * xiev);
TMask_field *cell2field (const XI_OBJ * cell) const;
void update_rec (int rec);
void set_focus_cell (int riga, int colonna);
void mask2str (int n);
void str2mask (int n);
KEY edit (int n);
TMask_field *field (short id) const;
int rec2row (int rec);
int row2rec (int row);
bool notify (int r, KEY k);
public:
void update (int row);
TToken_string & row (int n);
TArray & rows_array () const
{
return (TArray &) _str;
}
int add (TToken_string &);
int insert (int rec);
bool destroy (int rec = -1);
void enable_column (int col, bool on = TRUE);
void enable_cell (int row, int column, bool on = TRUE);
bool cell_disabled (int row, int column) const;
TMask & mask ()
{
return _mask;
}
int items () const
{
return _str.items ();
}
int columns () const
{
return _columns;
}
bool dirty () const
{
return _dirty;
}
void set_notify (SPREADSHEET_NOTIFY n)
{
_notify = n;
}
void set_dirty (bool spork = TRUE)
{
_dirty = spork;
}
TSpreadsheet (short x, short y, short dx, short dy, const char *maskname, int maskno,
const char *head, WINDOW parent);
};
// Certified 99%
void TSpreadsheet ::init ()
{
static bool first = TRUE;
if (!first) return;
xvt_set_font (TASK_WIN, FF_FIXED, 0);
DRAW_CTOOLS ct;
win_get_draw_ctools (TASK_WIN, &ct);
xi_set_font (&ct.font);
xi_init ();
xi_set_pref (XI_PREF_3D_LOOK, TRUE);
// xi_set_pref(XI_PREF_COLOR_LIGHT, COLOR_CYAN);
// xi_set_pref(XI_PREF_COLOR_CTRL, MASK_BACK_COLOR);
// xi_set_pref(XI_PREF_COLOR_DARK, COLOR_GRAY);
first = FALSE;
}
TSpreadsheet ::TSpreadsheet (short x, short y, short dx, short dy,
const char *maskname, int maskno,
const char *head, WINDOW parent)
: _mask (maskname, NO_MODE, maskno), _notify (NULL)
{
const int NUMBER_WIDTH = 3;
const int MAX_COL = 32;
int width[MAX_COL];
init ();
// Calcolo larghezza massima tabella
TToken_string header (head);
TToken_string new_header (256);
int i = 0, tot_width = NUMBER_WIDTH + 1;
for (const char *h = header.get (); h; h = header.get (), i++)
{
CHECKD (i < MAX_COL, "Tu meni calumns in scit: ", i);
int w;
char *at = strchr (h, '@');
if (at)
{
w = atoi (at + 1);
*at = '\0';
}
else
w = strlen (h);
width[i] = w + 1;
const int cid = FIRST_FIELD + i; // Column & Field ID
const TMask_field * f = field (cid); // Field on mask
CHECKD (f, "The spreadsheet mask needs ALSO field ", cid);
if (f->has_query ())w += 2;
tot_width += w;
new_header.add (h);
}
_columns = i;
if (x < 0) x = 0;
if (y < 0) y = 0;
if (dx == 0)
{
dx = tot_width;
if (dx > 76) dx = -x;
}
RCT rct = resize_rect (x, y, dx, dy, WO_TE, parent);
rct.right -= 20;
rct.bottom -= 8;
XI_OBJ_DEF * itfdef = xi_create_itf_def (ITF_CID,
(XI_EVENT_HANDLER) xiev_handler, &rct, (char *) maskname,
PTR_LONG (this));
itfdef->v.itf->automatic_back_color = FALSE;
itfdef->v.itf->back_color = MASK_BACK_COLOR;
XI_OBJ_DEF * listdef = xi_add_list_def (itfdef, LIST_CID,
0, 0, rct.bottom - rct.top,
XI_ATR_ENABLED | XI_ATR_VISIBLE,
NORMAL_COLOR, NORMAL_BACK_COLOR,
NORMAL_COLOR, DISABLED_BACK_COLOR, NORMAL_COLOR,
LIST_CID);
listdef->v.list->scroll_bar = TRUE;
listdef->v.list->sizable_columns = TRUE;
listdef->v.list->movable_columns = TRUE;
listdef->v.list->scroll_bar_button = TRUE;
listdef->v.list->fixed_columns = 1;
listdef->v.list->width = rct.right - rct.left;
listdef->v.list->min_cell_height = CHARY;
listdef->v.list->min_heading_height = CHARY;
listdef->v.list->white_space_color = COLOR_GRAY;
XI_OBJ_DEF * coldef = xi_add_column_def (listdef, 0,
XI_ATR_RJUST, 0, NUMBER_WIDTH, NUMBER_WIDTH, "");
coldef->v.column->heading_platform = TRUE;
coldef->v.column->column_platform = TRUE;
coldef->v.column->center_heading = TRUE;
for (h = new_header.get (0), i = 0; h; h = new_header.get (), i++)
{
const int cid = FIRST_FIELD + i; // Column & Field ID
const TMask_field * f = field (cid); // Field on mask
const int w = width[i] + (f->has_query ()? 2 : 0); // Column
// width
long flags = XI_ATR_EDITMENU | XI_ATR_AUTOSCROLL;
if (f->class_id () == CLASS_REAL_FIELD) flags |= XI_ATR_RJUST;
if (f->active ())flags |= XI_ATR_ENABLED;
else
_column_disabled.set (i);
coldef = xi_add_column_def (listdef, cid,
flags, cid, w, width[i], (char *) h);
coldef->v.column->heading_platform = TRUE;
coldef->v.column->center_heading = TRUE;
}
RCT itfrct;
xi_get_def_rect (itfdef, &itfrct);
offset_rect (&itfrct, rct.left, rct.top);
itfrct.bottom++;
WINDOW win = create_window (W_NO_BORDER, &itfrct, "", 0, parent,
0, EM_ALL, (EVENT_HANDLER) xi_event, 0L);
CHECK (win, "Can't create a window for the spreadsheet");
set_win (win); // Set TWindow::_win
itfdef->v.itf->win = win;
xi_create (NULL, itfdef);
xi_tree_free (itfdef);
XI_OBJ * itf = xi_get_itf (win);
_list = xi_get_obj (itf, LIST_CID);
}
// Converts a row number in the correspondig record number
int TSpreadsheet ::row2rec (int row)
{
int rows;
const long *rec = xi_get_list_info (_list, &rows);
#ifdef DBG
if (row < 0 || row >= rows)
{
error_box ("Line %d is not visible", row);
return 0L;
}
#endif
return (int) rec[row];
}
// Converts a row number in the correspondig record number
int TSpreadsheet ::rec2row (int record)
{
int rows;
const long *rec = xi_get_list_info (_list, &rows);
int r = int (record - rec[0]);
if (r < 0 || r >= rows)
r = -1;
return r;
}
// Retrieves the corresponding field of the mask from a spredsheet cell
TMask_field * TSpreadsheet ::cell2field (const XI_OBJ * cell) const
{
const int pos = cell->v.cell.column;
int num;
XI_OBJ ** column = xi_get_member_list (_list, &num);
TMask_field * good = NULL;
for (short id = column[pos]->cid;; id += 100)
{
TMask_field * f = field (id);
if (f == NULL) break;
good = f;
if (f->active ())break;
}
return good;
}
void TSpreadsheet ::update_rec (int rec)
{
const int riga = rec2row (rec);
if (riga >= 0)
{
XI_OBJ row;
XI_MAKE_ROW (&row, _list, riga);
xi_cell_request (&row); // Update internal values
xi_set_row_height (&row, CHARY + 1); // Force row updating
}
}
void TSpreadsheet ::set_focus_cell (int riga, int colonna)
{
set_front_window (win ());
XI_OBJ cell;
XI_MAKE_CELL (&cell, _list, rec2row (riga), colonna);
xi_set_focus (&cell);
}
int TSpreadsheet ::insert (int rec)
{
const bool ok = notify (rec, K_INS);
if (!ok) return -1;
TToken_string s; // Empty row
const int r = _str.insert (s, rec);
_disabled.insert (NULL, rec);
xi_insert_row (_list, INT_MAX);
xi_cell_request (_list);
return r;
}
bool TSpreadsheet ::destroy (int rec)
{
bool ok = TRUE;
if (rec < 0)
{
_disabled.destroy ();
_str.destroy ();
}
else
{
_disabled.destroy (rec, TRUE); // Destroy enable info
ok = _str.destroy (rec, TRUE); // Destroy line
enable_cell (_str.items (), -1); // Enable last line
}
if (ok) xi_cell_request (_list);
return ok;
}
void TSpreadsheet ::update (int row)
{
if (row < 0)
{
xi_cell_request (_list);
xi_scroll (_list, XI_SCROLL_FIRST);
set_front_window (win ());
}
else
update_rec (row);
}
void TSpreadsheet ::xiev_handler (XI_OBJ * itf, XI_EVENT * xiev)
{
TSpreadsheet * es = (TSpreadsheet *) xi_get_app_data (itf);
CHECK (es, "NULL Edit sheet in xi event");
es->list_handler (xiev);
}
// Certified 75%
void TSpreadsheet ::list_handler (XI_EVENT * xiev)
{
static TMask_field * edit_field = NULL; // Current edit field
static int cur_row = 0, cur_col = 0; // Current cell
static bool row_dirty = FALSE; // Current row changed
static bool check_enabled = TRUE; // Perform OFF_ROW checks
switch (xiev->type)
{
case XIE_GET_FIRST:
{
const long max = items ();
if (max <= 0L)
{
xiev->refused = TRUE;
break;
}
long n = max * (long)xiev->v.rec_request.percent / 100L;
if (n < 0L) n = 0L;
xiev->v.rec_request.data_rec = n;
}
break;
case XIE_GET_LAST:
xiev->v.rec_request.data_rec = items () - 1;
break;
case XIE_GET_PREV:
case XIE_GET_NEXT:
{
const long n = xiev->v.rec_request.spec_rec +
(xiev->type == XIE_GET_NEXT ? +1 : -1);
if (n < 0 || n >= items ())
xiev->refused = TRUE;
else
xiev->v.rec_request.data_rec = n;
}
break;
case XIE_CELL_REQUEST:
{
const int rec = (int)xiev->v.cell_request.rec;
const char *src = NULL;
int nm;
XI_OBJ ** obj = xi_get_member_list (xiev->v.cell_request.list, &nm);
const int num = xiev->v.cell_request.col_nbr;
const int cid = obj[num]->cid;
if (cid >= FIRST_FIELD)
{
if (rec < items ())
{
const int col = cid - FIRST_FIELD;
TMask_field * f = field (cid);
src = row (rec).get (col); // Set value for cell
if (src && *src && f->class_id () == CLASS_REAL_FIELD)
{
src = f->picture_data (src, FALSE); // Get formatted string
}
if (field (cid)->has_query ())
{
xiev->v.cell_request.button =
xiev->v.cell_request.button_on_focus = TRUE;
}
if (cell_disabled (rec, col))
xiev->v.cell_request.back_color = MASK_BACK_COLOR;
}
}
else
src = format ("%d", rec + 1);
const int len = xiev->v.cell_request.len;
char *dst = xiev->v.cell_request.s;
if (src)
{
strncpy (dst, src, len);
if (isspace (*dst))
{
TFixed_string d (dst);
d.ltrim ();
}
}
else
*dst = '\0';
}
break;
case XIE_BUTTON:
if (xiev->v.xi_obj->type == XIT_CELL)
{
if (edit_field)
{
const char *val = xi_get_text (xiev->v.xi_obj, NULL, -1);
edit_field->set (val); // Update current cell
check_enabled = FALSE; // Disable checks
if (!row_dirty) notify (cur_row, K_SPACE);
if (edit_field->on_key (K_F9)) // Show search sheet
{
mask2str (cur_row); // Update row
row_dirty = TRUE;
}
check_enabled = TRUE; // Enable checks
xi_set_focus (xiev->v.xi_obj); // Restore focus to cell
}
}
else
if (xiev->v.xi_obj->type == XIT_LIST)
insert (-1);
break;
case XIE_DBL_CELL:
{
check_enabled = FALSE;
cur_row = row2rec (xiev->v.xi_obj->v.cell.row);
cur_col = xiev->v.xi_obj->v.cell.column;
const KEY k = edit (cur_row);
if (k == K_ENTER)
{
update_rec (cur_row);
row_dirty = TRUE;
}
xi_set_focus (xiev->v.xi_obj);
check_enabled = TRUE;
}
break;
case XIE_ON_ROW:
{
const int rec = row2rec (xiev->v.xi_obj->v.row);
if (rec < items ())
{
cur_row = rec;
str2mask (rec);
row_dirty = FALSE;
}
else
xiev->refused = TRUE;
}
break;
case XIE_OFF_ROW:
if (row_dirty && check_enabled)
{
check_enabled = FALSE; // Avoid recursion!
set_dirty ();
str2mask (cur_row); // It shouldn't have to be necessary
bool ok = _mask.check_fields ();
if (ok)
{
mask2str (cur_row);
ok = notify (cur_row, K_ENTER); // Notify edit
}
else
{
xiev->refused = TRUE;
set_dirty (2); // Set error status
set_focus_cell (cur_row, cur_col);
}
check_enabled = TRUE;
}
break;
case XIE_ON_CELL:
{
TMask_field * f = cell2field (xiev->v.xi_obj);
const int col = (f->dlg () - FIRST_FIELD) % 100;
if (!cell_disabled (cur_row, col))
{
edit_field = f;
cur_col = xiev->v.xi_obj->v.cell.column;
xi_set_color (xiev->v.xi_obj, XIC_BACK, FOCUS_BACK_COLOR);
}
else
{
xiev->refused = TRUE; // Refuse focus on disabled cells
}
}
break;
case XIE_OFF_CELL:
if (edit_field && check_enabled)
{
TMask_field * c = edit_field; // Save field, it could turn out to
// be NULL on error
const TString80 old (c->get ()); // Save old value on mask
const TString80 nuo (c->picture_data (xi_get_text (xiev->v.xi_obj, NULL, -1), TRUE));
if (old != nuo)
{
check_enabled = FALSE;
if (!row_dirty)
{
notify (cur_row, K_SPACE);
row_dirty = TRUE;
}
c->set (nuo); // Set new mask value
c->set_dirty (); // Get it dirty!
if (c->on_key (K_TAB) == FALSE) // Test it
{
c->set (old);
xi_set_focus (xiev->v.xi_obj);
}
else
{
mask2str (cur_row); // Update sheet row
edit_field = NULL; // Reset current field
}
check_enabled = TRUE;
}
xi_set_color (xiev->v.xi_obj, XIC_BACK, NORMAL_BACK_COLOR);
}
break;
case XIE_GET_PERCENT:
{
const long rec = xiev->v.get_percent.record;
long n = items (); if (n < 1) n = 1;
xiev->v.get_percent.percent = int (rec * 100L / n);
}
break;
case XIE_CLEANUP:
set_win (NULL_WIN);
break;
case XIE_XVT_EVENT:
{
EVENT * ep = &xiev->v.xvte;
switch (ep->type)
{
case E_FOCUS:
if (ep->v.active == FALSE)
{
XI_OBJ * itf = xi_get_itf (win ());
const bool ok = (bool) xi_move_focus (itf);
if (!ok)
xiev->refused = TRUE;
}
break;
case E_CHAR:
if (edit_field)
{
const KEY k = e_char_to_key (ep);
switch (k)
{
case K_F1:
check_enabled = FALSE; // Disable checks
edit_field->on_key (K_F1);
set_focus_cell (cur_row, cur_col);
check_enabled = TRUE; // Enable checks
// xiev->refused = TRUE;
break;
case K_F2:
case K_F3:
case K_F8:
case K_F9:
{
check_enabled = FALSE; // Disable checks
if (!row_dirty) notify (cur_row, K_SPACE);
if (edit_field->on_key (k))
{
mask2str (cur_row);
row_dirty = TRUE;
}
set_focus_cell (cur_row, cur_col);
check_enabled = TRUE; // Enable checks
}
break;
case K_PLUS:
insert (cur_row);
xiev->refused = TRUE;
break;
case K_PREV:
xi_scroll (_list, XI_SCROLL_PGUP);
// xiev->refused = TRUE;
break;
case K_NEXT:
xi_scroll (_list, XI_SCROLL_PGDOWN);
// xiev->refused = TRUE;
break;
case K_HOME:
xi_scroll (_list, XI_SCROLL_FIRST);
// xiev->refused = TRUE;
break;
case K_END:
xi_scroll (_list, XI_SCROLL_LAST);
// xiev->refused = TRUE;
break;
default:
break;
}
}
break;
default:
break;
}
}
break;
default:
break;
}
}
int TSpreadsheet ::add (TToken_string & t)
{
return _str.add (t);
}
TToken_string & TSpreadsheet ::row (int n)
{
return (TToken_string &) _str[n];
}
#else
#include <sheet.h>
///////////////////////////////////////////////////////////
// TSpreadsheet
// /////////////////////////////////////////////////////////
class TSpreadsheet:public TArray_sheet
{
TMask _mask;
SPREADSHEET_NOTIFY _notify;
bool _dirty;
TBit_array _column_disabled;
TArray _disabled; // Array di TBit_array
protected:
virtual bool on_key (KEY key);
KEY edit (int n);
bool notify (int r, KEY k);
TMask_field *field (short id) const;
void mask2str (int riga);
void str2mask (int riga);
public:
TSpreadsheet (short x, short y, short dx, short dy, const char *maskname, int maskno,
const char *head, WINDOW parent);
TArray & rows_array () const
{
return data ();
}
TMask & mask ()
{
return _mask;
}
void set_notify (SPREADSHEET_NOTIFY n)
{
_notify = n;
}
void set_dirty (bool spork = TRUE)
{_dirty = spork;
}
bool dirty ()const
{
return _dirty;
}
void enable_column (int col, bool on);
void enable_cell (int row, int column, bool on = TRUE);
bool cell_disabled (int row, int column) const;
};
TSpreadsheet ::TSpreadsheet (short x, short y, short dx, short dy,
const char *maskname, int maskno,
const char *head, WINDOW parent)
:TArray_sheet (x, y, dx, dy, maskname, head, 0, parent),
_mask (maskname, NO_MODE, maskno), _notify (NULL)
{
}
bool TSpreadsheet ::on_key (KEY k)
{
switch (k)
{
case K_SHIFT_ENTER:
case K_ESC:
mask ().send_key (k, 0);
return TRUE;
case K_ENTER: // Selezione riga per editing
if (items () < 1) k = K_INS; // Se vuoto crea riga da editare
case K_INS:
case 'A': // Aggiunge dopo
case 'I': // Aggiunge prima
{
int n = (int)selected ();
if (k != K_ENTER)
{
if (k == K_INS) n = items ();
else // Aggiunge alla fine
if (k == 'A') n++;
if (n < 0) n = 0;
else
if (n > items ())n = items (); // Controlla range n
if (notify (n, K_INS) == FALSE) // Chiede l'ok alla applicazione
return FALSE;
insert (TToken_string (80), n); // Aggiunge una riga vuota
k = K_INS; // Inserimento in corso
}
edit (n); // Edita riga selezionata o creata
set_front_window (win ()); // Aggiorna sheet a video
open ();
}
break;
case K_TAB:
case K_BTAB:
case K_SHIFT_TAB:
dispatch_e_char (get_parent (win ()), k);
return TRUE;
default:
break;
}
return TArray_sheet ::on_key (k);
}
#endif
TMask_field * TSpreadsheet ::field (short id) const
{
const int pos = _mask.id2pos (id);
if (pos < 0) return NULL;
return &_mask.fld (pos);
}
void TSpreadsheet ::mask2str (int riga)
{
TToken_string & r = row (riga);
r.cut (0);
for (short id = FIRST_FIELD;; id++)
{
const int pos = _mask.id2pos (id);
if (pos < 0) break;
r.add (_mask.fld (pos).get ());
}
#if XVT_OS == XVT_OS_WIN
update_rec (riga);
#endif
}
// Certified 50%
void TSpreadsheet ::enable_cell (int row, int column, bool on)
{
TBit_array * ba = (TBit_array *) _disabled.objptr (row);
if (ba == NULL)
{
if (on) return; // Don't waste time and memory
ba = new TBit_array (_column_disabled);
_disabled.add (ba, row);
}
if (column >= 0)
ba->set (column, !on);
else
{
if (on)
_disabled.destroy (row, FALSE); // Let's save some memory!
else
{
#if XVT_OS == XVT_OS_WIN
ba->set (_columns); // Force right array size
#else
ba->set (32); // Force array size
#endif
ba->set (); // Set all bits
}
}
}
void TSpreadsheet ::enable_column (int col, bool on)
{
_column_disabled.set (col, !on);
}
// Certified 99%
bool TSpreadsheet ::cell_disabled (int row, int column) const
{
TBit_array * ba = (TBit_array *) _disabled.objptr (row);
if (ba == NULL) return _column_disabled[column]; // Use default
return (*ba)[column];
}
// Certified 75%
void TSpreadsheet ::str2mask (int riga)
{
if (riga == items ())
{
_mask.reset ();
mask2str (riga);
return;
}
TToken_string & r = row (riga);
r.restart ();
TString80 val;
for (short id = FIRST_FIELD;; id++)
{
int pos = _mask.id2pos (id);
if (pos < 0) break;
val = r.get (); // Value to set
int rid = id;
while (pos >= 0)
{
TMask_field & f = _mask.fld (pos);
f.set (val);
f.enable (!cell_disabled (riga, id - FIRST_FIELD));
if (f.active () || f.ghost ())
{
if (f.has_check ())f.check (STARTING_CHECK);
f.on_hit ();
}
f.set_dirty (FALSE);
rid += 100;
pos = _mask.id2pos (rid);
}
}
_mask.set_caption (format ("Riga %d", riga + 1));
}
// Certified 100%
bool TSpreadsheet ::notify (int n, KEY k)
{
return _notify ? _notify (n, k) : TRUE;
}
// Certified 99%
KEY TSpreadsheet ::edit (int n)
{
str2mask (n);
notify (n, K_SPACE); // Notifica intenzione di modificare
const KEY k = _mask.run ();
if (k == K_ENTER)
{
mask2str (n);
}
else
if (k == K_DEL)
{
const bool ok = notify (n, K_DEL); // Notifica intenzione di cancellare
if (ok)
{
destroy (n);
str2mask (n);
}
}
return k;
}
///////////////////////////////////////////////////////////
// TSheet_field
// /////////////////////////////////////////////////////////
// Certified 100%
TSheet_field ::TSheet_field (TMask * m)
: TMask_field (m), _sheet (NULL)
{
}
// Certified 100%
word TSheet_field ::class_id ()const
{
return CLASS_SHEET_FIELD;
}
// Certified 100%
TSheet_field ::~TSheet_field ()
{
CHECK (_sheet, "Can't delete NULL sheet");
delete _sheet;
}
// Certified 100%
void TSheet_field ::reset ()
{
_sheet->destroy ();
}
void TSheet_field ::parse_head (TScanner & scanner)
{
_width = scanner.integer ();
_size = scanner.integer ();
if (_size == 0) _size = -1;
}
// Certified 100%
bool TSheet_field ::parse_item (TScanner & scanner)
{
if (scanner.key () == "IT")
{
_head.add (scanner.string ());
return TRUE;
}
return TMask_field ::parse_item (scanner);
}
// Certified 100%
void TSheet_field ::create (WINDOW parent)
{
const TMask & m = mask ();
_sheet = new TSpreadsheet (_x, _y, _width, _size, m.source_file (), m.sheets (),
_head, parent);
_win = _sheet->win ();
enable_window (_win, enabled ());
show_window (_win, showed ());
}
// Certified 100%
TArray & TSheet_field ::rows_array ()const
{
return _sheet->rows_array ();
}
// Certified 100%
// Ritorna l'indice della prima riga vuota dello sheet
int TSheet_field ::first_empty ()const
{
const int max = _sheet->items ();
for (int n = 0; n < max; n++)
if (_sheet->row (n).empty_items ())
break;
return n;
}
TToken_string & TSheet_field ::row (int n)
{
const int max = _sheet->items ();
if (n < 0 || n >= max)
{
if (n < 0) n = first_empty ();
if (n >= max) n = _sheet->add (TToken_string (80));
}
return _sheet->row (n);
}
void TSheet_field ::force_update (int r)
{
#if XVTWS == WMWS
_sheet->open ();
#else
_sheet->update (r);
#endif
}
void TSheet_field ::set_window_data (const char *)
{
_sheet->set_dirty (FALSE);
set_dirty (FALSE);
}
void TSheet_field ::set_field_data (const char *)
{
set_dirty (_sheet->dirty ());
}
int TSheet_field ::items ()const
{
return (int)_sheet->items ();
}
void TSheet_field ::set_notify (SPREADSHEET_NOTIFY n)
{
_sheet->set_notify (n);
}
void TSheet_field ::enable_column (int column, bool on)
{
_sheet->enable_column (column, on);
}
void TSheet_field ::enable_cell (int row, int column, bool on)
{
_sheet->enable_cell (row, column, on);
}
TMask & TSheet_field ::sheet_mask ()const
{
return _sheet->mask ();
}
bool TSheet_field ::on_key (KEY k)
{
if (k == K_TAB)
{
const bool spork = _sheet->dirty ();
if (spork < FALSE || spork > TRUE)
return error_box ("Tabella inconsistente: correggere i valori errati prima di uscirne");
set_dirty (spork);
}
return TMask_field ::on_key (k);
}