330 lines
6.6 KiB
C++
330 lines
6.6 KiB
C++
|
// Includo stdio senno' dice che ridefinisco FILE
|
||
|
#include <stdio.h>
|
||
|
|
||
|
|
||
|
#include <files.h>
|
||
|
#include <utility.h>
|
||
|
#include <expr.h>
|
||
|
#include <isam.h>
|
||
|
#include <mask.h>
|
||
|
#include <sheet.h>
|
||
|
#include <msksheet.h>
|
||
|
#include <urldefid.h>
|
||
|
#include <validate.h>
|
||
|
|
||
|
#include "ba1100.h"
|
||
|
#define INVFLD 255
|
||
|
|
||
|
TMask* TRec_sheet::_mask = NULL;
|
||
|
HIDDEN TToken_string s(256);
|
||
|
|
||
|
|
||
|
void TDir_sheet::add ()
|
||
|
|
||
|
{
|
||
|
_dir->get(LF_DIR, _lock, _nordir, _sysdirop);
|
||
|
const int nitems = _dir->eod() + 1;
|
||
|
|
||
|
_dir->eod() = nitems;
|
||
|
_dir->put(LF_DIR);
|
||
|
_dir->zero();
|
||
|
_dir->put(nitems);
|
||
|
_items = nitems;
|
||
|
|
||
|
// select(nitems - 1);
|
||
|
}
|
||
|
|
||
|
TDir_sheet::TDir_sheet(const char* title)
|
||
|
: TSheet(-1,-1, 0, 0, title,"N.@5|Nome@20|EOD@7|EOX@7|Lung. |Descrizione@43|Formula@33|Flags@7", 0xC)
|
||
|
{
|
||
|
_dir = new TDir;
|
||
|
_rec = new TTrec;
|
||
|
rebuild();
|
||
|
}
|
||
|
|
||
|
TDir_sheet::~TDir_sheet()
|
||
|
{
|
||
|
delete _dir;
|
||
|
delete _rec;
|
||
|
}
|
||
|
|
||
|
void TDir_sheet::page_build(long first, byte rows)
|
||
|
|
||
|
{
|
||
|
TToken_string l(128);
|
||
|
|
||
|
for (byte i = 0; i < rows; i++)
|
||
|
{
|
||
|
const int n = int(i+first+1);
|
||
|
_dir->get (n,_nolock,_nordir,_sysdirop);
|
||
|
|
||
|
l = format("%3d", n); // Numero progressivo del file
|
||
|
l.add(_dir->name());
|
||
|
const TRecnotype eod = _dir->eod();
|
||
|
l.add(format("%ld", eod));
|
||
|
const TRecnotype eox = _dir->eox();
|
||
|
l.add(format("%ld", eox));
|
||
|
const word len = _dir->len();
|
||
|
l.add(format("%u", len));
|
||
|
l.add(_dir->des());
|
||
|
l.add(_dir->expr());
|
||
|
l.add(format("%ld", _dir->flags()));
|
||
|
set_row(l, i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
TRec_sheet::TRec_sheet(int logicnum)
|
||
|
|
||
|
{
|
||
|
_dir = new TDir;
|
||
|
_rec = new TTrec;
|
||
|
_rec_old = new TTrec;
|
||
|
_mask = new TMask("ba1100d");
|
||
|
|
||
|
_dir->get(logicnum, _lock, _nordir, _sysdirop);
|
||
|
_rec->get(logicnum);
|
||
|
*_rec_old = *_rec;
|
||
|
}
|
||
|
|
||
|
TRec_sheet::~TRec_sheet()
|
||
|
{
|
||
|
delete _dir;
|
||
|
delete _rec;
|
||
|
delete _rec_old;
|
||
|
delete _mask;
|
||
|
_mask = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void TRec_sheet::update_keys(int from, int shift)
|
||
|
|
||
|
{
|
||
|
RecDes *rdes = _rec->rec();
|
||
|
|
||
|
for (int i = 0 ; i < rdes->NKeys; i++)
|
||
|
for (int j = 0 ; j < rdes->Ky[i].NkFields; j++)
|
||
|
{
|
||
|
const int nfld = rdes->Ky[i].FieldSeq[j] - (rdes->Ky[i].FieldSeq[j] > MaxFields ? MaxFields : 0);
|
||
|
|
||
|
if (nfld > from) rdes->Ky[i].FieldSeq[j] += shift;
|
||
|
else
|
||
|
if (nfld == from)
|
||
|
{
|
||
|
if (shift < 0)
|
||
|
{
|
||
|
rdes->Ky[i].NkFields--;
|
||
|
for (int k = rdes->Ky[i].NkFields; k > j; k--)
|
||
|
rdes->Ky[i].FieldSeq[j] = rdes->Ky[i].FieldSeq[j + 1];
|
||
|
}
|
||
|
else
|
||
|
if (nfld >= from) rdes->Ky[i].FieldSeq[j] += shift;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const char* TRec_sheet::build_key_expr(int key)
|
||
|
|
||
|
{
|
||
|
RecDes *rdes = _rec->rec();
|
||
|
|
||
|
s = "";
|
||
|
for (int j = 0 ; j < rdes->Ky[key].NkFields; j++)
|
||
|
{
|
||
|
const bool upper = rdes->Ky[key].FieldSeq[j] > MaxFields;
|
||
|
const int nfld = rdes->Ky[key].FieldSeq[j] - (upper ? MaxFields : 0);
|
||
|
if (j) s << "+";
|
||
|
if (upper) s << "UPPER(";
|
||
|
s << rdes->Fd[nfld].Name;
|
||
|
if (rdes->Ky[key].FromCh[j] < INVFLD)
|
||
|
s << format("[%d,%d]", rdes->Ky[key].FromCh[j] + 1,
|
||
|
rdes->Ky[key].ToCh[j] + 1);
|
||
|
else
|
||
|
if (upper) s << ")";
|
||
|
}
|
||
|
s.add(rdes->Ky[key].DupKeys ? "X" : " ");
|
||
|
return (const char*) s;
|
||
|
}
|
||
|
|
||
|
bool TRec_sheet::check_key_expr(int key, const char * key_expr)
|
||
|
|
||
|
{
|
||
|
TExpression expr("", _strexpr);
|
||
|
return expr.set(key_expr, _strexpr);
|
||
|
}
|
||
|
|
||
|
void TRec_sheet::update_key_expr(int key, TToken_string& s)
|
||
|
|
||
|
{
|
||
|
RecDes *rdes = _rec->rec();
|
||
|
|
||
|
TExpression expr("", _strexpr);
|
||
|
TString ke(s.get());
|
||
|
|
||
|
if (expr.set((const char*) ke, _strexpr))
|
||
|
{
|
||
|
rdes->Ky[key].DupKeys = (*s.get() != ' ');
|
||
|
TCodearray& c = expr.code();
|
||
|
c.begin();
|
||
|
int n = 0;
|
||
|
while (!c.end())
|
||
|
{
|
||
|
TCode& inst = c.step();
|
||
|
TCodesym sym = inst.getsym();
|
||
|
|
||
|
if (sym == _variable)
|
||
|
{
|
||
|
const char* s = inst.string();
|
||
|
|
||
|
for (int i = 0; i <rdes->NFields; i++)
|
||
|
if (strcmp(rdes->Fd[i].Name, s) == 0) break;
|
||
|
|
||
|
rdes->Ky[key].FieldSeq[n] = i;
|
||
|
rdes->Ky[key].FromCh[n] = INVFLD;
|
||
|
rdes->Ky[key].FromCh[n] = INVFLD;
|
||
|
inst = c.step();
|
||
|
sym = inst.getsym();
|
||
|
if (sym == _upper)
|
||
|
rdes->Ky[key].FieldSeq[n] += MaxFields;
|
||
|
else
|
||
|
if (sym == _number)
|
||
|
{
|
||
|
rdes->Ky[key].FromCh[n] = inst.number().integer() - 1;
|
||
|
inst = c.step();
|
||
|
rdes->Ky[key].ToCh[n] = inst.number().integer() - 1;
|
||
|
inst = c.step();
|
||
|
}
|
||
|
else c.backtrace();
|
||
|
n++;
|
||
|
}
|
||
|
}
|
||
|
rdes->Ky[key].NkFields = n;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const char* TRec_sheet::build_field(int nfld)
|
||
|
|
||
|
{
|
||
|
RecDes *rdes = _rec->rec();
|
||
|
|
||
|
// s.format("%d", nfld+1);
|
||
|
s = "";
|
||
|
s.add((const char*)rdes->Fd[nfld].Name);
|
||
|
s.add(format("%d", rdes->Fd[nfld].TypeF));
|
||
|
s.add(format("%d", rdes->Fd[nfld].Len));
|
||
|
s.add(format("%d", rdes->Fd[nfld].Dec));
|
||
|
return (const char*) s;
|
||
|
}
|
||
|
|
||
|
void TRec_sheet::update_field(int nfld, TToken_string& s)
|
||
|
|
||
|
{
|
||
|
RecDes *rdes = _rec->rec();
|
||
|
|
||
|
// s.get();
|
||
|
strcpy(rdes->Fd[nfld].Name, s.get());
|
||
|
rdes->Fd[nfld].TypeF = atoi(s.get());
|
||
|
rdes->Fd[nfld].Len = atoi(s.get());
|
||
|
rdes->Fd[nfld].Dec = atoi(s.get());
|
||
|
}
|
||
|
|
||
|
HIDDEN bool len_handler(TMask_field& f, KEY key)
|
||
|
|
||
|
{
|
||
|
const int len = atoi(f.get());
|
||
|
|
||
|
if (len < 0) return FALSE;
|
||
|
|
||
|
const int typef = atoi(f.mask().get(FLD_TIPO));
|
||
|
|
||
|
switch (typef)
|
||
|
{
|
||
|
case _alfafld: return len <= INVFLD;
|
||
|
case _intfld: return len <= 5;
|
||
|
case _longfld: return len <= 10;
|
||
|
case _realfld: return len <= 18;
|
||
|
case _wordfld: return len <= 5;
|
||
|
case _intzerofld: return len <= 5;
|
||
|
case _longzerofld: return len <= 10;
|
||
|
default: return TRUE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
bool TRec_sheet::fld_notify(int r, KEY k)
|
||
|
|
||
|
{
|
||
|
const TSheet_field& f = (const TSheet_field&) _mask->field(F_FIELDS);
|
||
|
|
||
|
if (k == K_SPACE)
|
||
|
{
|
||
|
TMask& m = f.sheet_mask();
|
||
|
|
||
|
m.set(F_NUMF, r + 1);
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
bool TRec_sheet::key_notify(int r, KEY k)
|
||
|
|
||
|
{
|
||
|
const TSheet_field& f = (const TSheet_field&) _mask->field(F_KEYS);
|
||
|
|
||
|
if (k == K_SPACE)
|
||
|
{
|
||
|
TMask& m = f.sheet_mask();
|
||
|
|
||
|
m.enable(F_KDUP, r > 0);
|
||
|
if (r == 0) m.reset(F_KDUP);
|
||
|
}
|
||
|
else
|
||
|
if (k == K_INS && f.items() >= 8) return FALSE;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void TRec_sheet::save()
|
||
|
|
||
|
{
|
||
|
if (*_rec == *_rec_old ||
|
||
|
!yesnocancel_box("Devo salvare le modifiche")) return;
|
||
|
TSystemisamfile f(_rec->num());
|
||
|
|
||
|
f.update(*_rec);
|
||
|
*_rec_old = *_rec;
|
||
|
}
|
||
|
|
||
|
|
||
|
void TRec_sheet::edit()
|
||
|
|
||
|
{
|
||
|
TSheet_field& f1 = (TSheet_field&) _mask->field(F_FIELDS);
|
||
|
TSheet_field& f2 = (TSheet_field&) _mask->field(F_KEYS);
|
||
|
RecDes *rdes = _rec->rec();
|
||
|
|
||
|
_mask->set (F_NUM, _dir->num());
|
||
|
_mask->set (F_DES, _dir->des());
|
||
|
f1.set_notify(fld_notify);
|
||
|
f1.sheet_mask().field(FLD_LEN).set_handler(len_handler);
|
||
|
for (int i = 0; i < rdes->NFields; i++) f1.row(i) = build_field(i);
|
||
|
f2.set_notify(key_notify);
|
||
|
for (i = 0; i < rdes->NKeys; i++) f2.row(i) = build_key_expr(i);
|
||
|
if (_mask->run() == K_SAVE)
|
||
|
{
|
||
|
rdes->NFields = f1.items();
|
||
|
for (i = 0; i < rdes->NFields; i++)
|
||
|
{
|
||
|
TToken_string& s = f1.row(i);
|
||
|
update_field(i, s);
|
||
|
}
|
||
|
_rec->rehash();
|
||
|
rdes->NKeys = f2.items();
|
||
|
for (i = 0; i < rdes->NKeys; i++)
|
||
|
{
|
||
|
TToken_string& s = f2.row(i);
|
||
|
update_key_expr(i, s);
|
||
|
}
|
||
|
save();
|
||
|
}
|
||
|
}
|