campo-sirio/include/msksheet.cpp
guy 5479720988 Modificata gestione focus negli sheet.
git-svn-id: svn://10.65.10.50/trunk@40 c028cbd2-c16b-5b4b-a496-9718f37d4682
1994-08-19 10:43:57 +00:00

1047 lines
24 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!
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
}
if (!ok)
{
xiev->refused = TRUE;
set_dirty(2); // Set error status
}
else
{
xvt_statbar_set("");
set_dirty();
}
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
/*
const int r = xiev->v.xi_obj->v.cell.row;
int c = xiev->v.xi_obj->v.cell.column;
c += cur_col > col ? -1 : +1;
if (c < 1) c = _columns-1; else
if (c >= _columns) c = 1;
XI_OBJ cell;
XI_MAKE_CELL(&cell, _list, r, c);
xi_move_focus(&cell);
*/
}
}
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);
xiev->refused = TRUE;
}
else
{
mask2str(cur_row); // Update sheet row
edit_field = NULL; // Reset current field
}
check_enabled = TRUE;
}
if (!xiev->refused)
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
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_PREV:
xi_scroll(_list, XI_SCROLL_PGUP);
break;
case K_NEXT:
xi_scroll(_list, XI_SCROLL_PGDOWN);
break;
case K_HOME:
xi_scroll(_list, XI_SCROLL_FIRST);
break;
case K_END:
xi_scroll(_list, XI_SCROLL_LAST);
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.set_dirty(FALSE);
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
}
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_hit()
{
if (!mask().is_running())
{
force_update();
_sheet->set_dirty(FALSE);
}
return TRUE;
}
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 le celle errate");
set_dirty(spork);
}
return TMask_field::on_key(k);
}