diff --git a/include/about.cpp b/include/about.cpp index e3282f7fc..a49d80f2f 100755 --- a/include/about.cpp +++ b/include/about.cpp @@ -317,7 +317,7 @@ TInfo_mask::TInfo_mask() : TProperty_sheet(TR("Informazioni")) case _dongle_hardlock: prot = "Hardlock"; break; case _dongle_eutron : prot = "Eutron"; break; case _dongle_network : prot = dongle().server_name(); break; - case _dongle_aladdin : prot = "Aladdin"; break; + case _dongle_ssa : prot = "SSA"; break; default : prot = TR("Nessuna"); break; } diff --git a/include/applicat.cpp b/include/applicat.cpp index 1679eac48..f2a7bd466 100755 --- a/include/applicat.cpp +++ b/include/applicat.cpp @@ -373,37 +373,27 @@ const char* TApplication::get_module_name() const if (module.empty()) { const TDongle& d = dongle(); - const word aut = d.module_name2code(_name.left(2)); + const TString4 modname = _name.left(2); + const word aut = d.module_name2code(modname); module = d.module_code2desc(aut); bool ok = module.full(); - if (ok && check_autorization()) - ok = has_module(aut); + if (ok && check_autorization()) + ok = dongle().login(modname); if (!ok) { if (module.empty()) - module = "Tools"; + module = modname; TToken_string em(extra_modules()); if (!em.empty_items()) { - if (em != "*") - { - FOR_EACH_TOKEN(em, cod) - { - const word alt = d.module_name2code(cod); - if (has_module(alt)) - { - ok = true; - break; - } - } - } - else - ok = true; + ok = em == "*"; + FOR_EACH_TOKEN(em, cod) if (!ok) + ok = dongle().login(cod); } if (!ok) { - error_box(TR("Il modulo '%s' non e' autorizzato per l'utente %s"), (const char*)module, ((const char*)user())); + error_box(FR("Il modulo '%s' non e' autorizzato per l'utente %s"), (const char*)module, ((const char*)user())); module.cut(0); } } @@ -522,7 +512,7 @@ void TApplication::run( const int sn = get_serial_number(); if (sn > 0 && !test_assistance_year()) { - error_box(TR("E' necessario attivare il contratto di assistenza per l'anno in corso")); + error_box(FR("E' necessario attivare il contratto di assistenza per la chiave %d"), sn); return; } @@ -607,11 +597,11 @@ void TApplication::uncheck_menu_item(MENU_TAG item) // @mfunc Permette di abilitare/disabilitare una voce di menu' void TApplication::enable_menu_item( - MENU_TAG item, // @parm Voce del menu' da abilitare/disabilitare - bool on) // @parm Operazione da svolgere sulla voce del menu': + MENU_TAG item, // @parm Voce del menu da abilitare/disabilitare + bool on) // @parm Operazione da svolgere sulla voce del menu // - // @flag TRUE | Viene abilitata la voce del menu' - // @flag FALSE | Viene disabilitata la voce del menu' + // @flag TRUE | Viene abilitata la voce del menu + // @flag FALSE| Viene disabilitata la voce del menu { xvt_menu_set_item_enabled(TASK_WIN, item, on); xvt_menu_update(TASK_WIN); diff --git a/include/automask.cpp b/include/automask.cpp index 7cae8718b..7027ae98c 100755 --- a/include/automask.cpp +++ b/include/automask.cpp @@ -6,8 +6,7 @@ bool TAutomask::error_box(const char* fmt, ...) char* msg = message.get_buffer(); va_list argptr; va_start(argptr, fmt); - int len = vsprintf(msg, fmt, argptr); - CHECKD(len <= message.size(), "Error message too long: ", len); + vsnprintf_s(msg, message.size(), _TRUNCATE, fmt, argptr); va_end(argptr); if (is_sheetmask() && !is_running()) diff --git a/include/brwbut.cpp b/include/brwbut.cpp new file mode 100644 index 000000000..cae07bae7 --- /dev/null +++ b/include/brwbut.cpp @@ -0,0 +1,1765 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../mg/anamag.h" + +/////////////////////////////////////////////////////////// +// TBrowse_button +/////////////////////////////////////////////////////////// + +TBrowse_button::TBrowse_button(TEdit_field* f) + : _fld(f) +{ } + +TBrowse_button::~TBrowse_button() +{ +} + +// Certified 100% +TEditable_field& TBrowse_button::field(short id) const +{ + if (id > 0) + { + TMask_field& f = _fld->mask().field(id); + CHECKD(f.is_editable(), "Can't use in a browse the field ", id); + return (TEditable_field&)f; + } + return *_fld; +} + +/////////////////////////////////////////////////////////// +// TList_sheet +/////////////////////////////////////////////////////////// + +// Certified 100% +TList_sheet::TList_sheet(TEdit_field* f, const char* caption, const char* head) + : TBrowse_button(f), _row(-1), _caption(caption), _head(head) +{ } + +// Certified 100% +TList_sheet::~TList_sheet() +{ } + + +// Certified 100% +void TList_sheet::parse_input(TScanner& scanner) +{ + _inp_id.add(scanner.pop()); +} + +// Certified 100% +void TList_sheet::parse_item(TScanner& scanner) +{ + _data.add(new TToken_string(scanner.string())); +} + +// Certified 100% +void TList_sheet::parse_output(TScanner& scanner) +{ + _out_id.add(scanner.pop()); +} + +// il numero di riga selezionata +int TList_sheet::do_input() +{ + if (_inp_id.empty_items()) + return -2; // List empty! + + _inp_id.restart(); + TToken_string rowsel(80); + + for (const char* fld = _inp_id.get(); fld; fld = _inp_id.get()) + { + if (*fld == '"') + { + rowsel.add(fld+1); + if (rowsel.not_empty()) rowsel.cut(rowsel.len()-1); + } + else + { + const short id = field().atodlg(fld); + if (id > 0) + { + const TMask_field& f = field(id); + if (f.class_id() == CLASS_ZOOM_FIELD) + { + const TZoom_field& z = (TZoom_field&)f; + rowsel.add(z.get_first_line()); + } + else + rowsel.add(f.get()); + } + else rowsel.add(""); + } + } + + TString fd, it; + for (int i = 0 ; i < _data.items(); i++) + { + TToken_string& ts =_data.row(i); + + ts.restart(); + const char * item; + for (item = rowsel.get(0); item ; item = rowsel.get()) + { + it = item; it.trim(); + fd = ts.get(); fd.trim(); + if (fd != it) break; + } + if (!item) return i; + } + + return -1; // Value not found! +} + + +// Certified 50% +void TList_sheet::do_output(CheckTime t) +{ + if (_row < 0 || t == FINAL_CHECK) + return; + + _out_id.restart(); + TToken_string& rowsel = _data.row(_row); + rowsel.restart(); + for (const char* fld = _out_id.get(); fld; fld = _out_id.get()) + { + const short id = field().atodlg(fld); + TMask_field& f = field(id); + const char* val = rowsel.get(); + if (t != STARTING_CHECK || f.field() == NULL) + { + const bool hit = f.get() != val; + f.set(val); + if (hit && field().dlg() != id) + { + f.on_hit(); + if (t == RUNNING_CHECK) + f.check(); + } + } + } +} + + +// Certified 100% +KEY TList_sheet::run() +{ + TArray_sheet sci(3, 3, -3, -3, _caption, _head); + sci.rows_array() = _data; + + _row = do_input(); + sci.select(_row); + const KEY k = sci.run(); + + switch (k) + { + case K_ENTER: + _row = (int)sci.selected(); + do_output(); + break; + default: + break; + } + + return k; +} + + +// Certified 100% +bool TList_sheet::check(CheckTime t) +{ + _row = do_input(); + bool passed = _row != -1; + if (passed) + do_output(t); + else + { + switch(field().check_type()) + { + case CHECK_SEARCH: passed = true; break; + default: break; + } + } + return passed; +} + + +/////////////////////////////////////////////////////////// +// TBrowse +/////////////////////////////////////////////////////////// + +// Certified 100% +TBrowse::TBrowse(TEdit_field* f, TRelation* r, int key, const char* filter) + : TBrowse_button(f), + _relation(r), _cursor(new TCursor (r, "", key)), + _filter(filter), _secondary(false), _alt_browse(NULL), + _custom_filter_handler(NULL) +{ + custom_cursor(); +} + + +// Certified 100% +TBrowse::TBrowse(TEdit_field* f, TCursor* c) + : TBrowse_button(f), + _relation(NULL), _cursor(c), _secondary(false), _alt_browse(NULL), + _custom_filter_handler(NULL) +{ + custom_cursor(); +} + + +// Certified 100% +TBrowse::~TBrowse() +{ + // Se e' stato usato il primo costruttore devo distruggere la relazione ed il cursore + if (_relation) + { + delete _cursor; + delete _relation; + } + if (_alt_browse) + delete _alt_browse; +} + +static bool descr_filter_handler(TMask_field& f, KEY k) +{ + if (k == K_SPACE) + { + TString expr; + if (!f.get().empty()) // Filtro attivato! + { + const short id = f.dlg()-500; + TString e = f.mask().get(id); // Espressione regolare + e.strip("\"'"); // Tolgo caratteri che potrebbero dare problemi + if (!e.blank()) + expr << "(DESCR+DESCRAGG)" << "?=\"" << e << '"'; + if (expr.empty()) + f.reset(); + } + ((TBrowse_sheet&) f.mask()).add_custom_filter(expr); + } + return true; +} + +void TBrowse::custom_cursor() +{ + TRelation * relation = _relation == NULL ? _cursor->relation() : _relation; + int logicnum = relation->lfile().num(); + + switch(logicnum) + { + case LF_ANAMAG : + if (_cursor->key() == 2 && ini_get_bool(CONFIG_DITTA, "Main", "CUSTOM_SEARCH_" TOSTRING(LF_ANAMAG), false, 2)) + { + delete _cursor; + _cursor = new TSorted_cursor(relation, ANAMAG_DESCR "|" ANAMAG_DESCRAGG "[1,50]", "", 2); + set_custom_filter_handler(descr_filter_handler); + } + break; + default: + break; + } +} + +void TBrowse::custom_display() +{ + switch(_cursor->file().num()) + { + case LF_ANAMAG: + if (_cursor->key() == 2 && ini_get_bool(CONFIG_DITTA, "Main", "CUSTOM_SEARCH_" TOSTRING(LF_ANAMAG), false, 2)) + { + TToken_string & it = (TToken_string &) items(); + if (it.find(ANAMAG_DESCRAGG) < 0) + { + const char * s = it.get(0); + for (int i = 0; s && *s; s = it.get(++i)) + if (strcmp(s, ANAMAG_DESCR) == 0) + { + add_display_field("Descrizione aggiuntiva@50", ANAMAG_DESCRAGG, i + 1); + break; + } + } + } + break; + case LF_TABMOD: + { + _cursor->file().zero(); // Azzera il record corrente in modo da impostare "MOD" + const TString& mod =_cursor->curr().get("MOD"); + const word cod = dongle().module_name2code(mod); + field().set_module(cod); + } + break; + default: + break; + } +} + +// Certified 100% +void TBrowse::parse_display(TScanner& scanner) +{ + const char* s = scanner.string(); + _head.add(dictionary_translate_header(s)); + s = scanner.line(); + _items.add(s); +} + + +void TBrowse::parse_input(TScanner& scanner) +{ + const char* s = scanner.pop(); + _inp_fn.add(s); + + s = scanner.pop(); + if (*s == '"') // Constant string + { + scanner.push(); + TString& str = scanner.line(); + _inp_id.add(str); + } + else // Field on the mask + { + CHECKS(_inp_id.get_pos(s) < 0, "Duplicate input field ", s); + _inp_id.add(s); + if (scanner.popkey() == "SE") + _inp_id << '@'; // Special FILTERing field + else + scanner.push(); + } +} + + +void TBrowse::parse_output(TScanner& scanner) +{ + const char* s = scanner.pop(); +#ifdef DBG + field().atodlg(s); +#endif + _out_id.add(s); + s = scanner.pop(); + _out_fn.add(s); + _secondary = false; +} + + +bool TBrowse::parse_copy(const TString& what, const TBrowse& b) +{ + const bool all = what == "AL"; + if (all || what == "US") + { + set_insert(b.get_insert()); + _filter = b.get_filter(); + if (!field().has_warning() && b.field().has_warning()) + field().set_warning(b.field().get_warning()); + if (!all) return true; + } + if (all || what == "IN") + { + _inp_id = b._inp_id; + _inp_fn = b._inp_fn; + if (!all) return true; + } + if (all || what == "DI") + { + _head = b._head; + _items = b._items; + if (!all) return true; + } + if (all || what == "OU") + { + _out_id = b._out_id; + _out_fn = b._out_fn; + _secondary = b.field().has_check(); + } + return true; +} + + +void TBrowse::parse_join(TScanner& scanner) +{ + TString80 j(scanner.pop()); // File or table + + CHECKS(_relation, "Can't join to NULL relation ", (const char*)j); + + int to; + if (scanner.popkey() == "TO") // TO keyword + { + const char* t = scanner.pop(); + to = name2log(t); + } + else + { + to = 0; // _relation->lfile()->num(); + scanner.push(); + } + + int key = 1; + if (scanner.popkey() == "KE") + key = scanner.integer(); + else scanner.push(); + + int alias = 0; + if (scanner.popkey() == "AL") + alias = scanner.integer(); + else scanner.push(); + + TToken_string exp(80); + if (scanner.pop() == "INTO") + { + const char* r = scanner.pop(); + while (strchr(r, '=') != NULL) + { + exp.add(r); + r = scanner.pop(); + } + } + scanner.push(); + +#ifdef DBG + if (exp.empty()) yesnofatal_box("JOIN senza espressioni INTO"); +#endif + + if (isdigit(j[0])) + _relation->add(atoi(j), exp, key, to, alias); // join file + else + { +#ifdef DBG + if (j.len() > 4) + yesnofatal_box("'%s' non e' una tabella valida: %d", (const char*)j); + else +#endif + _relation->add(j, exp, key, to, alias); // join table + } +} + + +void TBrowse::parse_insert(TScanner& scanner) +{ + const TString& key = scanner.popkey(); + _insert.cut(0); + if (key != "NO") + { + _insert << key[0] << scanner.line(); + _insert.trim(); + } +} + +// Ritorna il numero di inputs senza contare quelli che funzionano solo da filtro +int TBrowse::input_fields() +{ + int inp = 0; + for (const char* fld = _inp_id.get(0); fld; fld = _inp_id.get()) + { + if (*fld != '"' && strchr(fld, '@') == NULL) + { + TMask_field& f = field(field().atodlg(fld)); + if (f.active() && f.is_editable()) + inp++; + } + } + return inp; +} + +const char* TBrowse::get_input_fields() const +{ + return _inp_id; +} + +const char* TBrowse::get_input_field_names() const +{ + return _inp_fn; +} + +void TBrowse::add_input_field(const char * id, const char * name, const int pos, bool select) +{ + TString strid(id) ; + + if (select) + strid << '@'; + if (pos < 0 || pos >= _items.items()) + { + _inp_id.add(strid); + _inp_fn.add(name); + } + else + { + _inp_id.insert_at(strid, pos); + _inp_fn.insert_at(name, pos); + } +} + +void TBrowse::remove_display_field(const int pos) +{ + if (pos < 0) + { + _head.cut(0); + _items.cut(0); + } + else + { + _head.destroy(pos); + _items.destroy(pos); + } +} +void TBrowse::copy_input(const TBrowse * b) +{ + if (b) + { + _inp_id = b->_inp_id; + _inp_fn = b->_inp_fn; + } +} + +void TBrowse::copy_display(const TBrowse* b) +{ + if (b) + b->get_display_fields(_head, _items); +} + +void TBrowse::copy_output(const TBrowse * b) +{ + if (b) + { + _out_id = b->_out_id; + _out_fn = b->_out_fn; + } +} + +void TBrowse::add_display_field(const char * hd, const char * name, const int pos) +{ + if (pos < 0 || pos >= _items.items()) + { + _head.add(dictionary_translate_header(hd)); + _items.add(name); + } + else + { + _head.insert_at(dictionary_translate_header(hd), pos); + _items.insert_at(name, pos); + } +} + +void TBrowse::remove_input_field(const int pos) +{ + if (pos < 0) + { + _inp_id.cut(0); + _inp_fn.cut(0); + } + else + { + _inp_id.destroy(pos); + _inp_fn.destroy(pos); + } +} + +void TBrowse::add_output_field(const char * id, const char * name, const int pos) +{ + if (pos < 0 || pos >= _items.items()) + { + _out_id.add(id); + _out_fn.add(name); + } + else + { + _out_id.insert_at(id, pos); + _out_fn.insert_at(name, pos); + } +} + +void TBrowse::remove_output_field(const int pos) +{ + if (pos < 0) + { + _out_id.cut(0); + _out_fn.cut(0); + } + else + { + _out_id.destroy(pos); + _out_fn.destroy(pos); + } +} + + +const char* TBrowse::get_output_fields() const +{ + return _out_id; +} + +const char* TBrowse::get_output_field_names() const +{ + return _out_fn; +} + +// @doc INTERNAL + +// @mfunc Ritorna il numero di campi non vuoti e non filtrati +// +// @rdesc Numero di campi non vuoti e non filtrati +int TBrowse::do_input( + bool filter) // @parm Indica se effettuare il filtro sulla selezione + + // @comm Questa funzione serve ai +{ + int ne = 0; + if (_inp_id.empty()) + return ne; + + _cursor->file(0).zero(); // was cur.zero() che non va bene per le tabelle di modulo + TRectype& cur = _cursor->curr(); + TRectype filtrec(cur); + + _inp_id.restart(); + _inp_fn.restart(); + + TString val; // Value to output + bool tofilter = false; + + for (const char* fld = _inp_id.get(); fld; fld = _inp_id.get()) + { + const TFieldref fldref(_inp_fn.get(), 0); // Output field + + if (*fld == '"') + { + val = (fld+1); + if (val.not_empty()) val.rtrim(1); + tofilter = filter; + } + else + { + const TMask_field* campf = NULL; + + if (*fld == '-') + { + TSheet_field* sheet = field().mask().get_sheet(); + if (sheet != NULL) + { + const short id = atoi(fld+1); + campf = &sheet->mask().field(id); + } + } + else + { + const short id = field().atodlg(fld); + campf = &field(id); + } + + if (campf != NULL) + { + const TMask_field& f = *campf; + val = f.get(); + + switch (f.class_id()) + { + case CLASS_REAL_FIELD: + // Cerco di allineare correttamente i campi interi salvati parzialmente su codtab + if (fldref.to() > 1 && f.size() > 1 && val.full() && + ((TReal_field&)f).decimals() == 0 && fldref.name() == "CODTAB") + { + const int len = fldref.len(cur); + if (f.size() == len && val.len() < len) + val.right_just(len); + } + break; + case CLASS_DATE_FIELD: + if (f.right_justified()) + { + const TDate d(val); + val = d.string(ANSI); + } + break; + default: + break; + } + + const bool filter_flag = strchr(fld, '@') != NULL; + tofilter = filter && filter_flag; + if (f.is_edit() && val.not_empty() && !filter_flag) + ne++; // Increment not empty fields count + } + } + fldref.write(val, *_cursor->relation()); + if (tofilter) + { + const int len = fldref.len(cur); + + if (val.len() < len && cur.type(fldref.name()) == _alfafld) + val.rpad(len, '~'); + fldref.write(val, filtrec); + } + } + + if (!filter) + return ne; + + TString work(_filter.size()); + bool filter_update = false; + + for (int i = 0; _filter[i]; i++) + { + if (_filter[i] == '"') + { + do + { + work << _filter[i++]; + } while (_filter[i] && _filter[i] != '"'); + work << '"'; + if (!_filter[i]) break; + } + else + if (_filter[i] == '#') + { + if (_filter[++i] == '-') + { + TString val; + TSheet_field* sheet = field().mask().get_sheet(); + + if (sheet != NULL) + { + const short id = atoi(&_filter[++i]); + + val = sheet->mask().field(id).get(); + } + work << '"' << val << '"'; + } + else + work << '"' << field(atoi(&_filter[i])).get() << '"'; + while (isspace(_filter[i])) i++; + while (isdigit(_filter[i])) i++; + i--; + } + else + { + work << _filter[i]; + if (_filter[i] == '-' && _filter[i + 1] == '>') + filter_update = true; + } + } + + _cursor->relation()->mask2rel(field().mask()); + _cursor->setfilter(work, filter_update); + _cursor->setregion(filtrec, filtrec); + + return ne; +} + +static TBit_array s_checked; +static short s_checking = 0; + +void TBrowse::do_output(CheckTime t) +{ + if (t == FINAL_CHECK) + return; + + const bool master = s_checking == 0; + if (master) + { + s_checking = field().dlg(); + s_checked.reset(); + // Rendo intoccabili i campi del MIO output + for (const char* fld = _out_id.get(0); fld && *fld; fld = _out_id.get()) + { + const short id = field().atodlg(fld); + s_checked.set(id); + } + } + + TString sum; + TToken_string flds(24, '+'); + + const TRelation& relation = *_cursor->relation(); + + TBit_array spotted; + + _out_fn.restart(); + const char* fld; + for (fld = _out_id.get(0); fld && *fld; fld = _out_id.get()) + { + const short id = field().atodlg(fld); + TMask_field& f = field(id); + + flds = _out_fn.get(); + + bool do_that = t != STARTING_CHECK || f.field() == NULL || (f.mask().mode() == MODE_INS && !f.in_key(0)); + if (do_that && main_app().class_id() == CLASS_RELATION_APPLICATION) + { + // Considera a parte l'inizializzazione delle transazioni! + // Non sovrascrivere con degli output campi che potrebbero essere riempiti dal .ini + if (!f.empty() && f.field() != NULL) + { + const TMask& m = f.mask(); + if (!m.is_running() && m.get_sheet() == NULL) // Maschera principale chiusa + { + const TRelation_application& ra = (const TRelation_application&)main_app(); + if (ra.is_transaction()) + do_that = false; + } + } + } + if (do_that) + { + sum.cut(0); + for(const char* fr = flds.get(0); fr; fr = flds.get()) + { + if (*fr == '"') + { + sum << (fr+1); + sum.rtrim(1); + } + else + { + const TFieldref fld(fr, 0); + sum << fld.read(relation); + } + } + + bool hit = false; + if (master) + { + f.set(sum); + hit = id != s_checking; // Il mio handler viene fatto nella on_key + } + else + { + if (!s_checked[id]) + { + f.set(sum); + s_checked.set(id); + hit = true; + } + } + spotted.set(id, hit); + } + } + + for (fld = _out_id.get(0); fld && *fld; fld = _out_id.get()) + { + const short id = field().atodlg(fld); + if (spotted[id]) + { + TMask_field& f = field(id); + f.check(); + f.on_hit(); + } + } + + if (master) + s_checking = 0; +} + + +void TBrowse::do_clear(CheckTime t) +{ + const bool master = s_checking == 0; + if (master) + { + s_checking = field().dlg(); + s_checked.reset(); + // Rendo intoccabili i campi del MIO input + for (const char* fld = _inp_id.get(0); fld && *fld; fld = _inp_id.get()) + { + if (isdigit(*fld)) + { + const short id = field().atodlg(fld); + s_checked.set(id); + } + } + } + + for (TString16 fld = _out_id.get(0); fld.not_empty(); fld = _out_id.get()) + { + const short id = field().atodlg(fld); + TMask_field& f = field(atoi(fld)); + if (f.field() == NULL && field().dlg() != id && + !s_checked[id] && _inp_id.get_pos(fld) < 0) + { + f.reset(); + s_checked.set(id); + f.on_hit(); + f.check(t); + } + } + + if (master) + s_checking = 0; +} + +bool TBrowse::do_link(bool insert) +{ + bool ok = false; + TString app; + if (_insert.starts_with("MTB", true)) + _cursor->file().get_relapp(app); + else + app = _insert.mid(1); + if (app.find('#') >= 0) + { + const TString w(app); + app = ""; + for (const char* f = w; *f; f++) + { + if (*f == '#') + { + const int id = atoi(++f); + app << field(id).get(); + while (isspace(*f)) ++f; + while (isdigit(*f)) ++f; + if (*f) + app << ' ' << *f; + else + break; + } + else + app << *f; + } + } + + TFilename msg; msg.temp("msg"); + app << " /i" << msg; + + if (insert) + { + TConfig ini(msg, "Transaction"); + ini.set("Action", TRANSACTION_RUN); + } + else + { + TConfig ini(msg, "Transaction"); + ini.set("Action", TRANSACTION_LINK); + + TString8 paragraph; paragraph << _cursor->file().num(); + ini.set_paragraph(paragraph); + + // Uso sempre la chiave 1 per collegarmi agli altri programmi + const TRelation& rel = *_cursor->relation(); + const RecDes& recd = rel.curr().rec_des(); // Descrizione del record della testata + const KeyDes& kd = recd.Ky[0]; // Elenco dei campi della chiave 1 + TString inp_val; + for (int i = 0; i < kd.NkFields; i++) + { + const int nf = kd.FieldSeq[i] % MaxFields; + const RecFieldDes& rf = recd.Fd[nf]; + const TFieldref fldref(rf.Name, 0); + inp_val = fldref.read(rel); + fldref.write(ini, paragraph, inp_val); + } + } + + TExternal_app a(app); + a.run(); + field().mask().set_focus(); + + if (msg.not_empty()) + { + TConfig ini(msg, "Transaction"); + _rec = ini.get_long("Record"); + if (_rec > 0 || !insert) // Modifica o cancellazione + _cursor->update(); // Forza ricalcolo cursore + if (_rec >= 0) + { + _cursor->file().readat(_rec); + ok = _cursor->ok(); + if (ok) + { + rec_cache(_cursor->file().num()).notify_change(); // Svuota eventule cache + do_output(); + } + } + ::remove(msg); + } + return ok; +} + + +TToken_string& TBrowse::create_siblings(TToken_string& siblings) const +{ + siblings = ""; // Azzera la lista dei campi associati + + TBit_array key(4); // Elenco delle chiavi gia' utilizzate + key.set(_cursor->key()); + + TString fn; // Nome campo + + // Scorre la lista dei campi di output + int n = 0; + TToken_string& outid = (TToken_string&)_out_id; + for (const char* i = outid.get(0); i; i = outid.get(), n++) + { + const short id = field().atodlg(i); + const TEditable_field& f = field(id); + if (!f.active() || !f.is_edit()) // Scarta i campi non editabili + continue; + const TEdit_field& e = (const TEdit_field&)f; + const TBrowse* b = e.browse(); + if (b == NULL) + continue; // Scarta i campi senza ricerca + + const TCursor* c = b->cursor(); + + // Considera ricerche sullo stesso file ma con chiave diversa + if (c->file().num() == _cursor->file().num() && + (key[c->key()] == false || id == field().dlg())) + { + _out_fn.get(n, fn); // Legge nome del campo su file + int pos = ((TToken_string&)_items).get_pos(fn); // Determina header corrispondente + if (pos < 0) // Se non lo trova identico ... + { + const int q = fn.find('['); + if (q > 0) + { + fn.cut(q); + pos = ((TToken_string&)_items).get_pos(fn); // ... ritenta senza parentesi + } + } + if (pos >= 0) + { + siblings.add(id); + TString80 h; _head.get(pos, h); + siblings.add(h); + const int et = siblings.find('@'); + if (et > 0) siblings.cut(et); + key.set(c->key()); // Marca la chiave come usata + } + } + } + + return siblings; +} + + +KEY TBrowse::run() +{ + if (_alt_browse && field().get().starts_with("%")) + { + const KEY k = _alt_browse->run(); + if (k == K_ENTER) + { + do_input(true); + _cursor->read(_isgteq); + do_output(); + } + return k; + } + + begin_wait(); + + do_input(true); + _cursor->read(_isgteq); + + TString caption = _cursor->file().description(); + if (caption.blank()) + caption = TR("Selezione"); + + KEY k = K_ESC; + long selected = 0; + + TToken_string siblings, vals; + create_siblings(siblings); + + { + byte buttons = 0; + if (_insert.not_empty()) + { + // Mette il bottone di gestione, a meno che ... + if (_cursor->items() == 0) + buttons = 2; // Non mette il bottone collega se non ci sono elementi + else + buttons = 3; + + if (_insert[0] == 'M' || _insert[0] == 'R') + { + const TString& maskname = field().mask().source_file(); + if (maskname.mid(2,2).compare("tb", 2, true) == 0 && field().in_key(0)) + { + const char* tabname = _cursor->file().name(); + if (maskname.mid(4, 3).compare(tabname, 3, true) == 0) + buttons = 0; + } + } + } + + for (const char* i = _inp_id.get(0); i; i = _inp_id.get()) + { + if (*i != '\0' && *i != '"' && strchr(i, '@') == NULL) + { + const short id = field().atodlg(i); + const TEditable_field& f = field(id); + if (f.active() && f.is_editable()) + { + vals.add(i); + vals.add(f.get()); + vals.add((int)f.dirty()); + } + } + } + + end_wait(); + + TBrowse_sheet s(_cursor, _items, caption, _head, buttons, field(), siblings, _custom_filter_handler); + + k = s.run(); + selected = s.selected(); + } + + switch (k) + { + case K_ESC: + case K_QUIT: + break; + case K_CTRL+'G': + *_cursor = selected; + k = do_link(false) ? K_ENTER : K_ESC; + break; + case K_INS: + k = do_link(true) ? K_ENTER : K_ESC; + break; + case K_ENTER: + *_cursor = selected; + do_output(); + break; + default: + { + for (const char* i = vals.get(0); i && *i; i = vals.get()) + { + const short id = field().atodlg(i); + TEditable_field& f = field(id); + f.set(vals.get()); + f.set_dirty(vals.get_int()); + } + } + if (k >= K_CTRL) // Scatta la ricerca su di una chiave alternativa + { + TMask& m = field().mask(); + const int tag = k - K_CTRL - K_F1; + const short id = siblings.get_int(tag * 2); + TEdit_field& ef = m.efield(id); + ef.set_focus(); + k = K_F9; + if (m.is_running()) + m.send_key(k, id, &ef); //m.send_key(k, id); + } + break; + } + + return k; +} + +void TBrowse::set_cursor(TCursor* c) +{ + if (_cursor != NULL) + delete _cursor; + _cursor = c ; +} + +bool TBrowse::check(CheckTime t) +{ + bool passed = true; + + if (_secondary == true && t != RUNNING_CHECK) + return true; + + + CheckType chk = field().check_type(); + if (chk != CHECK_NONE) + { + // Se ho la ricerca alternativa ed il campo comincia per % ... + if (_alt_browse != NULL && t == RUNNING_CHECK && field().get().starts_with("%")) + { + if (!_alt_browse->check(t)) + return false; + } + + const TMaskmode mode = (TMaskmode)field().mask().mode(); + if (chk == CHECK_REQUIRED && (t == STARTING_CHECK || mode == MODE_QUERY)) + chk = CHECK_NORMAL; + + const int ne = do_input(true); + if (ne || chk == CHECK_REQUIRED) + { + passed = _cursor->test() == NOERR; + + if (t != FINAL_CHECK) + { + if (passed) + { + _cursor->repos(); + do_output(t); + if (t == STARTING_CHECK && field().dirty() > 1) + field().set_dirty(true); + } + else + { + if (chk == CHECK_SEARCH) + { + passed = true; + } + else + { + do_clear(t); + if (!field().mask().query_mode() && field().check_enabled()) + field().set_dirty(3); + } + } + } + else + { + if (chk == CHECK_SEARCH) + passed = true; + } + } + else + { + if (chk == CHECK_SEARCH) + passed = true; + else + { + if (t != FINAL_CHECK) + do_clear(t); + } + } + } + return passed; +} + +bool TBrowse::empty_check() +{ + if (field().mask().query_mode() || field().check_type() != CHECK_REQUIRED) + return true; + else + return do_input() > 0; +} + +bool TBrowse::set_alt_browse(int altkey) +{ + if (_alt_browse) + delete _alt_browse; + if (altkey > 2) + _alt_browse = new TAlternative_browse(&field(), altkey); + return altkey > 2; +} + +/////////////////////////////////////////////////////////// +// TFile_select +/////////////////////////////////////////////////////////// + +TFile_select::TFile_select(TEdit_field* ef, const char* filter) +: TBrowse_button(ef), _filter(filter) +{ } + +void TFile_select::parse_input(TScanner& scanner) +{ + scanner.pop(); +} + +void TFile_select::parse_output(TScanner& scanner) +{ + scanner.pop(); +} + +KEY TFile_select::run() +{ + TFilename path; + path = field().get(); + if (path.full() && _filter.find('.') > 0 && !_filter.ends_with(".*")) + path.ext(_filter.ext()); + + FILE_SPEC fs; xvt_fsys_convert_str_to_fspec(path, &fs); + + bool good = xvt_dm_post_file_open(&fs, field().prompt()) == FL_OK; + if (good) + { + xvt_fsys_convert_fspec_to_str(&fs, path.get_buffer(), path.size()); + good = _filter.blank() || xvt_str_match(path.name(), _filter, false); + if (good) + field().set(path); + else + field().error_box(FR("Il nome del file non corrisponde a %s"), _filter.get_buffer()); + } + return good ? K_ENTER : K_ESC; +} + +bool TFile_select::check(CheckTime ct) +{ + const TFilename name = field().get(); + if (ct != STARTING_CHECK && name.empty() && + field().check_type() == CHECK_REQUIRED) + return false; + bool ok = _filter.empty() || xvt_str_match(name, _filter, false); + if (ok && field().roman()) // Must exist + ok = name.exist(); + return ok; +} + +/////////////////////////////////////////////////////////// +// TDir_select +/////////////////////////////////////////////////////////// + +TDir_select::TDir_select(TEdit_field* ef) : TBrowse_button(ef) +{ } + +void TDir_select::parse_input(TScanner& scanner) +{ + scanner.pop(); +} + +void TDir_select::parse_output(TScanner& scanner) +{ + scanner.pop(); +} + +KEY TDir_select::run() +{ + DIRECTORY savedir; + xvt_fsys_get_dir(&savedir); + + DIRECTORY dir; + xvt_fsys_convert_str_to_dir(field().get(), &dir); + bool good = xvt_dm_post_dir_sel(&dir) == FL_OK; + xvt_fsys_set_dir(&savedir); + + if (good) + { + TFilename path; + xvt_fsys_convert_dir_to_str(&dir, path.get_buffer(), path.size()); + field().set(path); + } + return good ? K_ENTER : K_ESC; +} + +bool TDir_select::check(CheckTime ct) +{ + const TFilename name = field().get(); + if (ct != STARTING_CHECK && name.empty() && + field().check_type() == CHECK_REQUIRED) + return false; + bool ok = true; + if (field().roman()) // Must exist + ok = name.exist(); + return ok; +} + +/////////////////////////////////////////////////////////// +// TProfile_select +/////////////////////////////////////////////////////////// + +TProfile_select::TProfile_select(TEdit_field* ef) +: TBrowse_button(ef) +{ } + +void TProfile_select::parse_input(TScanner& scanner) +{ + scanner.pop(); +} + +void TProfile_select::parse_output(TScanner& scanner) +{ + scanner.pop(); +} + +HIDDEN int get_profile_desc(TConfig& cfg, void* jolly) +{ + const int num = atoi(cfg.get_paragraph()); + if (num > 0) + { + TString_array& p = *(TString_array*)jolly; + TToken_string* str = new TToken_string; + str->format("%4d", num); + str->add(cfg.get("Description")); + p.add(str); + } + return false; +} + +int TProfile_select::get_descriptions(TString_array& a) const +{ + TFilename profname; + field().mask().make_profile_name(profname); + TConfig prof(profname); + a.destroy(); + prof.for_each_paragraph(get_profile_desc, &a); + a.sort(); + return a.items(); +} + +KEY TProfile_select::run() +{ + TArray_sheet p(3, 3, -3, -3, TR("Profili"), HR("Codice@6R|Descrizione@60"), 0x6, 2); + const short id = DLG_USER+1; + TEdit_field& prompt = p.add_string(id, 0, PR("Salva con nome "), 1, 0, 60); + p.add_button(DLG_SAVEREC, PR("~Registra"), K_CTRL+'r', TOOL_SAVEREC); + prompt.set(field().get()); + + TMask& m = field().mask(); + TFilename profname; m.make_profile_name(profname); + + bool running = true; + KEY key; + while (running) + { + p.destroy(); + TString_array& a = p.rows_array(); + get_descriptions(a); + p.field(DLG_SAVEREC).enable(a.items()>0); + FOR_EACH_ARRAY_ROW_BACK(a, r, row) + if (field().get() == row->get(1)) break; + if (r) + p.select(r); + + key = p.run(); + switch(key) + { + case K_ENTER: + { + const int num = p.row().get_int(0); + TString16 para; para << m.load_profile(num); + prompt.set(p.row().get(1)); + running = false; + } + break; + case K_CTRL+'r': + { + const TString& name = p.get(id); + FOR_EACH_ARRAY_ROW_BACK(a, r, row) + if (r != p.selected() && name == row->get(1)) break; + if (r < 0) + { + const int num = p.row().get_int(0); + m.save_profile(num, name); + running = false; + } + else + error_box("Esiste gia' un profilo di nome\n%s", + (const char*)name); + } + break; + case K_INS: + { + const TString& name = p.get(id); + if (!name.blank()) + { + FOR_EACH_ARRAY_ROW_BACK(a, r, row) + if (name == row->get(1)) break; + if (r < 0) + { + TString16 para; para << m.save_profile(-1, name); + field().set(name); + running = false; + } + else + error_box("Esiste gia' un profilo di nome\n%s", + (const char*)name); + } + else + error_box("E' necessario dare un nome al profilo"); + } + break; + case K_DEL: + { + TString16 para; para << p.row().get_int(0); + const TString desc = p.row().get(1); + TConfig prof(profname, para); + if (yesno_box("Confermare la cancellazione del profilo %s\n%s", + (const char*)para, (const char*)desc)) + prof.remove_all(); + } + break; + default: + running = false; + break; + } + } + field().set(prompt.get()); + return key; +} + +bool TProfile_select::check(CheckTime ct) +{ + switch (ct) + { + case STARTING_CHECK: + { + TMask& m = field().mask(); + TFilename name; m.make_profile_name(name); + TString16 para; para << m.load_profile(); + TConfig ini(name, para); + field().set(ini.get("Description")); + } + break; + case RUNNING_CHECK: + if (!field().empty()) + { + const TString& name = field().get(); + TString_array a; + get_descriptions(a); + FOR_EACH_ARRAY_ROW_BACK(a, r, row) + { + if (name == row->get(1)) + { + field().mask().load_profile(row->get_int(0)); + break; + } + } + if (r < 0) + return field().error_box("Profilo inesistente"); + } + break; + case FINAL_CHECK: + if (!field().active()) + { + TMask& m = field().mask(); + m.save_profile(); + } + break; + default: + break; + } + return true; +} + +/////////////////////////////////////////////////////////// +// TReport_select +/////////////////////////////////////////////////////////// + +TReport_select::TReport_select(TEdit_field* ef, const char* classe) +: TBrowse_button(ef), _classe(classe) +{ } + +void TReport_select::parse_input(TScanner& scanner) +{ + scanner.pop(); +} + +void TReport_select::parse_output(TScanner& scanner) +{ + scanner.pop(); +} + +KEY TReport_select::run() +{ + TFilename path = field().get(); + if (select_custom_file(path, "rep", _classe)) + { + path = path.name(); + path.ext(""); + field().set(path); + } + + return path.not_empty() ? K_ENTER : K_ESC; +} + +bool TReport_select::check(CheckTime ct) +{ + TFilename name = field().get(); + if (ct != STARTING_CHECK && name.empty() && + field().check_type() == CHECK_REQUIRED) + return false; + + bool ok = true; + if (field().roman()) // Must exist + ok = name.custom_path(); + return ok; +} + +/////////////////////////////////////////////////////////// +// TAlternative_browse +/////////////////////////////////////////////////////////// + +static TBit_array _alternative_bits; + +static bool alternative_filter(const TRelation* rel) +{ + const TRecnotype recno = rel->file().recno(); + return _alternative_bits[recno]; +} + +TCursor& TAlternative_browse::cursor() +{ + if (_cursor == NULL) + { + TBrowse& b = *field().browse(); + TCursor& c = *b.cursor(); + + const RecDes& rd = c.curr().rec_des(); + const KeyDes& kd = rd.Ky[_altkey-1]; + const int mf = kd.FieldSeq[kd.NkFields-1] % MaxFields; + _altfld = rd.Fd[mf].Name; + + _outfld = "RAGSOC"; + TToken_string outfields = b.get_output_fields(); + const int outpos = outfields.get_pos(field().dlg()); + if (outpos >= 0) + { + outfields = b.get_output_field_names(); + outfields.get(outpos, _outfld); + } + + _cursor = new TCursor(c.relation(), "", _altkey); + _alternative_bits.reset(); + const TRecnotype old = c.pos(); + for (c = 0L; c.ok(); ++c) + { + if (c.curr().get(_altfld).full()) + _alternative_bits.set(c.file().recno()); + } + _cursor->set_filterfunction(alternative_filter); + _cursor->items(); + _cursor->freeze(); + c = old; + } + return *_cursor; +} + +bool TAlternative_browse::check(CheckTime /*t*/) +{ + const TBrowse& b = *field().browse(); + TCursor& c = cursor(); + + TString80 magic_val; + magic_val = field().get(); + magic_val.strip("% "); + magic_val.upper(); + + c = 0L; + + TRectype& curr = c.curr(); + curr.put(_altfld, magic_val); + int err = c.read(); + if (err == NOERR && curr.get(_altfld).starts_with(magic_val)) + { + field().set(curr.get(_outfld)); + return true; + } + + curr.put(_altfld, magic_val.left(1)); + + double best = 0; + for (err = c.read(); err == NOERR; ++c) + { + const TString& val = curr.get(_altfld); + if (val[0] != magic_val[0]) + break; + + double n = xvt_str_fuzzy_compare(magic_val, val); + if (n < best && n < 0.5 && val.find(magic_val) >= 0) + n += 0.3; + + if (n > best && n > 0.6) + { + best = n; + field().set(curr.get(_outfld)); + if (n == 1.0) + break; + } + } + + return best > 0; +} + +static TAlternative_browse* _curr_browse = NULL; + +static bool alternative_code_handler(TMask_field& f, KEY k) +{ + if (k == K_F2) + { + f.reset(); + k = K_SPACE; + } + if (k == K_SPACE) + { + TCursor& c = _curr_browse->cursor(); + TRectype& curr = c.curr(); + const RecDes& rd = curr.rec_des(); + const KeyDes& kd = rd.Ky[c.key()-1]; + const int mf = kd.FieldSeq[kd.NkFields-1] % MaxFields; + const char* altfld = rd.Fd[mf].Name; + curr.put(altfld, ((TEdit_field&)f).get_window_data()); + const TRecnotype pos = c.read(); + if (pos >= 0 && pos < c.items()) + { + TSheet& s = (TSheet&)f.mask(); + s.select(pos); + } + } + + return true; +} + +KEY TAlternative_browse::run() +{ + const TBrowse& b = *field().browse(); + TCursor& c = cursor(); + + TString caption = c.file().description(); + if (caption.blank()) + caption = TR("Selezione"); + + TToken_string fields, head; + b.get_display_fields(head, fields); + const int pos = fields.get_pos(_altfld); + const int sz = c.curr().length(_altfld); + + if (pos > 0) + { + fields.destroy(pos); + fields.insert_at(_altfld, 0); + TString80 h; head.get(pos, h); + head.destroy(pos); + head.insert_at(h, 0); + } + else + { + fields.insert_at(_altfld, 0); + TString80 h; h << "Cod.Alt.@" << sz; + head.insert_at(h, 0); + } + + TCursor_sheet sheet(&c, fields, caption, head, 0, 2); + TEdit_field& e = sheet.add_string(field().dlg(), 0, head.before('@'), 1, 1, sz, "U"); + e.set_handler(alternative_code_handler); + + if (c.items() > 0) + { + TString80 magic_val; + magic_val = field().get(); + magic_val.strip("% "); + magic_val.upper(); + if (magic_val.full()) + { + e.set(magic_val); + c.curr().put(_altfld, magic_val); + c.read(); + } + else + c = 0L; + } + + _curr_browse = this; + const KEY k = sheet.run(); + _curr_browse = NULL; + + if (k == K_ENTER) + { + c = sheet.selected(); + field().set(c.curr().get(_outfld)); + } + return k; +} + +TAlternative_browse::TAlternative_browse(TEdit_field* ef, int altkey) : TBrowse_button(ef), _altkey(altkey), _cursor(NULL) +{ +} + +TAlternative_browse::~TAlternative_browse() +{ + if (_cursor) + delete _cursor; +} diff --git a/include/brwbut.h b/include/brwbut.h new file mode 100644 index 000000000..b37b3f9f3 --- /dev/null +++ b/include/brwbut.h @@ -0,0 +1,406 @@ +#ifndef __BRWBUT_H +#define __BRWBUT_H + +/////////////////////////////////////////////////////////// +// TBrowse_button +/////////////////////////////////////////////////////////// + +class TEdit_field; +class TEditable_field; + +class TBrowse_button : public TObject +{ + TEdit_field* _fld; + +protected: + // @cmember Ritorna il primo valore di

+ TEdit_field& field() const { return *_fld; } + + // @cmember Ritorna il campo

-esimo + TEditable_field& field(short id) const; + +public: + // @cmember Controlla la sintassi della input del campo e ne setta i membri + virtual void parse_input(TScanner& scanner) pure; + + // @cmember Controlla la sintassi della output del campo e ne setta i membri + virtual void parse_output(TScanner& scanner) pure; + + virtual KEY run() pure; + + // @cmember Controlla la validita' del campo + virtual bool check(CheckTime = RUNNING_CHECK) pure; + + virtual bool is_browse() const { return false; } + virtual bool is_sheet() const { return false; } + virtual bool is_filesel() const { return false; } + virtual bool is_profile() const { return false; } + + TBrowse_button(TEdit_field* f); + virtual ~TBrowse_button(); +}; + + +/////////////////////////////////////////////////////////// +// TBrowse +/////////////////////////////////////////////////////////// + +// @class TList_sheet | Classe per la gestione dei list sheet +class TList_sheet : public TBrowse_button +// @author:(INTERNAL) Guido +{ + // @access:(INTERNAL) Private Memeber + + // @cmember:(INTERNAL) Numero di riga corrente dello sheet + int _row; + + // @cmember:(INTERNAL) Titolo dello sheet + TString _caption; + + // @cmember:(INTERNAL) Testate delle colonne dello sheet + TToken_string _head; + + // @cmember:(INTERNAL) Righe dello sheet + TString_array _data; + + // @cmember:(INTERNAL) Campi di input sulla maschera + TToken_string _inp_id; + + // @cmember:(INTERNAL) Campi di output sulla maschera + TToken_string _out_id; + + // @access Protected Member +protected: + // @cmember Ritorna il numero di riga selezionata + int do_input(); + // @cmember Scrive l'output della ricerca sulla maschera + void do_output(CheckTime = RUNNING_CHECK); + + // @cmember Controlla la sintassi della input del campo e ne setta i membri + void parse_input(TScanner& scanner); + // @cmember Controlla la sintassi della output del campo e ne setta i membri + void parse_output(TScanner& scanner); + + // @access Public Memeber +public: + // @cmember Legge dal file gli item dello sheet + void parse_item(TScanner& scanner); + + // @cmember Controlla la validita' del campo + virtual bool check(CheckTime = RUNNING_CHECK); + + // @cmember Esegue la ricerca. Torna il tasto che ha terminato la ricerca + virtual KEY run(); + + virtual bool is_sheet() const { return true; } + + TString_array& rows_array() { return _data; } + + // @cmember Costruttore + TList_sheet(TEdit_field* f, const char* caption, const char* head); + // @cmember Distruttore + virtual ~TList_sheet(); +}; + +// @doc INTERNAL + +// @class TBrowse | Classe per la definizione dei campi con ricerca +class TBrowse : public TBrowse_button +// @author:(INTERNAL) Guido +{ + // @access:(INTERNAL) Private Member + + // @cmember:(INTERNAL) Relazione della ricerca + TRelation* _relation; + // @cmember:(INTERNAL) Cursore sulla relazione + TCursor* _cursor; + // @cmember:(INTERNAL) Comando da eseguire alla pressione del tasto Gestione + TString _insert; + // @cmember:(INTERNAL) Filtro sul cursore + TString _filter; + // @cmember:(INTERNAL) Record selezionato + long _rec; + // @cmember:(INTERNAL) Indica se e' presente un campo secondario nella ricerca + bool _secondary; + // @cmember:(INTERNAL) Indica se sul campo e' gia' stato effettuato il check + bool _checked; + // @cmember:(INTERNAL) Chiave di ricerca alternativa (quando il testo del campo comincia con %) + TBrowse_button* _alt_browse; + + // @cmember:(INTERNAL) Testate della maschera di ricerca + TToken_string _head; + // @cmember:(INTERNAL) Campi visualizzati dalla maschera di ricerca + TToken_string _items; + // @cmember:(INTERNAL) Campi di input sulla maschera + TToken_string _inp_id; + // @cmember:(INTERNAL) Campi di input sul file + TToken_string _inp_fn; + // @cmember:(INTERNAL) Campi di output sulla maschera + TToken_string _out_id; + // @cmember:(INTERNAL) Campi di output sul file + TToken_string _out_fn; + // @cmember:(INTERNAL) handler di filtro custom + CONTROL_HANDLER _custom_filter_handler; + + // @access Protected Member +protected: + // @cmember Azzera i campi di output sulla maschera + void do_clear(CheckTime t); + // @cmember Chiama la maschera di gestione della ricerca + bool do_link(bool insert); + + // @cmember Modifica il cursore + void custom_cursor(); + + // @cmember Crea lista identificatori di ricerca + TToken_string& create_siblings(TToken_string& siblings) const; + + // @access Public Member +public: + // @cmember Modifica il display + void custom_display(); + + // @cmember Ritorna il numero di inputs senza contare quelli che funzionano + // solo da filtro + int input_fields(); + + // @cmember Ritorna la lista completa degli identificatori dei campi di input + const char* get_input_fields() const; + + // @cmember Ritorna la lista completa dei nomi dei campi di input + const char* get_input_field_names() const; + + // @cmember Aggiorna la lista completa degli identificatori dei campi di input + void set_input_fields(const char * inp_id) { _inp_id = inp_id;} + + // @cmember Aggiorna la lista completa degli identificatori dei campi di input da un campo + void copy_input(const TBrowse * b); + + // @cmember Aggiorna la lista completa dei nomi dei campi di input + void set_input_field_names(const char * inp_names) { _inp_fn = inp_names;} + + // @cmember Aggiunge un campo di input alla posizione + void add_input_field(const char * id, const char * name, const int pos = - 1, bool select = false); + +// @cmember Elimina un campo di display alla posizione + void remove_display_field(const int pos = -1); + + // @cmember Aggiorna la lista completa degli identificatori dei campi di output + void set_display_fields(const char * hds, const char * names) { _head = hds; _items = names;} + int get_display_fields(TToken_string& hds, TToken_string& names) const { hds =_head; names = _items; return names.items(); } + + // @cmember Aggiorna la display da un campo + void copy_display(const TBrowse * b); + + // @cmember Aggiunge un campo di diplay alla posizione + void add_display_field(const char * hd, const char * name, const int pos = -1); + +// @cmember Elimina un campo di input alla posizione + void remove_input_field(const int pos = -1); + + // @cmember Ritorna la lista completa dei campi di output + const char* get_output_fields() const; + + // @cmember Ritorna la lista completa dei nomi dei campi di output + const char* get_output_field_names() const; + + // @cmember Aggiorna la lista completa degli identificatori dei campi di output + void set_output_fields(const char * out_id) { _out_id = out_id;} + + // @cmember Aggiorna la lista completa dei nomi dei campi di input + void set_output_field_names(const char * out_names) { _out_fn = out_names;} + + // @cmember Aggiorna la lista completa degli identificatori dei campi di output da un campo + void copy_output(const TBrowse * b); + + // @cmember Aggiunge un campo di output alla posizione + void add_output_field(const char * id, const char * name, const int pos = -1); + + // @cmember Elimina un campo di output alla posizione + void remove_output_field(const int pos = -1); + + // @cmember Ritorna il numero di campi non vuoti e non filtrati + int do_input(bool filter = false); + + // @cmember Scrive l'output della ricerca sulla maschera + void do_output(CheckTime = RUNNING_CHECK); + + // @cmember Costruttore + TBrowse(TEdit_field* f, TRelation* r, int key = 1, const char* filter = ""); + // @cmember Costruttore + TBrowse(TEdit_field* f, TCursor* c); + // @cmember Distruttore + ~TBrowse(); + + // @cmember Controlla la sintassi della join del campo e ne setta i membri + void parse_join(TScanner& scanner); + // @cmember Controlla la sintassi della input del campo e ne setta i membri + void parse_input(TScanner& scanner); + // @cmember Controlla la sintassi della display del campo e ne setta i membri + void parse_display(TScanner& scanner); + // @cmember Controlla la sintassi della output del campo e ne setta i membri + void parse_output(TScanner& scanner); + // @cmember Controlla la sintassi della insert del campo e ne setta i membri + void parse_insert(TScanner& scanner); + // @cmember Controlla la sintassi della copy del campo e ne setta i membri + bool parse_copy(const TString& what, const TBrowse& b); + + // @cmember Permette di settare il comando alla pressione del tasto Gestione + void set_insert(const char* s) + { _insert = s;} + // @cmember Ritorna il valore di

+ const TString& get_insert() const + { return _insert;} + + // @cmember Ritorna il valore di

+ const TString& get_filter() const + { return _filter;} + + // @cmember Cambia il filtro della browse + void set_filter(const char * filter) + { _filter = filter;} + + // @cmember Cambia il cursore della browse + void set_cursor(TCursor * c); + + // @cmember Cambia il filtro della browse + void set_custom_filter_handler(CONTROL_HANDLER custom_filter_handler) { _custom_filter_handler = custom_filter_handler;} + + // @cmember Controlla la validita' del campo + bool check(CheckTime = RUNNING_CHECK); + // @cmember Controlla se il campo puo' essere vuoto + bool empty_check(); + // @cmember Ritorna il valore di

+ const TToken_string& head() const + { return _head;} + // @cmember Ritorna il valore di

+ const TToken_string& items() const + { return _items;} + // @cmember Ritorna il valore di

+ TCursor* cursor() const + { return _cursor;} + // @cmember Ritorna il valore di

+ bool checked() const + { return _checked;} + // @cmember Ritorna il valore di

+ bool secondary() const + { return _secondary;} + + bool set_alt_browse(int altkey); + + virtual bool is_browse() const { return true; } + + // @cmember Esegue la ricerca. Torna il tasto che ha terminato la ricerca + virtual KEY run(); +}; + +class TAlternative_browse : public TBrowse_button +{ + int _altkey; + TString16 _altfld, _outfld; + TCursor* _cursor; + + +protected: + virtual void parse_input(TScanner& scanner) {} + virtual void parse_output(TScanner& scanner) {} + virtual bool check(CheckTime = RUNNING_CHECK); + +public: + TCursor& cursor(); + virtual KEY run(); + TAlternative_browse(TEdit_field* ef, int altkey); + ~TAlternative_browse(); +}; + +class TFile_select : public TBrowse_button +{ + TFilename _filter; + +public: + // @cmember Controlla la sintassi della input del campo e ne setta i membri + virtual void parse_input(TScanner& scanner); + + // @cmember Controlla la sintassi della output del campo e ne setta i membri + virtual void parse_output(TScanner& scanner); + + virtual KEY run(); + + // @cmember Controlla la validita' del campo + virtual bool check(CheckTime = RUNNING_CHECK); + + virtual bool is_filesel() const { return true; } + + TFile_select(TEdit_field* ef, const char* filter); + virtual ~TFile_select() { } +}; + +class TDir_select : public TBrowse_button +{ +public: + // @cmember Controlla la sintassi della input del campo e ne setta i membri + virtual void parse_input(TScanner& scanner); + + // @cmember Controlla la sintassi della output del campo e ne setta i membri + virtual void parse_output(TScanner& scanner); + + virtual KEY run(); + + // @cmember Controlla la validita' del campo + virtual bool check(CheckTime = RUNNING_CHECK); + + virtual bool is_filesel() const { return TRUE; } + + TDir_select(TEdit_field* ef); + virtual ~TDir_select() { } +}; + +class TReport_select : public TBrowse_button +{ + TString _classe; + +public: + // @cmember Controlla la sintassi della input del campo e ne setta i membri + virtual void parse_input(TScanner& scanner); + + // @cmember Controlla la sintassi della output del campo e ne setta i membri + virtual void parse_output(TScanner& scanner); + + virtual KEY run(); + + // @cmember Controlla la validita' del campo + virtual bool check(CheckTime = RUNNING_CHECK); + + virtual bool is_filesel() const { return true; } + + TReport_select(TEdit_field* ef, const char* classe); + virtual ~TReport_select() { } +}; + + +class TProfile_select : public TBrowse_button +{ +protected: + // @cmember Controlla la sintassi della input del campo e ne setta i membri + virtual void parse_input(TScanner& scanner); + + // @cmember Controlla la sintassi della output del campo e ne setta i membri + virtual void parse_output(TScanner& scanner); + +public: + virtual KEY run(); + + // @cmember Controlla la validita' del campo + virtual bool check(CheckTime = RUNNING_CHECK); + + // @cmember E' un campo profilo + virtual bool is_profile() const { return true; } + + // @cmember Estrae dal .ini tutti i profili + int get_descriptions(TString_array& a) const; + + TProfile_select(TEdit_field* ef); + virtual ~TProfile_select() { } +}; + +#endif diff --git a/include/currency.cpp b/include/currency.cpp index 60d9d61b2..11c035528 100755 --- a/include/currency.cpp +++ b/include/currency.cpp @@ -20,22 +20,20 @@ class TDowJones : public TFile_cache int _dec_prices; // Decimali per i prezzi unitari int _dec_change; // Decimali per i cambi bool _is_euro; // E' l'EURO in persona - exchange_type _et; // Il cambio e' espresso contro EURO public: const TExchangeData& operator=(const TExchangeData& d) { _chg = d._chg; _dec = d._dec; _dec_prices = d._dec_prices; - _is_euro = d._is_euro; _et = d._et; + _is_euro = d._is_euro; return d; } TExchangeData() - : _chg(UNO), _dec(0), _dec_prices(0), _is_euro(false), _et(_exchange_base) { } + : _chg(UNO), _dec(0), _dec_prices(0), _is_euro(false) { } }; long _codditta; - TString4 _base_val, _firm_val, _euro_val; - real _euro_chg; + TString4 _firm_val, _euro_val; protected: virtual TObject* rec2obj(const TRectype& rec) const; @@ -44,24 +42,21 @@ protected: const TExchangeData& get(const char* key); public: - const TString& get_base_val(); const TString& get_firm_val(); const TString& get_euro_val(); void force_firm_val(const char* val); const char* expand_value(const char* val); - const char* normalize_value(const char* val, const real& chg, exchange_type& et); + const char* normalize_value(const char* val, const real& chg); real exchange(const real& num, - const char* fromval, const real& fromchg, exchange_type fromeuro, - const char* toval, const real& tochg, exchange_type toeuro, + const char* fromval, const real& fromchg, + const char* toval, const real& tochg, int price = 0); real exchange(const real& num, const TExchange& frval, const TExchange& toval, int price = 0); int get_dec(const char* val, bool prices = FALSE); - const real& get_change(const char* val, exchange_type& contro_euro); - real get_base_change(const char* val); - real get_contro_change(const char* val); + const real& get_change(const char* val); virtual void flush(); @@ -92,7 +87,7 @@ TObject* TDowJones::rec2obj(const TRectype& rec) const } } - if (codval.not_empty()) + if (codval.full()) { data->_dec = rec.get_int("I0"); data->_dec_prices = rec.get_int("I1"); @@ -100,7 +95,6 @@ TObject* TDowJones::rec2obj(const TRectype& rec) const data->_dec_prices = data->_dec; data->_dec_change = rec.get_int("I2"); data->_is_euro = rec.get_bool("B0"); - data->_et = rec.get_bool("B1") ? _exchange_contro : _exchange_base; } return data; @@ -108,7 +102,6 @@ TObject* TDowJones::rec2obj(const TRectype& rec) const void TDowJones::flush() { - _base_val.cut(0); _firm_val.cut(0); _euro_val.cut(0); kill_file(); @@ -124,14 +117,12 @@ void TDowJones::test_cache() _firm_val = prefix().firm().codice_valuta(); } - if (_base_val.empty()) + if (_euro_val.empty()) { fill(); FOR_EACH_ASSOC_OBJECT(_cache, hash, key, obj) if (*key) { const TExchangeData& data = *(const TExchangeData*)obj; - if ((_base_val.empty() || strcmp(key, "LIT") == 0) && data._chg == UNO) - _base_val = key; if (data._is_euro && _euro_val.empty()) _euro_val = key; } @@ -139,22 +130,13 @@ void TDowJones::test_cache() if (_euro_val.empty()) // Si son dimenticati dell'EURO? { TExchangeData* euro = new TExchangeData; - euro->_chg = 1936.27; euro->_dec = euro->_dec_prices = 2; - euro->_is_euro = TRUE; euro->_et = _exchange_base; + euro->_chg = UNO; euro->_dec = euro->_dec_prices = 2; + euro->_is_euro = true; _euro_val = "EUR"; _cache.add(_euro_val, euro); } - if (_base_val.empty()) // Si son dimenticati delle LIRE? - { - TExchangeData* lira = new TExchangeData; - lira->_chg = UNO; lira->_dec = lira->_dec_prices = 0; - lira->_is_euro = FALSE; lira->_et = _exchange_base; - _base_val = "LIT"; - _cache.add(_base_val, lira); - } _firm_val = prefix().firm().codice_valuta(); - _euro_chg = get_base_change(_euro_val); } } @@ -167,9 +149,7 @@ const char* TDowJones::expand_value(const char* val) if (xvt_str_compare_ignoring_case(val, "_FIRM") == 0) val = get_firm_val(); else if (xvt_str_compare_ignoring_case(val, "_EURO") == 0) - val = get_euro_val(); else - if (xvt_str_compare_ignoring_case(val, "_BASE") == 0) - val = get_base_val(); + val = get_euro_val(); } else { @@ -188,12 +168,6 @@ const TDowJones::TExchangeData& TDowJones::get(const char* val) return (const TExchangeData&)query(expand_value(val)); } -const TString& TDowJones::get_base_val() -{ - test_cache(); - return _base_val; -} - const TString& TDowJones::get_firm_val() { test_cache(); @@ -215,10 +189,8 @@ void TDowJones::force_firm_val(const char* val) real TDowJones::exchange(const real& num, // Importo da convertire const char* frval, // Dalla valuta const real& frchg, // Dal cambio - exchange_type freur, // Dal cambio in euro const char* toval, // Alla valuta const real& tochg, // Al cambio - exchange_type toeur, // Al cambio in euro int price) // e' un prezzo ? { real n = num; @@ -228,27 +200,12 @@ real TDowJones::exchange(const real& num, // Importo da convertire const TExchangeData& datato = get(toval); real fr = frchg; - if (fr <= ZERO) { fr = datafr._chg; freur = datafr._et; } + if (fr <= ZERO) fr = datafr._chg; real to = tochg; - if (to <= ZERO) { to = datato._chg; toeur = datato._et; } + if (to <= ZERO) to = datato._chg; - const int mode = (freur == _exchange_contro ? 1 : 0) + (toeur == _exchange_contro ? 2 : 0); - switch (mode) - { - case 1: - n = (n * _euro_chg) / (fr * to); // Modo misto 1 - break; - case 2: - n = n * (fr * to) / _euro_chg; // Modo misto 2 - break; - case 3: - n = n * to / fr; // Nuovo modo - break; - default: - n = n * fr / to; // Vecchio modo - break; - } + n = n * to / fr; // Nuovo modo if (price == 0 || price == 1) // Arrotonda solo in caso normale n.round(price ? datato._dec_prices : datato._dec); } @@ -260,10 +217,9 @@ real TDowJones::exchange(const real& num, // Importo da convertire const TExchange& toval, // Alla valuta int price) // e' un prezzo ? { - exchange_type fret, toet; - const real& frch = frval.get_change(fret); - const real& toch = toval.get_change(toet); - return exchange(num, frval.get_value(), frch, fret, toval.get_value(), toch, toet, price); + const real& frch = frval.get_change(); + const real& toch = toval.get_change(); + return exchange(num, frval.get_value(), frch, toval.get_value(), toch, price); } int TDowJones::get_dec(const char* val, bool price) @@ -272,56 +228,15 @@ int TDowJones::get_dec(const char* val, bool price) return price ? data._dec_prices : data._dec; } -const real& TDowJones::get_change(const char* val, exchange_type& et) +const real& TDowJones::get_change(const char* val) { const TExchangeData& data = get(val); - et = data._et; return data._chg; } -real TDowJones::get_base_change(const char* val) +const char* TDowJones::normalize_value(const char* val, const real& /*exch*/) { - exchange_type et; - real c = get_change(val, et); - if (et == _exchange_contro) - { - c = _euro_chg / c; - c.round(6); - } - return c; -} - -real TDowJones::get_contro_change(const char* val) -{ - exchange_type et; - real c = get_change(val, et); - if (et == _exchange_base) - { - c = _euro_chg / c; - c.round(6); - } - return c; -} - -const char* TDowJones::normalize_value(const char* val, const real& exch, exchange_type& et) -{ - val = expand_value(val); - if (et == _exchange_undefined) - { - if (exch > ZERO) - { - real base_diff = get_base_change(val) - exch; - base_diff = abs(base_diff); - - real contro_diff = get_contro_change(val) - exch; - contro_diff = abs(contro_diff); - - et = base_diff < contro_diff ? _exchange_base : _exchange_contro; - } - else - get_change(val, et); - } - return val; + return expand_value(val); } /////////////////////////////////////////////////////////// @@ -332,60 +247,23 @@ void TExchange::copy(const TExchange& exc) { strcpy(_val, exc._val); _exchange = exc._exchange; - _et = exc._et; } -const real& TExchange::get_change(exchange_type& et) const +const real& TExchange::get_change() const { if (_exchange.is_zero()) - return DowJones.get_change(_val, et); - et = _et; + return DowJones.get_change(_val); return _exchange; } -real TExchange::get_base_change() const -{ - exchange_type et; - real c = get_change(et); - if (et != _exchange_base) - { - c = DowJones.get_base_change("_EURO") / c; - c.round(6); - } - return c; -} - -real TExchange::get_contro_change() const -{ - exchange_type et; - real c = get_change(et); - if (et != _exchange_contro) - { - c = DowJones.get_base_change("_EURO") / c; - c.round(6); - } - return c; -} - int TExchange::compare(const TSortable& obj) const { const TExchange& exc = (const TExchange&)obj; int cmp = strcmp(_val, exc._val); if (cmp == 0) { - if (_et == exc._et) - { - exchange_type dummy; - const real diff = get_change(dummy) - exc.get_change(dummy); - cmp = diff.sign(); - } - else - { - real chg1 = get_contro_change(); - real chg2 = exc.get_contro_change(); - const real diff = chg1 - chg2; - cmp = diff.sign(); - } + const real diff = get_change() - exc.get_change(); + cmp = diff.sign(); } return cmp; } @@ -410,28 +288,24 @@ int TExchange::decimals(bool price) const return DowJones.get_dec(_val, price); } -void TExchange::set(const char* val, const real& chg, exchange_type et) +void TExchange::set(const char* val, const real& chg) { - val = DowJones.normalize_value(val, chg, et); + val = DowJones.normalize_value(val, chg); strncpy(_val, val, 4); _val[3] = '\0'; _exchange = chg; - _et = et; } void TExchange::set(const TRectype& rec) { const TString4 codval = rec.get("CODVAL"); const real chg = rec.get_real("CAMBIO"); - exchange_type et = _exchange_undefined; - if (rec.exist("CONTROEURO")) - et = rec.get_bool("CONTROEURO") ? _exchange_contro : _exchange_base; - set(codval, chg, et); + set(codval, chg); } -TExchange::TExchange(const char* val, const real& chg, exchange_type et) +TExchange::TExchange(const char* val, const real& chg) { - set(val, chg, et); + set(val, chg); } TExchange::TExchange(const TRectype& rec) @@ -443,11 +317,6 @@ TExchange::TExchange(const TRectype& rec) // TCurrency /////////////////////////////////////////////////////////// -const TString& TCurrency::get_base_val() -{ - return DowJones.get_base_val(); -} - const TString& TCurrency::get_firm_val() { return DowJones.get_firm_val(); @@ -458,11 +327,6 @@ const TString& TCurrency::get_euro_val() return DowJones.get_euro_val(); } -int TCurrency::get_base_dec(bool price) -{ - return DowJones.get_dec(NULL, price); -} - int TCurrency::get_firm_dec(bool price) { return DowJones.get_dec(get_firm_val(), price); @@ -473,17 +337,7 @@ int TCurrency::get_euro_dec(bool price) return DowJones.get_dec(get_euro_val(), price); } -const real& TCurrency::get_firm_change(exchange_type& ce) -{ - return DowJones.get_change("_FIRM", ce); -} -const real& TCurrency::get_euro_change() -{ - exchange_type dummy; - return DowJones.get_change("_EURO", dummy); -} - void TCurrency::force_firm_val(const char* val) { DowJones.force_firm_val(val); @@ -494,9 +348,9 @@ void TCurrency::force_cache_update() DowJones.flush(); } -void TCurrency::force_value(const char* newval, const real& newchange, exchange_type newet) +void TCurrency::force_value(const char* newval, const real& newchange) { - _chg.set(newval, newchange, newet); + _chg.set(newval, newchange); } void TCurrency::change_value(const TExchange& exc) @@ -506,9 +360,9 @@ void TCurrency::change_value(const TExchange& exc) _chg = exc; } -void TCurrency::change_value(const char* val, const real& newchange, exchange_type to_euro) +void TCurrency::change_value(const char* val, const real& newchange) { - const TExchange exc(val, newchange, to_euro); + const TExchange exc(val, newchange); change_value(exc); } @@ -616,20 +470,15 @@ TCurrency TCurrency::abs() const return *this; } -bool TCurrency::is_base_value() const -{ - return get_base_val() == get_value(); -} - bool TCurrency::is_firm_value() const { return _chg.is_firm_value(); } -TCurrency::TCurrency(const real& num, const char* val, const real& exchg, exchange_type et, bool price) +TCurrency::TCurrency(const real& num, const char* val, const real& exchg, bool price) : _num(num), _price(price) { - force_value(val, exchg, et); + force_value(val, exchg); _num.round(decimals()); } @@ -651,9 +500,9 @@ bool same_values(const char * valuea, const char * valueb) real change_currency(const real& num, - const char* fromval, const real& fromchg, exchange_type fromeuro, - const char* toval, const real& tochg, exchange_type toeuro, + const char* fromval, const real& fromchg, + const char* toval, const real& tochg, int price) { - return DowJones.exchange(num, fromval, fromchg, fromeuro, toval, tochg, toeuro, price); + return DowJones.exchange(num, fromval, fromchg, toval, tochg, price); } diff --git a/include/currency.h b/include/currency.h index 4aada452d..a80b3ad2c 100755 --- a/include/currency.h +++ b/include/currency.h @@ -14,13 +14,10 @@ class TRectype; #endif -enum exchange_type { _exchange_base, _exchange_contro, _exchange_undefined }; - class TExchange : public TSortable { char _val[4]; // Codice valuta real _exchange; // Cambio personalizzato - exchange_type _et;// Cambio normale o contro euro protected: void copy(const TExchange& exc); @@ -32,20 +29,17 @@ public: TExchange& operator=(const TExchange& exc) { copy(exc); return *this; } TExchange& operator=(const TRectype& rec) { set(rec); return *this; } - void set(const char* val = NULL, const real& exc = ZERO, exchange_type et = _exchange_undefined); + void set(const char* val = NULL, const real& exc = ZERO); void set(const TRectype& rec); - exchange_type get_type() const { return _et; } bool is_firm_value() const; bool is_euro_value() const; const char* get_value() const { return _val; } - const real& get_change(exchange_type& et) const; - real get_base_change() const; - real get_contro_change() const; + const real& get_change() const; int decimals(bool price = false) const; - TExchange(const char* val = NULL, const real& exc = ZERO, exchange_type et = _exchange_undefined); + TExchange(const char* val = NULL, const real& exc = ZERO); TExchange(const TExchange& exc) { copy(exc); } TExchange(const TRectype& rec); virtual ~TExchange() { } @@ -63,14 +57,14 @@ protected: TCurrency(bool price) : _price(price) { } // Internal use only public: - static const TString& get_base_val(); + //static const TString& get_base_val(); static const TString& get_firm_val(); static const TString& get_euro_val(); - static int get_base_dec(bool price = false); + //static int get_base_dec(bool price = false); static int get_firm_dec(bool price = false); static int get_euro_dec(bool price = false); - static const real& get_firm_change(exchange_type& ce); - static const real& get_euro_change(); + //static const real& get_firm_change(exchange_type& ce); + //static const real& get_euro_change(); // serve per la personalizzazione cgp4, per stampare il bilancio in euro static void force_firm_val(const char* val); @@ -79,15 +73,15 @@ public: void set_price(bool p) { _price = p; } bool is_price() const { return _price; } - void force_value(const char* newval, const real& newchange = ZERO, exchange_type et = _exchange_undefined); + void force_value(const char* newval, const real& newchange = ZERO); void change_value(const TExchange& exc); - void change_value(const char* newval, const real& newchange = ZERO, exchange_type et = _exchange_undefined); - void change_to_base_val() { change_value(get_base_val()); } + void change_value(const char* newval, const real& newchange = ZERO); + //void change_to_base_val() { change_value(get_base_val()); } void change_to_firm_val() { change_value(get_firm_val()); } void change_to_euro_val() { change_value(get_euro_val()); } const char* get_value() const { return _chg.get_value(); } - bool is_base_value() const; + //bool is_base_value() const; bool is_firm_value() const; bool same_value_as(const TCurrency& cur) const { return _chg.same_value_as(cur._chg); } @@ -97,9 +91,10 @@ public: void set_exchange(const TExchange& exc) { _chg = exc; } const TExchange& get_exchange() const { return _chg; } - const real& get_change(exchange_type& et) const { return _chg.get_change(et); } - real get_base_change() const { return _chg.get_base_change(); } - real get_contro_change() const { return _chg.get_contro_change(); } + //const real& get_change(exchange_type& et) const { return _chg.get_change(et); } + //real get_base_change() const { return _chg.get_base_change(); } + //real get_contro_change() const { return _chg.get_contro_change(); } + const real& get_change() const { return _chg.get_change(); } const TCurrency& operator=(const TCurrency& cur) { copy(cur); return *this; } @@ -123,7 +118,8 @@ public: TCurrency() : _price(false) {} TCurrency(const TCurrency& cur) { copy(cur); } - TCurrency(const real& num, const char* val = "", const real& exchg = ZERO, exchange_type et = _exchange_undefined, bool price = false); + //TCurrency(const real& num, const char* val = "", const real& exchg = ZERO, exchange_type et = _exchange_undefined, bool price = false); + TCurrency(const real& num, const char* val = "", const real& exchg = ZERO, bool price = false); TCurrency(const real& num, const TExchange& chg, bool price = false); virtual ~TCurrency() { } }; @@ -135,8 +131,8 @@ public: TPrice() : TCurrency(true) { } TPrice(const TPrice& price) { copy(price); } - TPrice(const real& num, const char* val = "", const real& exc = ZERO, exchange_type ext = _exchange_undefined) - : TCurrency(num, val, exc, ext, true) { } + TPrice(const real& num, const char* val = "", const real& exc = ZERO) + : TCurrency(num, val, exc) { set_price(true); } virtual ~TPrice() { } }; @@ -147,8 +143,8 @@ bool same_values(const char * valuea, const char * valueb); // Funzione di levello super-basso: usate solo se sapete bene cosa state facendo real change_currency(const real& num, - const char* fromval, const real& fromchg, exchange_type fromeuro, - const char* toval, const real& tochg, exchange_type toeuro = _exchange_undefined, + const char* fromval, const real& fromchg, + const char* toval, const real& tochg, int price_round = 0); #endif diff --git a/include/dongle.cpp b/include/dongle.cpp index 1e1a69f7b..cfd2852e7 100755 --- a/include/dongle.cpp +++ b/include/dongle.cpp @@ -124,11 +124,11 @@ void TDongle::garble(word* data) const case _dongle_eutron: xvt_dongle_sl_crypt(data); break; - case _dongle_aladdin: - // xvt_dongle_al_crypt(data); - break; - default: + case _dongle_ssa: + xvt_dongle_sa_crypt(data); // Reversible XOR encryption break; + default: + break; } } @@ -303,9 +303,9 @@ bool TDongle::eutron_login(bool test_all_keys) { bool ok = false; - const char* labels[3] = { "AGA.INFORMATICA", "AGA.CAMPO", "25EBAI" }; - TDongleType types[3] = { _aga_dongle, _user_dongle, _developer_dongle }; - for (int k = test_all_keys ? 0 : 1; k < 3; k++) + const char* labels[2] = { "AGA.CAMPO", "25EBAI" }; + TDongleType types[2] = { _user_dongle, _developer_dongle }; + for (int k = test_all_keys ? 0 : 1; k < 2; k++) { const unsigned char* pwd = (const unsigned char*)::encode(labels[k]); ok = xvt_dongle_sl_login((const unsigned char*)labels[k], pwd) != 0; @@ -365,13 +365,50 @@ bool TDongle::eutron_login(bool test_all_keys) _module.set(0, true); // Forza l'attivazione della base } else - set_developer_permissions(); + set_developer_permissions(); } return ok; } -bool TDongle::aladdin_login(bool test_all_dongles) -{ return false; } +bool TDongle::ssa_login(const char* mod) +{ + if (mod && *mod) + { + return xvt_dongle_sa_login(mod) == 0; + } + + _max_users = 1; + _last_update = TDate(TODAY); + _year_assist = _last_update.year(); + + _module.reset(); // Disattiva tutti i moduli + _module.set(0L); // Attiva la base + + const int err = xvt_dongle_sa_login(NULL); + _serno = (err >= 0) ? err : 0xFFFF; + if (_serno != 0xFFFF) + { + _hardware =_dongle_ssa; + _type = _serno ? _user_dongle : _developer_dongle; + if (_serno) + { + Tdninst dn; + if (dn.find_serno()) + _year_assist = dn.assist_year(); + else + _year_assist = 2121; + for (word m = BAAUT; m < ENDAUT; m++) + { + const TString& name = module_code2name(m); + if (xvt_dongle_sa_test(name) == 0) + _module.set(m); + } + } + else + set_developer_permissions(); + } + return _serno != 0xFFFF; +} bool TDongle::network_login(bool test_all_keys) { @@ -446,7 +483,7 @@ bool TDongle::login(bool test_all_keys) case _dongle_hardlock: ok = hardlock_login(test_all_keys); break; case _dongle_eutron : ok = eutron_login(test_all_keys); break; case _dongle_network : ok = network_login(test_all_keys); break; - case _dongle_aladdin : ok = aladdin_login(test_all_keys); break; + case _dongle_ssa : ok = ssa_login(NULL); break; default : ok = false; break; } if (!ok) @@ -459,8 +496,8 @@ bool TDongle::login(bool test_all_keys) ok = eutron_login(test_all_keys); if (!ok && hw != _dongle_hardlock) ok = hardlock_login(test_all_keys); - if (!ok && hw != _dongle_aladdin) - ok = aladdin_login(test_all_keys); + if (!ok && hw != _dongle_ssa) + ok = ssa_login(NULL); } if (ok) @@ -469,7 +506,7 @@ bool TDongle::login(bool test_all_keys) { // DEMO _hardware = _dongle_unknown; _type = _no_dongle; - _serno = 0xFFFF; //numero di serie più alto possibile (65535 in exadecimals: non sarà mai raggiunto da chiavi clienti...magari!) + _serno = 0xFFFF; //numero di serie più alto possibile (65535 in esadecimale: non sarà mai raggiunto da chiavi clienti...magari!) _max_users = 1; _last_update = TDate(TODAY); _year_assist = 3000; // anno di assistenza a 3000 per non avere problemi con le versioni nei vari anni @@ -482,6 +519,15 @@ bool TDongle::login(bool test_all_keys) return ok; } +bool TDongle::login(const char* module) +{ + const word code = module_name2code(module); + bool ok = active(code); + if (ok && _hardware == _dongle_ssa) + ok = ssa_login(module); + return ok; +} + bool TDongle::logout() { switch (_hardware) @@ -495,8 +541,8 @@ bool TDongle::logout() case _dongle_network: rpc_UserLogout(main_app().name()); break; - case _dongle_aladdin: - // xvt_dongle_al_logout(); + case _dongle_ssa: + xvt_dongle_sa_logout(NULL); break; default: break; @@ -643,12 +689,11 @@ int TDongle::oem() const if (campo.blank()) campo = "Campo Enterprise"; if (firm.blank()) - firm = "AGA informatica s.r.l."; + firm = "Sirio Informatica e Sistemi s.p.a."; if (breve.blank()) breve = "Campo"; - if (oem < 0) - oem = firm.starts_with("AGA ") ? 0 : 1; + if (oem < 0) oem = 1; } return _OEM; } @@ -798,11 +843,6 @@ bool TDongle::burn_eutron() return ok; } -bool TDongle::burn_aladdin() -{ - return false; -} - bool TDongle::burn() { bool ok = local() && _type == _user_dongle; @@ -811,10 +851,9 @@ bool TDongle::burn() { switch(_hardware) { - case _dongle_hardlock: ok = burn_hardlock(); break; - case _dongle_eutron : ok = burn_eutron(); break; - case _dongle_aladdin : ok = burn_aladdin(); break; - default : break; + case _dongle_hardlock: ok = burn_hardlock(); break; + case _dongle_eutron : ok = burn_eutron(); break; + default : ok = false; break; } } @@ -1258,7 +1297,6 @@ bool Tdninst::find_serno() const { if (em.year_assist() > 2100) { - TToken_string l(80, '='); good = em.find_serno(serno); } else diff --git a/include/dongle.h b/include/dongle.h index 29068bf9b..25a5ef1eb 100755 --- a/include/dongle.h +++ b/include/dongle.h @@ -13,7 +13,7 @@ #include #endif -enum TDongleHardware { _dongle_unknown, _dongle_hardlock, _dongle_eutron, _dongle_network, _dongle_aladdin }; +enum TDongleHardware { _dongle_unknown, _dongle_hardlock, _dongle_eutron, _dongle_network, _dongle_ssa }; enum TDongleType { _no_dongle, _user_dongle, _developer_dongle, _aga_dongle }; class TDongle : public TObject @@ -39,11 +39,13 @@ protected: bool hardlock_login(bool test_all_dongles); bool eutron_login(bool test_all_dongles); bool network_login(bool test_all_dongles); - bool aladdin_login(bool test_all_dongles); + + bool ssa_login(const char* mod); + bool ssa_test_module(const char* mod); + bool ssa_logout(); bool burn_hardlock(); bool burn_eutron(); - bool burn_aladdin(); int can_try_server() const; const TString_array& info() const; // Array di coppie modulo|descrizione @@ -54,6 +56,7 @@ public: // TObject public: bool login(bool test_all_dongles = false); + bool login(const char* module); bool logout(); word number() const { return _serno; } diff --git a/include/form.cpp b/include/form.cpp index 8166e6619..e8f863d96 100755 --- a/include/form.cpp +++ b/include/form.cpp @@ -1464,7 +1464,7 @@ TCurrency TForm_currency::get_currency() const { const char * codval = _driver ? _driver->get() : (const char *) form().get_curr_codval(); const real n(get()); - return TCurrency(n, codval, ZERO, _exchange_undefined, _flag.price != 0); + return TCurrency(n, codval, ZERO, _flag.price != 0); } bool TForm_currency::update() @@ -1555,7 +1555,7 @@ bool TForm_currency::update() int d = 0; if (_driver) { - const TCurrency z(ZERO, _driver->get(), ZERO, _exchange_base, _flag.price != 0); + const TCurrency z(ZERO, _driver->get(), ZERO, _flag.price != 0); d = z.decimals(); } else @@ -4743,11 +4743,11 @@ int TForm::matches_done(int file) return 0; } -void TForm::set_output_exchange(const char* codval, real exchange, exchange_type et) +void TForm::set_output_exchange(const char* codval, real exchange) { if (_exchange == NULL) _exchange = new TExchange; - _exchange->set(codval, exchange, et); + _exchange->set(codval, exchange); } TForm::TForm() diff --git a/include/form.h b/include/form.h index 4ff3ca06e..50f34c74f 100755 --- a/include/form.h +++ b/include/form.h @@ -336,7 +336,7 @@ public: const bool magic_currency() const { return _magic_currency; } - void set_output_exchange(const char* codval, real exchange = ZERO, exchange_type et = _exchange_undefined); + void set_output_exchange(const char* codval, real exchange = ZERO); const TExchange* output_exchange() const { return _exchange; } void enable_message_add(bool on) { _msg_add_enabled = on; } diff --git a/include/golem.cpp b/include/golem.cpp index a260a9f02..745ee6e4b 100755 --- a/include/golem.cpp +++ b/include/golem.cpp @@ -972,11 +972,11 @@ bool TMail_message::send(TMAPI_session& lhSession, bool hide_ui) int i; for (i = 0; i < items(); i++) tot += row(i).len(); - char * buffer = new char[tot + 1]; + char* buffer = new char[tot + 16]; long b = 0; for (i = 0; i < items(); i++) { - strcpy(&buffer[b], row(i)); + strcpy_s(&buffer[b], tot-b+1, row(i)); b += row(i).len(); } buffer[b] = '\0'; @@ -1065,7 +1065,7 @@ void TMail_message::set_date_time(const char* str) int anno, mese, giorno; int ora = 12, minuto = 0, secondo = 0; - const int num = sscanf(str, "%d/%d/%d %d:%d:%d", + const int num = sscanf_s(str, "%d/%d/%d %d:%d:%d", &anno, &mese, &giorno, &ora, &minuto, &secondo); if (num >= 3) { diff --git a/include/maskfld.cpp b/include/maskfld.cpp index 3051b452f..a31d65783 100755 --- a/include/maskfld.cpp +++ b/include/maskfld.cpp @@ -8,9 +8,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -19,7 +17,6 @@ #include #include -#include "../mg/anamag.h" #include // @doc INTERNAL @@ -2002,1535 +1999,6 @@ void TCheckbutton_field::create(WINDOW parent) TCheckbutton_field::TCheckbutton_field(TMask* mask) : TBoolean_field(mask) { } -/////////////////////////////////////////////////////////// -// TBrowse_button -/////////////////////////////////////////////////////////// - -TBrowse_button::TBrowse_button(TEdit_field* f) - : _fld(f) -{ } - -TBrowse_button::~TBrowse_button() -{ -} - -// Certified 100% -TEditable_field& TBrowse_button::field(short id) const -{ - if (id > 0) - { - TMask_field& f = _fld->mask().field(id); - CHECKD(f.is_editable(), "Can't use in a browse the field ", id); - return (TEditable_field&)f; - } - return *_fld; -} - -/////////////////////////////////////////////////////////// -// TList_sheet -/////////////////////////////////////////////////////////// - -// Certified 100% -TList_sheet::TList_sheet(TEdit_field* f, const char* caption, const char* head) - : TBrowse_button(f), _row(-1), _caption(caption), _head(head) -{ } - -// Certified 100% -TList_sheet::~TList_sheet() -{ } - - -// Certified 100% -void TList_sheet::parse_input(TScanner& scanner) -{ - _inp_id.add(scanner.pop()); -} - -// Certified 100% -void TList_sheet::parse_item(TScanner& scanner) -{ - _data.add(new TToken_string(scanner.string())); -} - -// Certified 100% -void TList_sheet::parse_output(TScanner& scanner) -{ - _out_id.add(scanner.pop()); -} - -// il numero di riga selezionata -int TList_sheet::do_input() -{ - if (_inp_id.empty_items()) - return -2; // List empty! - - _inp_id.restart(); - TToken_string rowsel(80); - - for (const char* fld = _inp_id.get(); fld; fld = _inp_id.get()) - { - if (*fld == '"') - { - rowsel.add(fld+1); - if (rowsel.not_empty()) rowsel.cut(rowsel.len()-1); - } - else - { - const short id = field().atodlg(fld); - if (id > 0) - { - const TMask_field& f = field(id); - if (f.class_id() == CLASS_ZOOM_FIELD) - { - const TZoom_field& z = (TZoom_field&)f; - rowsel.add(z.get_first_line()); - } - else - rowsel.add(f.get()); - } - else rowsel.add(""); - } - } - - TString fd, it; - for (int i = 0 ; i < _data.items(); i++) - { - TToken_string& ts =_data.row(i); - - ts.restart(); - const char * item; - for (item = rowsel.get(0); item ; item = rowsel.get()) - { - it = item; it.trim(); - fd = ts.get(); fd.trim(); - if (fd != it) break; - } - if (!item) return i; - } - - return -1; // Value not found! -} - - -// Certified 50% -void TList_sheet::do_output(CheckTime t) -{ - if (_row < 0 || t == FINAL_CHECK) - return; - - _out_id.restart(); - TToken_string& rowsel = _data.row(_row); - rowsel.restart(); - for (const char* fld = _out_id.get(); fld; fld = _out_id.get()) - { - const short id = field().atodlg(fld); - TMask_field& f = field(id); - const char* val = rowsel.get(); - if (t != STARTING_CHECK || f.field() == NULL) - { - const bool hit = f.get() != val; - f.set(val); - if (hit && field().dlg() != id) - { - f.on_hit(); - if (t == RUNNING_CHECK) - f.check(); - } - } - } -} - - -// Certified 100% -KEY TList_sheet::run() -{ - TArray_sheet sci(3, 3, -3, -3, _caption, _head); - sci.rows_array() = _data; - - _row = do_input(); - sci.select(_row); - const KEY k = sci.run(); - - switch (k) - { - case K_ENTER: - _row = (int)sci.selected(); - do_output(); - break; - default: - break; - } - - return k; -} - - -// Certified 100% -bool TList_sheet::check(CheckTime t) -{ - _row = do_input(); - bool passed = _row != -1; - if (passed) - do_output(t); - else - { - switch(field().check_type()) - { - case CHECK_SEARCH: passed = true; break; - default: break; - } - } - return passed; -} - - -/////////////////////////////////////////////////////////// -// TBrowse -/////////////////////////////////////////////////////////// - -// Certified 100% -TBrowse::TBrowse(TEdit_field* f, TRelation* r, int key, const char* filter) - : TBrowse_button(f), - _relation(r), _cursor(new TCursor (r, "", key)), - _filter(filter), _secondary(false), - _custom_filter_handler(NULL) -{ - custom_cursor(); -} - - -// Certified 100% -TBrowse::TBrowse(TEdit_field* f, TCursor* c) - : TBrowse_button(f), - _relation(NULL), _cursor(c), _secondary(false), - _custom_filter_handler(NULL) -{ - custom_cursor(); -} - - -// Certified 100% -TBrowse::~TBrowse() -{ - // Se e' stato usato il primo costruttore devo distruggere la relazione ed il cursore - if (_relation) - { - delete _cursor; - delete _relation; - } -} - -static bool descr_filter_handler(TMask_field& f, KEY k) -{ - if (k == K_SPACE) - { - TString expr; - if (!f.get().empty()) // Filtro attivato! - { - const short id = f.dlg()-500; - TString e = f.mask().get(id); // Espressione regolare - e.strip("\"'"); // Tolgo caratteri che potrebbero dare problemi - if (!e.blank()) - expr << "(DESCR+DESCRAGG)" << "?=\"" << e << '"'; - if (expr.empty()) - f.reset(); - } - ((TBrowse_sheet&) f.mask()).add_custom_filter(expr); - } - return true; -} - -void TBrowse::custom_cursor() -{ - TRelation * relation = _relation == NULL ? _cursor->relation() : _relation; - int logicnum = relation->lfile().num(); - - switch(logicnum) - { - case LF_ANAMAG : - if (_cursor->key() == 2 && ini_get_bool(CONFIG_DITTA, "Main", "CUSTOM_SEARCH_" TOSTRING(LF_ANAMAG), false, 2)) - { - delete _cursor; - _cursor = new TSorted_cursor(relation, ANAMAG_DESCR "|" ANAMAG_DESCRAGG "[1,50]", "", 2); - set_custom_filter_handler(descr_filter_handler); - } - break; - default: - break; - } -} - -void TBrowse::custom_display() -{ - switch(_cursor->file().num()) - { - case LF_ANAMAG: - if (_cursor->key() == 2 && ini_get_bool(CONFIG_DITTA, "Main", "CUSTOM_SEARCH_" TOSTRING(LF_ANAMAG), false, 2)) - { - TToken_string & it = (TToken_string &) items(); - if (it.find(ANAMAG_DESCRAGG) < 0) - { - const char * s = it.get(0); - for (int i = 0; s && *s; s = it.get(++i)) - if (strcmp(s, ANAMAG_DESCR) == 0) - { - add_display_field("Descrizione aggiuntiva@50", ANAMAG_DESCRAGG, i + 1); - break; - } - } - } - break; - case LF_TABMOD: - { - _cursor->file().zero(); // Azzera il record corrente in modo da impostare "MOD" - const TString& mod =_cursor->curr().get("MOD"); - const word cod = dongle().module_name2code(mod); - field().set_module(cod); - } - break; - default: - break; - } -} - -// Certified 100% -void TBrowse::parse_display(TScanner& scanner) -{ - const char* s = scanner.string(); - _head.add(dictionary_translate_header(s)); - s = scanner.line(); - _items.add(s); -} - - -void TBrowse::parse_input(TScanner& scanner) -{ - const char* s = scanner.pop(); - _inp_fn.add(s); - - s = scanner.pop(); - if (*s == '"') // Constant string - { - scanner.push(); - TString& str = scanner.line(); - _inp_id.add(str); - } - else // Field on the mask - { - CHECKS(_inp_id.get_pos(s) < 0, "Duplicate input field ", s); - _inp_id.add(s); - if (scanner.popkey() == "SE") - _inp_id << '@'; // Special FILTERing field - else - scanner.push(); - } -} - - -void TBrowse::parse_output(TScanner& scanner) -{ - const char* s = scanner.pop(); -#ifdef DBG - field().atodlg(s); -#endif - _out_id.add(s); - s = scanner.pop(); - _out_fn.add(s); - _secondary = false; -} - - -bool TBrowse::parse_copy(const TString& what, const TBrowse& b) -{ - const bool all = what == "AL"; - if (all || what == "US") - { - set_insert(b.get_insert()); - _filter = b.get_filter(); - if (!field().has_warning() && b.field().has_warning()) - field().set_warning(b.field().get_warning()); - if (!all) return true; - } - if (all || what == "IN") - { - _inp_id = b._inp_id; - _inp_fn = b._inp_fn; - if (!all) return true; - } - if (all || what == "DI") - { - _head = b._head; - _items = b._items; - if (!all) return true; - } - if (all || what == "OU") - { - _out_id = b._out_id; - _out_fn = b._out_fn; - _secondary = b.field().has_check(); - } - return true; -} - - -void TBrowse::parse_join(TScanner& scanner) -{ - TString80 j(scanner.pop()); // File or table - - CHECKS(_relation, "Can't join to NULL relation ", (const char*)j); - - int to; - if (scanner.popkey() == "TO") // TO keyword - { - const char* t = scanner.pop(); - to = name2log(t); - } - else - { - to = 0; // _relation->lfile()->num(); - scanner.push(); - } - - int key = 1; - if (scanner.popkey() == "KE") - key = scanner.integer(); - else scanner.push(); - - int alias = 0; - if (scanner.popkey() == "AL") - alias = scanner.integer(); - else scanner.push(); - - TToken_string exp(80); - if (scanner.pop() == "INTO") - { - const char* r = scanner.pop(); - while (strchr(r, '=') != NULL) - { - exp.add(r); - r = scanner.pop(); - } - } - scanner.push(); - -#ifdef DBG - if (exp.empty()) yesnofatal_box("JOIN senza espressioni INTO"); -#endif - - if (isdigit(j[0])) - _relation->add(atoi(j), exp, key, to, alias); // join file - else - { -#ifdef DBG - if (j.len() > 4) - yesnofatal_box("'%s' non e' una tabella valida: %d", (const char*)j); - else -#endif - _relation->add(j, exp, key, to, alias); // join table - } -} - - -void TBrowse::parse_insert(TScanner& scanner) -{ - const TString& key = scanner.popkey(); - _insert.cut(0); - if (key != "NO") - { - _insert << key[0] << scanner.line(); - _insert.trim(); - } -} - -// Ritorna il numero di inputs senza contare quelli che funzionano solo da filtro -int TBrowse::input_fields() -{ - int inp = 0; - for (const char* fld = _inp_id.get(0); fld; fld = _inp_id.get()) - { - if (*fld != '"' && strchr(fld, '@') == NULL) - { - TMask_field& f = field(field().atodlg(fld)); - if (f.active() && f.is_editable()) - inp++; - } - } - return inp; -} - -const char* TBrowse::get_input_fields() const -{ - return _inp_id; -} - -const char* TBrowse::get_input_field_names() const -{ - return _inp_fn; -} - -void TBrowse::add_input_field(const char * id, const char * name, const int pos, bool select) -{ - TString strid(id) ; - - if (select) - strid << '@'; - if (pos < 0 || pos >= _items.items()) - { - _inp_id.add(strid); - _inp_fn.add(name); - } - else - { - _inp_id.insert_at(strid, pos); - _inp_fn.insert_at(name, pos); - } -} - -void TBrowse::remove_display_field(const int pos) -{ - if (pos < 0) - { - _head.cut(0); - _items.cut(0); - } - else - { - _head.destroy(pos); - _items.destroy(pos); - } -} -void TBrowse::copy_input(const TBrowse * b) -{ - if (b) - { - _inp_id = b->_inp_id; - _inp_fn = b->_inp_fn; - } -} - -void TBrowse::copy_display(const TBrowse * b) -{ - if (b) - { - _head = b->_head; - _items = b->_items; - } -} - -void TBrowse::copy_output(const TBrowse * b) -{ - if (b) - { - _out_id = b->_out_id; - _out_fn = b->_out_fn; - } -} - -void TBrowse::add_display_field(const char * hd, const char * name, const int pos) -{ - if (pos < 0 || pos >= _items.items()) - { - _head.add(dictionary_translate_header(hd)); - _items.add(name); - } - else - { - _head.insert_at(dictionary_translate_header(hd), pos); - _items.insert_at(name, pos); - } -} - -void TBrowse::remove_input_field(const int pos) -{ - if (pos < 0) - { - _inp_id.cut(0); - _inp_fn.cut(0); - } - else - { - _inp_id.destroy(pos); - _inp_fn.destroy(pos); - } -} - -void TBrowse::add_output_field(const char * id, const char * name, const int pos) -{ - if (pos < 0 || pos >= _items.items()) - { - _out_id.add(id); - _out_fn.add(name); - } - else - { - _out_id.insert_at(id, pos); - _out_fn.insert_at(name, pos); - } -} - -void TBrowse::remove_output_field(const int pos) -{ - if (pos < 0) - { - _out_id.cut(0); - _out_fn.cut(0); - } - else - { - _out_id.destroy(pos); - _out_fn.destroy(pos); - } -} - - -const char* TBrowse::get_output_fields() const -{ - return _out_id; -} - -const char* TBrowse::get_output_field_names() const -{ - return _out_fn; -} - -// @doc INTERNAL - -// @mfunc Ritorna il numero di campi non vuoti e non filtrati -// -// @rdesc Numero di campi non vuoti e non filtrati -int TBrowse::do_input( - bool filter) // @parm Indica se effettuare il filtro sulla selezione - - // @comm Questa funzione serve ai -{ - int ne = 0; - if (_inp_id.empty()) - return ne; - - _cursor->file(0).zero(); // was cur.zero() che non va bene per le tabelle di modulo - TRectype& cur = _cursor->curr(); - TRectype filtrec(cur); - - _inp_id.restart(); - _inp_fn.restart(); - - TString val; // Value to output - bool tofilter = false; - - for (const char* fld = _inp_id.get(); fld; fld = _inp_id.get()) - { - const TFieldref fldref(_inp_fn.get(), 0); // Output field - - if (*fld == '"') - { - val = (fld+1); - if (val.not_empty()) val.rtrim(1); - tofilter = filter; - } - else - { - const TMask_field* campf = NULL; - - if (*fld == '-') - { - TSheet_field* sheet = field().mask().get_sheet(); - if (sheet != NULL) - { - const short id = atoi(fld+1); - campf = &sheet->mask().field(id); - } - } - else - { - const short id = field().atodlg(fld); - campf = &field(id); - } - - if (campf != NULL) - { - const TMask_field& f = *campf; - val = f.get(); - - switch (f.class_id()) - { - case CLASS_REAL_FIELD: - // Cerco di allineare correttamente i campi interi salvati parzialmente su codtab - if (fldref.to() > 1 && f.size() > 1 && val.full() && - ((TReal_field&)f).decimals() == 0 && fldref.name() == "CODTAB") - { - const int len = fldref.len(cur); - if (f.size() == len && val.len() < len) - val.right_just(len); - } - break; - case CLASS_DATE_FIELD: - if (f.right_justified()) - { - const TDate d(val); - val = d.string(ANSI); - } - break; - default: - break; - } - - const bool filter_flag = strchr(fld, '@') != NULL; - tofilter = filter && filter_flag; - if (f.is_edit() && val.not_empty() && !filter_flag) - ne++; // Increment not empty fields count - } - } - fldref.write(val, *_cursor->relation()); - if (tofilter) - { - const int len = fldref.len(cur); - - if (val.len() < len && cur.type(fldref.name()) == _alfafld) - val.rpad(len, '~'); - fldref.write(val, filtrec); - } - } - - if (!filter) - return ne; - - TString work(_filter.size()); - bool filter_update = false; - - for (int i = 0; _filter[i]; i++) - { - if (_filter[i] == '"') - { - do - { - work << _filter[i++]; - } while (_filter[i] && _filter[i] != '"'); - work << '"'; - if (!_filter[i]) break; - } - else - if (_filter[i] == '#') - { - if (_filter[++i] == '-') - { - TString val; - TSheet_field* sheet = field().mask().get_sheet(); - - if (sheet != NULL) - { - const short id = atoi(&_filter[++i]); - - val = sheet->mask().field(id).get(); - } - work << '"' << val << '"'; - } - else - work << '"' << field(atoi(&_filter[i])).get() << '"'; - while (isspace(_filter[i])) i++; - while (isdigit(_filter[i])) i++; - i--; - } - else - { - work << _filter[i]; - if (_filter[i] == '-' && _filter[i + 1] == '>') - filter_update = true; - } - } - - _cursor->relation()->mask2rel(field().mask()); - _cursor->setfilter(work, filter_update); - _cursor->setregion(filtrec, filtrec); - - return ne; -} - -static TBit_array s_checked; -static short s_checking = 0; - -void TBrowse::do_output(CheckTime t) -{ - if (t == FINAL_CHECK) - return; - - const bool master = s_checking == 0; - if (master) - { - s_checking = field().dlg(); - s_checked.reset(); - // Rendo intoccabili i campi del MIO output - for (const char* fld = _out_id.get(0); fld && *fld; fld = _out_id.get()) - { - const short id = field().atodlg(fld); - s_checked.set(id); - } - } - - TString sum; - TToken_string flds(24, '+'); - - const TRelation& relation = *_cursor->relation(); - - TBit_array spotted; - - _out_fn.restart(); - const char* fld; - for (fld = _out_id.get(0); fld && *fld; fld = _out_id.get()) - { - const short id = field().atodlg(fld); - TMask_field& f = field(id); - - flds = _out_fn.get(); - - bool do_that = t != STARTING_CHECK || f.field() == NULL || (f.mask().mode() == MODE_INS && !f.in_key(0)); - if (do_that && main_app().class_id() == CLASS_RELATION_APPLICATION) - { - // Considera a parte l'inizializzazione delle transazioni! - // Non sovrascrivere con degli output campi che potrebbero essere riempiti dal .ini - if (!f.empty() && f.field() != NULL) - { - const TMask& m = f.mask(); - if (!m.is_running() && m.get_sheet() == NULL) // Maschera principale chiusa - { - const TRelation_application& ra = (const TRelation_application&)main_app(); - if (ra.is_transaction()) - do_that = false; - } - } - } - if (do_that) - { - sum.cut(0); - for(const char* fr = flds.get(0); fr; fr = flds.get()) - { - if (*fr == '"') - { - sum << (fr+1); - sum.rtrim(1); - } - else - { - const TFieldref fld(fr, 0); - sum << fld.read(relation); - } - } - - bool hit = false; - if (master) - { - f.set(sum); - hit = id != s_checking; // Il mio handler viene fatto nella on_key - } - else - { - if (!s_checked[id]) - { - f.set(sum); - s_checked.set(id); - hit = true; - } - } - spotted.set(id, hit); - } - } - - for (fld = _out_id.get(0); fld && *fld; fld = _out_id.get()) - { - const short id = field().atodlg(fld); - if (spotted[id]) - { - TMask_field& f = field(id); - f.check(); - f.on_hit(); - } - } - - if (master) - s_checking = 0; -} - - -void TBrowse::do_clear(CheckTime t) -{ - const bool master = s_checking == 0; - if (master) - { - s_checking = field().dlg(); - s_checked.reset(); - // Rendo intoccabili i campi del MIO input - for (const char* fld = _inp_id.get(0); fld && *fld; fld = _inp_id.get()) - { - if (isdigit(*fld)) - { - const short id = field().atodlg(fld); - s_checked.set(id); - } - } - } - - for (TString16 fld = _out_id.get(0); fld.not_empty(); fld = _out_id.get()) - { - const short id = field().atodlg(fld); - TMask_field& f = field(atoi(fld)); - if (f.field() == NULL && field().dlg() != id && - !s_checked[id] && _inp_id.get_pos(fld) < 0) - { - f.reset(); - s_checked.set(id); - f.on_hit(); - f.check(t); - } - } - - if (master) - s_checking = 0; -} - -bool TBrowse::do_link(bool insert) -{ - bool ok = false; - TString app; - if (_insert.starts_with("MTB", true)) - _cursor->file().get_relapp(app); - else - app = _insert.mid(1); - if (app.find('#') >= 0) - { - const TString w(app); - app = ""; - for (const char* f = w; *f; f++) - { - if (*f == '#') - { - const int id = atoi(++f); - app << field(id).get(); - while (isspace(*f)) ++f; - while (isdigit(*f)) ++f; - if (*f) - app << ' ' << *f; - else - break; - } - else - app << *f; - } - } - - TFilename msg; msg.temp("msg"); - app << " /i" << msg; - - if (insert) - { - TConfig ini(msg, "Transaction"); - ini.set("Action", TRANSACTION_RUN); - } - else - { - TConfig ini(msg, "Transaction"); - ini.set("Action", TRANSACTION_LINK); - - TString8 paragraph; paragraph << _cursor->file().num(); - ini.set_paragraph(paragraph); - - // Uso sempre la chiave 1 per collegarmi agli altri programmi - const TRelation& rel = *_cursor->relation(); - const RecDes& recd = rel.curr().rec_des(); // Descrizione del record della testata - const KeyDes& kd = recd.Ky[0]; // Elenco dei campi della chiave 1 - TString inp_val; - for (int i = 0; i < kd.NkFields; i++) - { - const int nf = kd.FieldSeq[i] % MaxFields; - const RecFieldDes& rf = recd.Fd[nf]; - const TFieldref fldref(rf.Name, 0); - inp_val = fldref.read(rel); - fldref.write(ini, paragraph, inp_val); - } - } - - TExternal_app a(app); - a.run(); - field().mask().set_focus(); - - if (msg.not_empty()) - { - TConfig ini(msg, "Transaction"); - _rec = ini.get_long("Record"); - if (_rec > 0 || !insert) // Modifica o cancellazione - _cursor->update(); // Forza ricalcolo cursore - if (_rec >= 0) - { - _cursor->file().readat(_rec); - ok = _cursor->ok(); - if (ok) - { - rec_cache(_cursor->file().num()).notify_change(); // Svuota eventule cache - do_output(); - } - } - ::remove(msg); - } - return ok; -} - - -TToken_string& TBrowse::create_siblings(TToken_string& siblings) -{ - siblings = ""; // Azzera la lista dei campi associati - - TBit_array key(4); // Elenco delle chiavi gia' utilizzate - key.set(_cursor->key()); - - TString fn; // Nome campo - - // Scorre la lista dei campi di output - int n = 0; - for (const char* i = _out_id.get(0); i; i = _out_id.get(), n++) - { - const short id = field().atodlg(i); - const TEditable_field& f = field(id); - if (!f.active() || !f.is_edit()) // Scarta i campi non editabili - continue; - const TEdit_field& e = (const TEdit_field&)f; - const TBrowse* b = e.browse(); - if (b == NULL) - continue; // Scarta i campi senza ricerca - - const TCursor* c = b->cursor(); - - // Considera ricerche sullo stesso file ma con chiave diversa - if (c->file().num() == _cursor->file().num() && - (key[c->key()] == false || id == field().dlg())) - { - fn = _out_fn.get(n); // Legge nome del campo su file - int pos = _items.get_pos(fn); // Determina header corrispondente - if (pos < 0) // Se non lo trova identico ... - { - const int q = fn.find('['); - if (q > 0) - { - fn.cut(q); - pos = _items.get_pos(fn); // ... ritenta senza parentesi - } - } - if (pos >= 0) - { - siblings.add(id); - const char* h = _head.get(pos); - siblings.add(h); - const int et = siblings.find('@'); - if (et > 0) siblings.cut(et); - key.set(c->key()); // Marca la chiave come usata - } - } - } - - return siblings; -} - - -KEY TBrowse::run() -{ - begin_wait(); - - do_input(true); - _cursor->read(_isgteq); - - TString caption = _cursor->file().description(); - if (caption.blank()) - caption = TR("Selezione"); - - KEY k = K_ESC; - long selected = 0; - - TToken_string siblings, vals; - create_siblings(siblings); - - { - byte buttons = 0; - if (_insert.not_empty()) - { - // Mette il bottone di gestione, a meno che ... - if (_cursor->items() == 0) - buttons = 2; // Non mette il bottone collega se non ci sono elementi - else - buttons = 3; - - if (_insert[0] == 'M' || _insert[0] == 'R') - { - const TString& maskname = field().mask().source_file(); - if (maskname.mid(2,2).compare("tb", 2, true) == 0 && field().in_key(0)) - { - const char* tabname = _cursor->file().name(); - if (maskname.mid(4, 3).compare(tabname, 3, true) == 0) - buttons = 0; - } - } - } - - for (const char* i = _inp_id.get(0); i; i = _inp_id.get()) - { - if (*i != '\0' && *i != '"' && strchr(i, '@') == NULL) - { - const short id = field().atodlg(i); - const TEditable_field& f = field(id); - if (f.active() && f.is_editable()) - { - vals.add(i); - vals.add(f.get()); - vals.add((int)f.dirty()); - } - } - } - - end_wait(); - - TBrowse_sheet s(_cursor, _items, caption, _head, buttons, field(), siblings, _custom_filter_handler); - - k = s.run(); - selected = s.selected(); - } - - switch (k) - { - case K_ESC: - case K_QUIT: - break; - case K_CTRL+'G': - *_cursor = selected; - k = do_link(false) ? K_ENTER : K_ESC; - break; - case K_INS: - k = do_link(true) ? K_ENTER : K_ESC; - break; - case K_ENTER: - *_cursor = selected; - do_output(); - break; - default: - { - for (const char* i = vals.get(0); i && *i; i = vals.get()) - { - const short id = field().atodlg(i); - TEditable_field& f = field(id); - f.set(vals.get()); - f.set_dirty(vals.get_int()); - } - } - if (k >= K_CTRL) // Scatta la ricerca su di una chiave alternativa - { - TMask& m = field().mask(); - const int tag = k - K_CTRL - K_F1; - const short id = siblings.get_int(tag * 2); - TEdit_field& ef = m.efield(id); - ef.set_focus(); - k = K_F9; - if (m.is_running()) - m.send_key(k, id, &ef); //m.send_key(k, id); - } - break; - } - - return k; -} - -void TBrowse::set_cursor(TCursor * c) -{ - if (_cursor != NULL) - delete _cursor; - _cursor = c ; -} - -bool TBrowse::check(CheckTime t) -{ - bool passed = true; - - if (_secondary == true && t != RUNNING_CHECK) - return true; - - CheckType chk = field().check_type(); - if (chk != CHECK_NONE) - { - const TMaskmode mode = (TMaskmode)field().mask().mode(); - if (chk == CHECK_REQUIRED && (t == STARTING_CHECK || mode == MODE_QUERY)) - chk = CHECK_NORMAL; - - const int ne = do_input(true); - if (ne || chk == CHECK_REQUIRED) - { - passed = _cursor->test() == NOERR; - - if (t != FINAL_CHECK) - { - if (passed) - { - _cursor->repos(); - do_output(t); - if (t == STARTING_CHECK && field().dirty() > 1) - field().set_dirty(true); - } - else - { - if (chk == CHECK_SEARCH) - { - passed = true; - } - else - { - do_clear(t); - if (!field().mask().query_mode() && field().check_enabled()) - field().set_dirty(3); - } - } - } - else - { - if (chk == CHECK_SEARCH) - passed = true; - } - } - else - { - if (chk == CHECK_SEARCH) - passed = true; - else - { - if (t != FINAL_CHECK) - do_clear(t); - } - } - } - return passed; -} - -bool TBrowse::empty_check() -{ - if (field().mask().query_mode() || field().check_type() != CHECK_REQUIRED) - return true; - else - return do_input() > 0; -} - -/////////////////////////////////////////////////////////// -// TFile_select -/////////////////////////////////////////////////////////// - -TFile_select::TFile_select(TEdit_field* ef, const char* filter) -: TBrowse_button(ef), _filter(filter) -{ } - -void TFile_select::parse_input(TScanner& scanner) -{ - scanner.pop(); -} - -void TFile_select::parse_output(TScanner& scanner) -{ - scanner.pop(); -} - -KEY TFile_select::run() -{ - TFilename path; - path = field().get(); - if (path.full() && _filter.find('.') > 0 && !_filter.ends_with(".*")) - path.ext(_filter.ext()); - - FILE_SPEC fs; xvt_fsys_convert_str_to_fspec(path, &fs); - - bool good = xvt_dm_post_file_open(&fs, field().prompt()) == FL_OK; - if (good) - { - xvt_fsys_convert_fspec_to_str(&fs, path.get_buffer(), path.size()); - good = _filter.blank() || xvt_str_match(path.name(), _filter, false); - if (good) - field().set(path); - else - field().error_box(FR("Il nome del file non corrisponde a %s"), _filter.get_buffer()); - } - return good ? K_ENTER : K_ESC; -} - -bool TFile_select::check(CheckTime ct) -{ - const TFilename name = field().get(); - if (ct != STARTING_CHECK && name.empty() && - field().check_type() == CHECK_REQUIRED) - return false; - bool ok = _filter.empty() || xvt_str_match(name, _filter, false); - if (ok && field().roman()) // Must exist - ok = name.exist(); - return ok; -} - -/////////////////////////////////////////////////////////// -// TDir_select -/////////////////////////////////////////////////////////// - -TDir_select::TDir_select(TEdit_field* ef) : TBrowse_button(ef) -{ } - -void TDir_select::parse_input(TScanner& scanner) -{ - scanner.pop(); -} - -void TDir_select::parse_output(TScanner& scanner) -{ - scanner.pop(); -} - -KEY TDir_select::run() -{ - DIRECTORY savedir; - xvt_fsys_get_dir(&savedir); - - DIRECTORY dir; - xvt_fsys_convert_str_to_dir(field().get(), &dir); - bool good = xvt_dm_post_dir_sel(&dir) == FL_OK; - xvt_fsys_set_dir(&savedir); - - if (good) - { - TFilename path; - xvt_fsys_convert_dir_to_str(&dir, path.get_buffer(), path.size()); - field().set(path); - } - return good ? K_ENTER : K_ESC; -} - -bool TDir_select::check(CheckTime ct) -{ - const TFilename name = field().get(); - if (ct != STARTING_CHECK && name.empty() && - field().check_type() == CHECK_REQUIRED) - return false; - bool ok = true; - if (field().roman()) // Must exist - ok = name.exist(); - return ok; -} - -/////////////////////////////////////////////////////////// -// TProfile_select -/////////////////////////////////////////////////////////// - -TProfile_select::TProfile_select(TEdit_field* ef) -: TBrowse_button(ef) -{ } - -void TProfile_select::parse_input(TScanner& scanner) -{ - scanner.pop(); -} - -void TProfile_select::parse_output(TScanner& scanner) -{ - scanner.pop(); -} - -HIDDEN int get_profile_desc(TConfig& cfg, void* jolly) -{ - const int num = atoi(cfg.get_paragraph()); - if (num > 0) - { - TString_array& p = *(TString_array*)jolly; - TToken_string* str = new TToken_string; - str->format("%4d", num); - str->add(cfg.get("Description")); - p.add(str); - } - return false; -} - -int TProfile_select::get_descriptions(TString_array& a) const -{ - TFilename profname; - field().mask().make_profile_name(profname); - TConfig prof(profname); - a.destroy(); - prof.for_each_paragraph(get_profile_desc, &a); - a.sort(); - return a.items(); -} - -KEY TProfile_select::run() -{ - TArray_sheet p(3, 3, -3, -3, TR("Profili"), HR("Codice@6R|Descrizione@60"), 0x6, 2); - const short id = DLG_USER+1; - TEdit_field& prompt = p.add_string(id, 0, PR("Salva con nome "), 1, 0, 60); - p.add_button(DLG_SAVEREC, PR("~Registra"), K_CTRL+'r', TOOL_SAVEREC); - prompt.set(field().get()); - - TMask& m = field().mask(); - TFilename profname; m.make_profile_name(profname); - - bool running = true; - KEY key; - while (running) - { - p.destroy(); - TString_array& a = p.rows_array(); - get_descriptions(a); - p.field(DLG_SAVEREC).enable(a.items()>0); - FOR_EACH_ARRAY_ROW_BACK(a, r, row) - if (field().get() == row->get(1)) break; - if (r) - p.select(r); - - key = p.run(); - switch(key) - { - case K_ENTER: - { - const int num = p.row().get_int(0); - TString16 para; para << m.load_profile(num); - prompt.set(p.row().get(1)); - running = false; - } - break; - case K_CTRL+'r': - { - const TString& name = p.get(id); - FOR_EACH_ARRAY_ROW_BACK(a, r, row) - if (r != p.selected() && name == row->get(1)) break; - if (r < 0) - { - const int num = p.row().get_int(0); - m.save_profile(num, name); - running = false; - } - else - error_box("Esiste gia' un profilo di nome\n%s", - (const char*)name); - } - break; - case K_INS: - { - const TString& name = p.get(id); - if (!name.blank()) - { - FOR_EACH_ARRAY_ROW_BACK(a, r, row) - if (name == row->get(1)) break; - if (r < 0) - { - TString16 para; para << m.save_profile(-1, name); - field().set(name); - running = false; - } - else - error_box("Esiste gia' un profilo di nome\n%s", - (const char*)name); - } - else - error_box("E' necessario dare un nome al profilo"); - } - break; - case K_DEL: - { - TString16 para; para << p.row().get_int(0); - const TString desc = p.row().get(1); - TConfig prof(profname, para); - if (yesno_box("Confermare la cancellazione del profilo %s\n%s", - (const char*)para, (const char*)desc)) - prof.remove_all(); - } - break; - default: - running = false; - break; - } - } - field().set(prompt.get()); - return key; -} - -bool TProfile_select::check(CheckTime ct) -{ - switch (ct) - { - case STARTING_CHECK: - { - TMask& m = field().mask(); - TFilename name; m.make_profile_name(name); - TString16 para; para << m.load_profile(); - TConfig ini(name, para); - field().set(ini.get("Description")); - } - break; - case RUNNING_CHECK: - if (!field().empty()) - { - const TString& name = field().get(); - TString_array a; - get_descriptions(a); - FOR_EACH_ARRAY_ROW_BACK(a, r, row) - { - if (name == row->get(1)) - { - field().mask().load_profile(row->get_int(0)); - break; - } - } - if (r < 0) - return field().error_box("Profilo inesistente"); - } - break; - case FINAL_CHECK: - if (!field().active()) - { - TMask& m = field().mask(); - m.save_profile(); - } - break; - default: - break; - } - return true; -} - -/////////////////////////////////////////////////////////// -// TReport_select -/////////////////////////////////////////////////////////// - -TReport_select::TReport_select(TEdit_field* ef, const char* classe) -: TBrowse_button(ef), _classe(classe) -{ } - -void TReport_select::parse_input(TScanner& scanner) -{ - scanner.pop(); -} - -void TReport_select::parse_output(TScanner& scanner) -{ - scanner.pop(); -} - -KEY TReport_select::run() -{ - TFilename path = field().get(); - if (select_custom_file(path, "rep", _classe)) - { - path = path.name(); - path.ext(""); - field().set(path); - } - - return path.not_empty() ? K_ENTER : K_ESC; -} - -bool TReport_select::check(CheckTime ct) -{ - TFilename name = field().get(); - if (ct != STARTING_CHECK && name.empty() && - field().check_type() == CHECK_REQUIRED) - return false; - - bool ok = true; - if (field().roman()) // Must exist - ok = name.custom_path(); - return ok; -} /////////////////////////////////////////////////////////// // TEdit_field @@ -3642,7 +2110,7 @@ bool TEdit_field::parse_item(TScanner& scanner) return yesnofatal_box("USE duplicata nel campo %d", dlg()); #endif - int key = 1; + int key = 1, altkey = 0; TRelation* r = NULL; TString16 tablename = scanner.pop(); @@ -3672,14 +2140,35 @@ bool TEdit_field::parse_item(TScanner& scanner) if (scanner.popkey() == "KE") { - key = scanner.integer(); -#ifdef DBG - if (key < 1 || key > MAX_KEYS) + const TString& k = scanner.pop(); + key = atoi(k); + + const int maxkey = r ? r->curr().rec_des().NKeys : MAX_KEYS; + if (key <= 0 || key > maxkey) { +#ifdef DBG yesnofatal_box("Chiave %d non valida nella USE del campo %d", key, dlg()); +#endif key = 1; } -#endif + + if (key > 1 && !is_kind_of(CLASS_REAL_FIELD)) + { + const int par = k.find('('); + if (par > 0) + altkey = atoi(k.mid(par+1)); + + if (altkey <= 2 || altkey > maxkey) + { + switch (r->file().num()) + { + case LF_CLIFO: altkey = 6; break; + default : altkey = 0; break; + } + if (altkey == key) + altkey = 0; + } + } } else scanner.push(); @@ -3708,6 +2197,10 @@ bool TEdit_field::parse_item(TScanner& scanner) tablename.insert("MTB", 0); browse()->set_insert(tablename); } + + if (altkey > 2) + ((TBrowse*)_browse)->set_alt_browse(altkey); + _check_enabled = true; } else @@ -4080,11 +2573,6 @@ bool TEdit_field::on_key(KEY key) set_focusdirty(false); break; case K_TAB: - /* - if (vf >= 0 && (vf == AUTOEXIT_FUNC || vf == NUMCALC_FUNC || vf == STRCALC_FUNC)) - set_focusdirty(); // Forza validate - */ - if (to_check(K_TAB, true)) { if (class_id() == CLASS_EDIT_FIELD) // Altrimenti l'ha gia' fatto @@ -4859,23 +3347,17 @@ TCurrency& TCurrency_field::get_currency(TCurrency& cur) const const real num(get()); const char* value = NULL; real exchange; - exchange_type et = _exchange_undefined; const TMask_field* d0 = driver(0); if (d0) { value = d0->get(); const TMask_field* d1 = driver(1); if (d1) - { exchange = real(d1->get()); - const TMask_field* d2 = driver(2); - if (d2) - et = d2->get().blank() ? _exchange_base : _exchange_contro; - } } cur.set_num(num); - cur.force_value(value, exchange, et); + cur.force_value(value, exchange); cur.set_price(_flags.uppercase != 0); return cur; } @@ -4906,7 +3388,7 @@ const char* TCurrency_field::raw2win(const char* data) const const TMask_field* d0 = driver(0); const char* value = d0 ? (const char*)d0->get() : NULL; const bool price = _flags.uppercase != 0; - TCurrency cur(num, value, ZERO, _exchange_undefined, price); + TCurrency cur(num, value, ZERO, price); TString& s = _ctl_data._park; s = cur.string(true); @@ -4952,7 +3434,7 @@ const char* TCurrency_field::win2raw(const char* data) const const TMask_field* d0 = driver(0); const char* value = d0 ? (const char*)d0->get() : NULL; const bool price = _flags.uppercase != 0; - TCurrency cur(num, value, ZERO, _exchange_undefined, price); + TCurrency cur(num, value, ZERO, price); str = cur.get_num().string(); } return str; diff --git a/include/maskfld.h b/include/maskfld.h index 6d83cc548..bc7405697 100755 --- a/include/maskfld.h +++ b/include/maskfld.h @@ -11,7 +11,7 @@ #ifndef __SCANNER_H #include -#endif +#endif #ifndef __WINDOW_H #include @@ -36,6 +36,14 @@ class TCurrency; // __CURRENCY_H // @doc EXTERNAL +// @enum Momento di richiesta del check +enum CheckTime +{ + RUNNING_CHECK, // @emem Check chiamato mentra la maschera sta andando + STARTING_CHECK, // @emem Check chiamato al caricamento della maschera + FINAL_CHECK // @emem Check chiamato quando la maschera si sta fermando +}; + // @enum Tipo di check da eseguire su un controllo enum CheckType { CHECK_NONE, // @emem Nessun controllo @@ -46,11 +54,6 @@ enum CheckType { // @doc EXTERNAL -// @enum Momento di richiesta del check -enum CheckTime { - RUNNING_CHECK, // @emem Check chiamato mentra la maschera sta andando - STARTING_CHECK, // @emem Check chiamato al caricamento della maschera - FINAL_CHECK }; // @emem Check chiamato quando la maschera si sta fermando // @type CONTROL_HANDLER | Prototipo funzione per gestire i tasti speciali all'interno di un controllo typedef bool (*CONTROL_HANDLER)(TMask_field& field, KEY key); @@ -264,21 +267,17 @@ public: virtual bool has_query_button() const { return false;} // @cmember Ritorna il campo corrispondente su record - virtual const TFieldref* field() const - { return NULL; } + virtual const TFieldref* field() const { return NULL; } // @cmember Imposta il tipo di checktype del campo virtual void check_type(CheckType); // @cmember Ritorna lo stato di checktype del campo - virtual CheckType check_type() const - { return CHECK_NONE; } + virtual CheckType check_type() const { return CHECK_NONE; } // @cmember Ritorna true se il checktype del campo e'

- bool required() const - { return check_type() == CHECK_REQUIRED; } + bool required() const { return check_type() == CHECK_REQUIRED; } // @cmember Controlla la validita' del campo - virtual bool check(CheckTime = RUNNING_CHECK) - { return true;} + virtual bool check(CheckTime = RUNNING_CHECK) { return true;} // @cmember Azzera il contenuto del campo virtual void reset(); @@ -793,386 +792,13 @@ public: virtual ~TCheckbutton_field() {} }; -/////////////////////////////////////////////////////////// -// TBrowse_button -/////////////////////////////////////////////////////////// - -class TEdit_field; - -class TBrowse_button : public TObject -{ - TEdit_field* _fld; - -protected: - // @cmember Ritorna il primo valore di

- TEdit_field& field() const - { return *_fld; } - - // @cmember Ritorna il campo

-esimo - TEditable_field& field(short id) const; - -public: - // @cmember Controlla la sintassi della input del campo e ne setta i membri - virtual void parse_input(TScanner& scanner) pure; - - // @cmember Controlla la sintassi della output del campo e ne setta i membri - virtual void parse_output(TScanner& scanner) pure; - - virtual KEY run() pure; - - // @cmember Controlla la validita' del campo - virtual bool check(CheckTime = RUNNING_CHECK) pure; - - virtual bool is_browse() const { return false; } - virtual bool is_sheet() const { return false; } - virtual bool is_filesel() const { return false; } - virtual bool is_profile() const { return false; } - - TBrowse_button(TEdit_field* f); - virtual ~TBrowse_button(); -}; - - -/////////////////////////////////////////////////////////// -// TBrowse -/////////////////////////////////////////////////////////// - -// @class TList_sheet | Classe per la gestione dei list sheet -class TList_sheet : public TBrowse_button -// @author:(INTERNAL) Guido -{ - // @access:(INTERNAL) Private Memeber - - // @cmember:(INTERNAL) Numero di riga corrente dello sheet - int _row; - - // @cmember:(INTERNAL) Titolo dello sheet - TString _caption; - - // @cmember:(INTERNAL) Testate delle colonne dello sheet - TToken_string _head; - - // @cmember:(INTERNAL) Righe dello sheet - TString_array _data; - - // @cmember:(INTERNAL) Campi di input sulla maschera - TToken_string _inp_id; - - // @cmember:(INTERNAL) Campi di output sulla maschera - TToken_string _out_id; - - // @access Protected Member -protected: - // @cmember Ritorna il numero di riga selezionata - int do_input(); - // @cmember Scrive l'output della ricerca sulla maschera - void do_output(CheckTime = RUNNING_CHECK); - - // @cmember Controlla la sintassi della input del campo e ne setta i membri - void parse_input(TScanner& scanner); - // @cmember Controlla la sintassi della output del campo e ne setta i membri - void parse_output(TScanner& scanner); - - // @access Public Memeber -public: - // @cmember Legge dal file gli item dello sheet - void parse_item(TScanner& scanner); - - // @cmember Controlla la validita' del campo - virtual bool check(CheckTime = RUNNING_CHECK); - - // @cmember Esegue la ricerca. Torna il tasto che ha terminato la ricerca - virtual KEY run(); - - virtual bool is_sheet() const { return true; } - - TString_array& rows_array() { return _data; } - - // @cmember Costruttore - TList_sheet(TEdit_field* f, const char* caption, const char* head); - // @cmember Distruttore - virtual ~TList_sheet(); -}; - -// @doc INTERNAL - -// @class TBrowse | Classe per la definizione dei campi con ricerca -class TBrowse : public TBrowse_button -// @author:(INTERNAL) Guido -{ - // @access:(INTERNAL) Private Member - - // @cmember:(INTERNAL) Relazione della ricerca - TRelation* _relation; - // @cmember:(INTERNAL) Cursore sulla relazione - TCursor* _cursor; - // @cmember:(INTERNAL) Comando da eseguire alla pressione del tasto Gestione - TString _insert; - // @cmember:(INTERNAL) Filtro sul cursore - TString _filter; - // @cmember:(INTERNAL) Record selezionato - long _rec; - // @cmember:(INTERNAL) Indica se e' presente un campo secondario nella ricerca - bool _secondary; - // @cmember:(INTERNAL) Indica se sul campo e' gia' stato effettuato il check - bool _checked; - - // @cmember:(INTERNAL) Testate della maschera di ricerca - TToken_string _head; - // @cmember:(INTERNAL) Campi visualizzati dalla maschera di ricerca - TToken_string _items; - // @cmember:(INTERNAL) Campi di input sulla maschera - TToken_string _inp_id; - // @cmember:(INTERNAL) Campi di input sul file - TToken_string _inp_fn; - // @cmember:(INTERNAL) Campi di output sulla maschera - TToken_string _out_id; - // @cmember:(INTERNAL) Campi di output sul file - TToken_string _out_fn; - // @cmember:(INTERNAL) handler di filtro custom - CONTROL_HANDLER _custom_filter_handler; - - // @access Protected Member -protected: - // @cmember Azzera i campi di output sulla maschera - void do_clear(CheckTime t); - // @cmember Chiama la maschera di gestione della ricerca - bool do_link(bool insert); - - // @cmember Crea lista identificatori di ricerca - TToken_string& create_siblings(TToken_string& siblings); - - // @cmember Modifica il cursore - void custom_cursor(); - - // @access Public Member -public: - // @cmember Modifica il display - void custom_display(); - - // @cmember Ritorna il numero di inputs senza contare quelli che funzionano - // solo da filtro - int input_fields(); - - // @cmember Ritorna la lista completa degli identificatori dei campi di input - const char* get_input_fields() const; - - // @cmember Ritorna la lista completa dei nomi dei campi di input - const char* get_input_field_names() const; - - // @cmember Aggiorna la lista completa degli identificatori dei campi di input - void set_input_fields(const char * inp_id) { _inp_id = inp_id;} - - // @cmember Aggiorna la lista completa degli identificatori dei campi di input da un campo - void copy_input(const TBrowse * b); - - // @cmember Aggiorna la lista completa dei nomi dei campi di input - void set_input_field_names(const char * inp_names) { _inp_fn = inp_names;} - - // @cmember Aggiunge un campo di input alla posizione - void add_input_field(const char * id, const char * name, const int pos = - 1, bool select = false); - -// @cmember Elimina un campo di display alla posizione - void remove_display_field(const int pos = -1); - - // @cmember Aggiorna la lista completa degli identificatori dei campi di output - void set_display_fields(const char * hds, const char * names) { _head = hds; _items = names;} - - // @cmember Aggiorna la il display da un campo - void copy_display(const TBrowse * b); - - // @cmember Aggiunge un campo di diplay alla posizione - void add_display_field(const char * hd, const char * name, const int pos = -1); - -// @cmember Elimina un campo di input alla posizione - void remove_input_field(const int pos = -1); - - // @cmember Ritorna la lista completa dei campi di output - const char* get_output_fields() const; - - // @cmember Ritorna la lista completa dei nomi dei campi di output - const char* get_output_field_names() const; - - // @cmember Aggiorna la lista completa degli identificatori dei campi di output - void set_output_fields(const char * out_id) { _out_id = out_id;} - - // @cmember Aggiorna la lista completa dei nomi dei campi di input - void set_output_field_names(const char * out_names) { _out_fn = out_names;} - - // @cmember Aggiorna la lista completa degli identificatori dei campi di output da un campo - void copy_output(const TBrowse * b); - - // @cmember Aggiunge un campo di output alla posizione - void add_output_field(const char * id, const char * name, const int pos = -1); - - // @cmember Elimina un campo di output alla posizione - void remove_output_field(const int pos = -1); - - // @cmember Ritorna il numero di campi non vuoti e non filtrati - int do_input(bool filter = false); - - // @cmember Scrive l'output della ricerca sulla maschera - void do_output(CheckTime = RUNNING_CHECK); - - // @cmember Costruttore - TBrowse(TEdit_field* f, TRelation* r, int key = 1, const char* filter = ""); - // @cmember Costruttore - TBrowse(TEdit_field* f, TCursor* c); - // @cmember Distruttore - ~TBrowse(); - - // @cmember Controlla la sintassi della join del campo e ne setta i membri - void parse_join(TScanner& scanner); - // @cmember Controlla la sintassi della input del campo e ne setta i membri - void parse_input(TScanner& scanner); - // @cmember Controlla la sintassi della display del campo e ne setta i membri - void parse_display(TScanner& scanner); - // @cmember Controlla la sintassi della output del campo e ne setta i membri - void parse_output(TScanner& scanner); - // @cmember Controlla la sintassi della insert del campo e ne setta i membri - void parse_insert(TScanner& scanner); - // @cmember Controlla la sintassi della copy del campo e ne setta i membri - bool parse_copy(const TString& what, const TBrowse& b); - - // @cmember Permette di settare il comando alla pressione del tasto Gestione - void set_insert(const char* s) - { _insert = s;} - // @cmember Ritorna il valore di

- const TString& get_insert() const - { return _insert;} - - // @cmember Ritorna il valore di

- const TString& get_filter() const - { return _filter;} - - // @cmember Cambia il filtro della browse - void set_filter(const char * filter) - { _filter = filter;} - - // @cmember Cambia il cursore della browse - void set_cursor(TCursor * c); - - // @cmember Cambia il filtro della browse - void set_custom_filter_handler(CONTROL_HANDLER custom_filter_handler) { _custom_filter_handler = custom_filter_handler;} - - // @cmember Controlla la validita' del campo - bool check(CheckTime = RUNNING_CHECK); - // @cmember Controlla se il campo puo' essere vuoto - bool empty_check(); - // @cmember Ritorna il valore di

- const TToken_string& head() const - { return _head;} - // @cmember Ritorna il valore di

- const TToken_string& items() const - { return _items;} - // @cmember Ritorna il valore di

- TCursor* cursor() const - { return _cursor;} - // @cmember Ritorna il valore di

- bool checked() const - { return _checked;} - // @cmember Ritorna il valore di

- bool secondary() const - { return _secondary;} - - virtual bool is_browse() const { return true; } - - // @cmember Esegue la ricerca. Torna il tasto che ha terminato la ricerca - virtual KEY run(); -}; - -class TFile_select : public TBrowse_button -{ - TFilename _filter; - -public: - // @cmember Controlla la sintassi della input del campo e ne setta i membri - virtual void parse_input(TScanner& scanner); - - // @cmember Controlla la sintassi della output del campo e ne setta i membri - virtual void parse_output(TScanner& scanner); - - virtual KEY run(); - - // @cmember Controlla la validita' del campo - virtual bool check(CheckTime = RUNNING_CHECK); - - virtual bool is_filesel() const { return true; } - - TFile_select(TEdit_field* ef, const char* filter); - virtual ~TFile_select() { } -}; - -class TDir_select : public TBrowse_button -{ -public: - // @cmember Controlla la sintassi della input del campo e ne setta i membri - virtual void parse_input(TScanner& scanner); - - // @cmember Controlla la sintassi della output del campo e ne setta i membri - virtual void parse_output(TScanner& scanner); - - virtual KEY run(); - - // @cmember Controlla la validita' del campo - virtual bool check(CheckTime = RUNNING_CHECK); - - virtual bool is_filesel() const { return TRUE; } - - TDir_select(TEdit_field* ef); - virtual ~TDir_select() { } -}; - -class TReport_select : public TBrowse_button -{ - TString _classe; - -public: - // @cmember Controlla la sintassi della input del campo e ne setta i membri - virtual void parse_input(TScanner& scanner); - - // @cmember Controlla la sintassi della output del campo e ne setta i membri - virtual void parse_output(TScanner& scanner); - - virtual KEY run(); - - // @cmember Controlla la validita' del campo - virtual bool check(CheckTime = RUNNING_CHECK); - - virtual bool is_filesel() const { return true; } - - TReport_select(TEdit_field* ef, const char* classe); - virtual ~TReport_select() { } -}; - - -class TProfile_select : public TBrowse_button -{ -protected: - // @cmember Controlla la sintassi della input del campo e ne setta i membri - virtual void parse_input(TScanner& scanner); - - // @cmember Controlla la sintassi della output del campo e ne setta i membri - virtual void parse_output(TScanner& scanner); - -public: - virtual KEY run(); - - // @cmember Controlla la validita' del campo - virtual bool check(CheckTime = RUNNING_CHECK); - - // @cmember E' un campo profilo - virtual bool is_profile() const { return true; } - - // @cmember Estrae dal .ini tutti i profili - int get_descriptions(TString_array& a) const; - - TProfile_select(TEdit_field* ef); - virtual ~TProfile_select() { } -}; // @doc EXTERNAL +#ifndef __BRWBUT_H +#include +#endif + // @class TEdit_field | Classe per la definizione dei campi editabili // // @base public | TEditable_field diff --git a/include/msksheet.cpp b/include/msksheet.cpp index 63f4626fc..35bef386e 100755 --- a/include/msksheet.cpp +++ b/include/msksheet.cpp @@ -1158,7 +1158,7 @@ bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev) const real r(src); // Memorizzo valore numerico const int pos = driver->dlg() - FIRST_FIELD; const TString4 codval = rowrec.get(pos); // Codice valuta - const TCurrency c(r, codval, ZERO, _exchange_undefined, e->uppercase()); + const TCurrency c(r, codval, ZERO, e->uppercase()); src = c.string(true); break; } diff --git a/include/sheet.cpp b/include/sheet.cpp index c9aa6a6ad..2eb785e65 100755 --- a/include/sheet.cpp +++ b/include/sheet.cpp @@ -1683,7 +1683,7 @@ bool TBrowse_sheet::browse_field_handler(TMask_field& f, KEY k) TBrowse* b = e.browse(); if (b != NULL) { - b->do_input(FALSE); + b->do_input(false); rec = b->cursor()->read(_isgteq); } } diff --git a/include/validate.cpp b/include/validate.cpp index 41a3f260e..a874b15b7 100755 --- a/include/validate.cpp +++ b/include/validate.cpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include @@ -17,9 +17,7 @@ HIDDEN int get_val_param_count() HIDDEN const TString& get_val_param(int i) { const TString* str = (const TString*)_parms->objptr(i); - if (str && *str) - return *str; - return EMPTY_STRING; + return str ? *str : EMPTY_STRING; } HIDDEN int get_int_val_param(int i) @@ -524,7 +522,7 @@ HIDDEN bool _mtcheck_val(TMask_field& f, KEY) const int month = atoi(f.get()); if (month < 1 || month > 13) return false; - +/* TLocalisamfile d(LF_NDITTE); d.put(NDT_CODDITTA, prefix().get_codditta()); if (d.read() != NOERR) @@ -532,6 +530,11 @@ HIDDEN bool _mtcheck_val(TMask_field& f, KEY) if (d.get_char(NDT_FREQVIVA) == 'M') return true; return month == 13 || (month % 3) == 0; +*/ + if (month == 13 || (month % 3) == 0) + return true; + const TRectype& ndt = cache().get(LF_NDITTE, prefix().get_codditta()); + return ndt.get_char(NDT_FREQVIVA) == 'M'; } diff --git a/include/viswin.cpp b/include/viswin.cpp index c9963b4af..e65cae863 100755 --- a/include/viswin.cpp +++ b/include/viswin.cpp @@ -547,7 +547,9 @@ void TViswin::shift_screen(scroll dir) case down: xvt_rect_set(&r, 0, taby(Y_OFFSET)/*+1*/, tabx(int(_textcolumns) + X_OFFSET), taby(int(_textrows) + Y_OFFSET)); + xvt_dwin_scroll_rect (win(), &r, 0, dir == down ? taby(1) : -taby(1)); + paint_row (dir == up ? origin ().y + _textrows - 1 : origin ().y); break; case left: @@ -1554,18 +1556,6 @@ long TViswin::handler (WINDOW win, EVENT * ep) break; case E_MOUSE_MOVE: { - /* - if (!_selecting && !_iscross) // no buttons pressed - { - p = ep->v.mouse.where; - if (in_text (p)) - { - p.x += (origin ().x - 6); - p.y += (origin ().y - 1); - check_link (&p); - } - } - */ if (_selecting || _iscross) { autoscroll(FALSE); @@ -1722,7 +1712,9 @@ long TViswin::handler (WINDOW win, EVENT * ep) erase_selection (); check_link (); update_thumb (origin().x, origin().y - 1l); - _need_scroll = down; + //_need_scroll = down; + update (); // AAAARGH! + check_link (&_point); } else scroll_error(-1, 0); } @@ -1785,7 +1777,10 @@ long TViswin::handler (WINDOW win, EVENT * ep) check_link (); update_thumb (origin ().x, origin ().y + 1l); _point.y++; - _need_scroll = up; + + // _need_scroll = up; + update (); // AAAARGH! + check_link (&_point); } else scroll_error(-1, _txt.lines()-_textrows/*-1*/); }