#include "ve2400.h" #include "ve2401.h" #include "../db/dblib.h" #include #include #include #include /////////////////////////////////////////////////////////// // 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; }