campo-sirio/ve/ve2401.cpp

347 lines
8.0 KiB
C++
Raw Normal View History

#include "ve2400.h"
#include "ve2401.h"
#include "../db/dblib.h"
#include <automask.h>
#include <diction.h>
#include <recset.h>
#include <utility.h>
///////////////////////////////////////////////////////////
// Utility per gestione struttura codice avanzato
///////////////////////////////////////////////////////////
const TString& root_code()
{
static TString8 _root_code; // Solitamente lungo 3, ma stiamo larghi
if (_root_code.empty())
{
const TString query = "USE FSA SELECT B0=\"X\"";
TISAM_recordset set(query);
if (set.move_first())
_root_code = set.get("CODTAB").as_string();
else
_root_code = " "; // Evito riletture inutili
}
return _root_code;
}
static const TRectype& get_sublevel_info(const TString& code)
{
return cache().get("FSA", code.full() ? code : root_code());
}
///////////////////////////////////////////////////////////
// Maschera dinamica per inserimento codici
///////////////////////////////////////////////////////////
class TCodart_mask : public TAutomask
{
static TCodice_articolo _restart;
TString80 _children;
TString80 _separators;
TString80 _prompts;
bool _add_descr;
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void start_run();
void create_level(int level, const TString& subcode);
bool build_children();
public:
bool restart() const { return _restart.full(); }
static void restart_with(const TString& cod) { _restart = cod; }
const TString & get_descr_separator(const int level);
int get_descr_order(const int level);
const bool add_descr() { return _add_descr; }
TCodart_mask();
};
TCodice_articolo TCodart_mask::_restart;
bool TCodart_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case 101:
if (e == fe_modify && !o.empty()) // Se cambio il contenuto del primo livello ...
{
_restart = o.get();
stop_run(K_FORCE_CLOSE);
}
break;
default:
break;
}
return true;
}
void TCodart_mask::start_run()
{
first_focus(101);
if (_restart.full())
{
const TString r(_restart);
bool spegni101 = false;
int from = 0;
for (short id = 101; id2pos(id) >= 0; id++)
{
const int len = efield(id).size();
const TString16 part = r.mid(from, len);
if (part.not_empty())
{
set(id, part);
from += len;
if (id == 101)
{
if (build_children())
first_focus(102);
}
else
spegni101 = true;
}
else
break;
}
_restart.cut(0);
enable(101, !spegni101);
}
TAutomask::start_run();
}
int TCodart_mask::get_descr_order(const int level)
{
int order = 0;
const int pos = 48 + (level - 1);
if (level > 0 && _separators.len() >= pos)
{
char ord = _separators[pos];
if (ord > ' ')
order = ord - '0';
}
return order;
}
const TString & TCodart_mask::get_descr_separator(const int level)
{
TString & sep = get_tmp_string(8);
if (level > 0)
{
sep = _separators.mid((level - 1)*6, 6);
sep.trim();
sep = esc(sep);
}
return (const TString & )sep;
}
void TCodart_mask::create_level(int level, const TString& subcode)
{
const TRectype& fsa = get_sublevel_info(subcode);
if (!fsa.empty())
{
const TString4 code = fsa.get("CODTAB"); // Puo' essere diverso da subcode!
TString80 prompt = fsa.get("S0");
if (level > 1)
{
TString16 gprompt = _prompts.mid((level - 2) * 10, 10);
gprompt.trim();
if (gprompt.blank() || !prompt.starts_with(gprompt))
prompt = gprompt;
}
prompt.left_just(30);
const TString& picture = fsa.get("S1");
const int length = picture.len();
TEdit_field& kfld = add_string(100+level, 0, prompt, 1, level, length, "BU");
TEdit_field& dfld = add_string(200+level, 0, "", 40, level, 50, "B", 36);
TFilename tmp; tmp.temp();
ofstream out(tmp);
out << "USE GSA" << endl; //usa la tabella dei sottolivelli articolo
out << "IN CODTAB[1,3] \"" << code << "\" SELECT" << endl;
out << "IN CODTAB[4,0] " << kfld.dlg() << endl;
out << "DI \"" << prompt;
if (length > prompt.len())
out << '@' << length;
out << "\" CODTAB[4,0]" << endl;
out << "DI \"" << HR("Descrizione") << "@50\" S0" << endl;
out << "OU " << kfld.dlg() << " CODTAB[4,0]" << endl;
out << "OU " << dfld.dlg() << " S0" << endl;
out << "CH RE" << endl;
out << "ADD RU mg0 -0 GSA " << code << endl;
out << "EN" << endl;
out.close();
TScanner scan(tmp);
while (scan.pop() != "EN")
kfld.parse_item(scan);
xvt_fsys_remove_file(tmp);
ofstream outd(tmp);
outd << "USE GSA KEY 2 SELECT CODTAB[1,3]==\"" << code << "\"" << endl; //usa la tabella dei sottolivelli articolo
outd << "IN S0 " << dfld.dlg() << endl;
outd << "DI \"" << HR("Descrizione") << "@50\" S0" << endl;
outd << "DI \"" << prompt;
if (length > prompt.len())
outd << '@' << length;
outd << "\" CODTAB[4,0]" << endl;
outd << "CO OU " << kfld.dlg() << endl;
outd << "CH SE" << endl;
outd << "ADD RU mg0 -0 GSA " << code << endl;
outd << "EN" << endl;
outd.close();
TScanner scand(tmp);
while (scand.pop() != "EN")
dfld.parse_item(scand);
xvt_fsys_remove_file(tmp);
set_handlers();
}
}
bool TCodart_mask::build_children()
{
TString8 code = root_code();
code << get(101);
// Non usare qui un TString& children, altrimenti cambia sul piu' bello!
_children = cache().get("GSA", code, "S1");
_separators = cache().get("GSA", code, "S2");
_prompts = cache().get("GSA", code, "S4");
_prompts.left(10);
_prompts.rpad(10);
_prompts << cache().get("GSA", code, "S3");
_add_descr = cache().get("GSA", code, "B0").full();
// Affetto la stringona S1 in sottocodici da 3 caratteri l'uno
for (int i = 0; i < 9; i++)
{
const TString4 subcode = _children.mid(i*3, 3);
if (subcode.full())
create_level(i+2, subcode);
else
break;
}
force_update();
return id2pos(102) > 0;
}
TCodart_mask::TCodart_mask() : TAutomask(TR("Articolo guidato"), 1, 78, 21)
{
add_button(DLG_OK, 0, "", -12, -1, 10, 2);
add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
create_level(1, EMPTY_STRING);
}
bool advanced_codart_ask(TString& code, TString& desc)
{
bool ok = false;
bool running = true;
if (code.full())
TCodart_mask::restart_with(code);
code.cut(0);
desc.cut(0);
while (running)
{
TCodart_mask m;
ok = m.run() == K_ENTER;
if (ok)
{
int order[20];
int elements = 0;
int id;
const bool add_des = m.add_descr();
order[0] = 0;
for (id = 101; m.id2pos(id) >= 0; id++, elements++)
{
const int el = id - 101;
if (add_des || id > 101)
order[el] = m.get_descr_order(el);
code << m.get(id);
}
if (!add_des)
elements--;
const int start_id = add_des ? 101 : 102;
while (elements-- > 0)
{
int ord = 1000;
int el = -1;
for (id = start_id; m.id2pos(id) >= 0; id++)
{
if (order[id - 101] < ord)
{
el = id - 101;
ord = order[el];
}
}
if (el >= 0)
{
const int dlg = el + 101;
order[el] = 1001;
const TString descpiece(esc(m.get(dlg + 100)));
if (descpiece.full())
{
if (desc.full())
desc << m.get_descr_separator(el);
desc << descpiece;
}
}
}
running = false;
}
else
running = m.restart();
}
return ok;
}
///////////////////////////////////////////////////////////
// Essenzialissima interfaccia pubblica
///////////////////////////////////////////////////////////
bool advanced_codart_enabled()
{
return root_code().full();
}
bool advanced_codart_handler(TMask_field& fld, KEY key)
{
if (key == K_SPACE)
{
TString code, desc;
if (advanced_codart_ask(code, desc))
{
TMask& msk = fld.mask();
TString desc1 = desc.mid(50);
desc = desc.left(50);
msk.set(F_DESCR, desc);
msk.set(F_DESCRAGG, desc1);
msk.set(F_CODART, code, true);
msk.field(F_CODART).set_focus();
}
}
return true;
}