#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ba2800a.h" /////////////////////////////////////////////////////////// // Utilities /////////////////////////////////////////////////////////// const TString& smart_trim(const TString& str, int len) { TString& tmp = get_tmp_string(); tmp = str; tmp.trim(); if (tmp.len() > len) { TParagraph_string p(tmp, len); tmp = p.get(); } return tmp; } int smart_cmp(const char* s1, const char* s2) { if (s1 == NULL || *s1 <= ' ') s1 = ""; if (s2 == NULL || *s2 <= ' ') s2 = ""; if (isdigit(*s1) && isdigit(*s2)) return atoi(s1) - atoi(s2); return xvt_str_compare_ignoring_case(s1, s2); } ///////////////////////////////////////////////////////////a // TOEM_cache /////////////////////////////////////////////////////////// class TOEM_cache : public TObject { public: int Agente2OEM(int agente) const; TOEM_cache(); }; // Trasforma un codice OEM del DB in quello di oem.ini int TOEM_cache::Agente2OEM(int agente) const { int oem = -1; switch (agente) { case 2: oem = 0; break; // Aga case 3: oem = 3; break; // Geisoft case 5: oem = 6; break; // Sipag -> Sicuri case 7: oem = 7; break; // Prassi Roma -> Itertec case 8: // Prassi Calabria case 9: oem = 8; break; // Metacalabria case 10: oem = 6; break; // Socogem -> Sicuri case 11: oem = 7; break; // Itertec case 13: oem = 2; break; // Tetractis case 14: oem = 9; break; // San Zeno informatica default: oem = 1; break; // Sirio } return oem; } // Carica la lista di tutti gli OEM dal file setup/oem.ini TOEM_cache::TOEM_cache() { } /////////////////////////////////////////////////////////// // Tdnist_full /////////////////////////////////////////////////////////// class Tdnist_full { TArray _chiavi; public: void set(int key, const char* var, const TString& value); TAssoc_array* get_all(int key) const; const TString& get(int key, const char* var) const; int last() const { return _chiavi.last(); } bool exists(int key) const { return _chiavi.objptr(key) != NULL; } bool load(); bool save(int version) const; }; #define DNINST "setup/dninst." const char* const DNINST_ZIP = DNINST"zip"; const char* const DNINST_TXT = DNINST"txt"; const char* const DNINST_BAK = DNINST"bak"; void Tdnist_full::set(int key, const char* var, const TString& value) { CHECKD(key > 0, "Invalid key ", key); TAssoc_array* info = (TAssoc_array*)_chiavi.objptr(key); if (info == NULL) { info = new TAssoc_array; _chiavi.add(info, key); } if (value.full()) info->add(var, value, true); else info->remove(var); } TAssoc_array* Tdnist_full::get_all(int key) const { TAssoc_array* info = (TAssoc_array*)_chiavi.objptr(key); return info; } const TString& Tdnist_full::get(int key, const char* var) const { const TAssoc_array* info = get_all(key); if (info == NULL) return EMPTY_STRING; const TString* val = (const TString*)info->objptr(var); return val ? *val : EMPTY_STRING; } // Decodifica l'intero dninst.zip in memoria bool Tdnist_full::load() { _chiavi.destroy(); TFilename txt = DNINST_TXT; Tdninst dninst; if (dninst.decode(txt)) { TScanner s(txt); const int anno = atoi(s.line()); int key = 0; TString16 var; TString256 val; while (s.good()) { TString& line = s.line(); if (line[0] == '[') { line.strip("[]"); key = atoi(line); } else { if (key > 0) { const int equal = line.find('='); if (equal > 0) { var = line.left(equal); var.trim(); val = line.mid(equal+1); val.strip("\""); val.trim(); set(key, var, val); } } } } } else cantread_box(DNINST_ZIP); return !_chiavi.empty(); } bool Tdnist_full::save(int version) const { Tdninst dninst; bool done = dninst.ok(); if (done) { int ass_year = 2151; if (version < 12) ass_year = version < 11 ? 2101 : 2121; ofstream out(DNINST_TXT); out << ass_year << endl; FOR_EACH_ARRAY_ITEM(_chiavi, key, obj) { out << '[' << key << ']' << endl; TAssoc_array& info = (TAssoc_array&)*obj; FOR_EACH_ASSOC_OBJECT(info, o, k, i) out << k << '=' << *i << endl; } } if (done) { done = dninst.encode(DNINST_TXT); #ifdef DBG if (version == 12) fcopy(DNINST_TXT, "../src/setup/dninst.txt"); #endif } return done; } /////////////////////////////////////////////////////////// // Tdninst_mask /////////////////////////////////////////////////////////// static int _c_key, _c_oem, _c_owner, _c_suspend, _c_killed; static int _c_dboem, _c_dbowner, _c_dbsuspend, _c_dbkilled; static int _c_xmloem, _c_xmlowner, _c_xmlyear, _c_xmlaccess; class Tdninst_mask : public TAutomask { TOEM_cache _oem; Tdnist_full _dninst; private: static int dongle_compare(const TSortable& o1, const TSortable& o2, void* jolly); const TString& remote_dninst(int version) const; void load_dninst(TString_array& a); bool load_odbc(TString_array& a) const; bool load_xml(TString_array& a) const; TToken_string& find_or_create_line(TString_array& a, int key) const; protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); bool on_sheet_event(TSheet_field& s, TField_event e, long jolly); bool fill_sheet(); void merge_sheet(); void save_sheet(); void log(int severity, const char* msg) const; bool get_remote_dninst(); bool send_remote_dninst(const TString& ftp) const; public: void overnight_batch(); Tdninst_mask(); }; void Tdninst_mask::log(int severity, const char* msg) const { FILE* f = fopen("DNINST.log", "a"); if (f != NULL) { if (msg && *msg > ' ') { char sev = ' '; switch (severity) { case 0: sev = ' '; break; case 1: sev = '-'; break; default: sev = '!'; break; } time_t rawtime; time(&rawtime); struct tm * timeinfo = localtime (&rawtime); fprintf(f, "%c %02d-%02d-%04d %02d:%02d:%02d %s\n", sev, timeinfo->tm_mday, timeinfo->tm_mon, timeinfo->tm_year+1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, msg); } else fputc('\n', f); fclose(f); } } void Tdninst_mask::overnight_batch() { log(0, TR("Inizio procedura aggiornamento DNINST")); set(F_ZIP_ON, "X"); set(F_DSN_ON, "X"); set(F_XML_ON, ""); on_field_event(efield(F_ZIP_WWW), fe_init, 0); on_field_event(efield(F_DSN_WWW), fe_init, 0); log(0, TR("Caricamento dati da DSN")); if (get_remote_dninst()) { fill_sheet(); log(0, TR("Elaborazione abilitazioni")); merge_sheet(); log(0, TR("Salvataggio dati")); save_sheet(); } log(0, TR("Fine procedura aggiornamento DNINST")); log(0, "\n"); } int Tdninst_mask::dongle_compare(const TSortable& o1, const TSortable& o2, void* jolly) { TToken_string& d1 = (TToken_string&)o1; TToken_string& d2 = (TToken_string&)o2; const int sort = *(int*)jolly; if (sort == 1) { const char* o1 = d1.get(_c_oem); if (o1 == NULL || *o1 <= ' ') o1 = d1.get(_c_dboem); const char* o2 = d2.get(_c_oem); if (o2 == NULL || *o2 <= ' ') o2 = d2.get(_c_dboem); const int cmp = smart_cmp(o1, o2); if (cmp != 0) return cmp; } else if (sort == 3) { const TDate a1 = d1.get(_c_xmlaccess); const TDate a2 = d2.get(_c_xmlaccess); int cmp = a2.date2ansi() - a1.date2ansi(); if (cmp == 0) cmp = atoi(d1) - atoi(d2); return cmp; } if (sort >= 1) { const char* o1 = d1.get(_c_owner); if (o1 == NULL || *o1 <= ' ') o1 = d1.get(_c_dbowner); const char* o2 = d2.get(_c_owner); if (o2 == NULL || *o2 <= ' ') o2 = d2.get(_c_dbowner); const int cmp = smart_cmp(o1, o2); if (cmp != 0) return cmp; } return atoi(d1) - atoi(d2); } const TString& Tdninst_mask::remote_dninst(int version) const { if (!get_bool(F_ZIP_ON) || field(F_ZIP_WWW).empty()) return EMPTY_STRING; if (version < 10) { int year, tag, patch; main_app().get_version_info(year, version, tag, patch); } TString& path = get_tmp_string(); path << "ftp://" << get(F_ZIP_USR) << ':' << get(F_ZIP_PWD) << '@' << get(F_ZIP_WWW) << '/' << get(F_ZIP_USR) << "/release/v_" << version << ".0/program/" << DNINST_ZIP; return path; } void Tdninst_mask::load_dninst(TString_array& a) { _dninst.load(); const int last_key = _dninst.last(); TToken_string str; for (int key = 1; key <= last_key; key++) if (_dninst.exists(key)) { str.cut(0) << key; str.add(_dninst.get(key, "OEM"), _c_oem); str.add(smart_trim(_dninst.get(key, "Owner"), 50), _c_owner); str.add(_dninst.get(key, "MustCall"), _c_suspend); str.add(_dninst.get(key, "*"), _c_killed); a.add(str); } } TToken_string& Tdninst_mask::find_or_create_line(TString_array& a, int key) const { int mi = 0, ma = a.last(); int k = 0; while (mi <= ma) { const int me = (mi+ma)/2; k = a.row(me).get_int(0); if (k == key) return a.row(me); if (k < key) mi = me+1; else ma = me-1; } while (mi < a.items() && key > a.row(mi).get_int(0)) mi++; TToken_string* str = new TToken_string; str->add(key); a.insert(str, mi); return *str; } bool Tdninst_mask::load_odbc(TString_array& a) const { const TString& dsn = get(F_DSN_WWW); bool done = false; if (dsn.full()) { TString query; query << "ODBC(" << dsn << ")\n" << "SELECT chiavette.Codice, chiavette.Cliente, clienti.RagioneSociale, clienti.Agente, clienti.DataDisattivazione, clienti.Stato" << "\nFROM chiavette JOIN clienti ON chiavette.cliente=clienti.codice" << "\nORDER BY Codice"; TODBC_recordset att(query); TProgress_monitor pi(att.items(), dsn); for (bool ok = att.move_first(); ok; ok = att.move_next()) { if (!pi.add_status()) break; const int key = att.get("Codice").as_int(); if (key > 0) { TToken_string& r = find_or_create_line(a, key); const int agente = att.get("Agente").as_int(); r.add(_oem.Agente2OEM(agente), _c_dboem); r.add(smart_trim(att.get("RagioneSociale").as_string(), 50), _c_dbowner); TString16 kill; TString16 stato = att.get("Stato").as_string(); if (stato[0] > 'A') // Non Attivo kill = att.get("DataDisattivazione").as_string(); if (kill.blank()) { query.cut(0); query << "ODBC(" << dsn << ")\n" << "SELECT Chiave,DataAttivazione,DataScadenza\n" << "FROM attivazioni WHERE Modulo IS NULL AND Chiave=" << r.get(0); TODBC_recordset ad(query); for (bool ok = ad.move_first(); ok; ok = ad.move_next()) { const TString& attivaz = ad.get("DataAttivazione").as_string(); const TString& disatt = ad.get("DataScadenza").as_string(); if (disatt > kill) kill = disatt; else if (attivaz > kill) kill.cut(0); } if (kill.full()) stato = "Disdetto"; } if (kill.full() && kill.len() == 10) { TDate d; if (kill[2] == '-') d = TDate(kill); else if (kill[4] == '-') d = TDate(atol(kill.strip("-"))); if (d.year() >= 1990) { switch (stato[0]) { case 'D': r.add(d.string(), _c_dbkilled); break; // Disdetto case 'S': r.add(d.string(), _c_dbsuspend); break; // Sospeso default: break; // Attivo } } } done = true; } } } if (!done) { if (is_running()) cantread_box(dsn); else { TString msg; msg << TR("Impossibile leggere i dati da ") << dsn; log(2, msg); } } return done; } static bool XmlScanner(TXmlItem& item, long jolly) { TToken_string& row = *(TToken_string*)jolly; if (item.GetTag() == "firm") { if (item.GetBoolAttr("Current")) row.add(item.GetAttr("RAGSOC"), _c_xmlowner); } else if (item.GetTag() == "dongle") { row.add(item.GetAttr("OEM"), _c_xmloem); const int year_new = item.GetIntAttr("Year"); const int year_old = row.get_int(_c_xmlyear); if (year_new > year_old) row.add(year_new, _c_xmlyear); } else if (item.GetTag() == "module") { const TDate date_new = item.GetAttr("Date"); const TDate date_old = row.get(_c_xmlaccess); if (date_new > date_old) row.add(date_new, _c_xmlaccess); } return false; } bool Tdninst_mask::load_xml(TString_array& a) const { TFilename path; path << "ftp://" << get(F_XML_USR) << ':' << get(F_XML_PWD) << '@' << get(F_XML_WWW) << "/attivazioni/?????.xml"; TString_array xml; list_files(path, xml); TString msg; msg.format(FR("Scansione %s: %d files"), (const char*)path, xml.items()); TProgress_monitor pi(xml.items(), msg); TFilename fname, tmpname; TFilename tmpdir; tmpdir.tempdir(); tmpdir.add("www"); FOR_EACH_ARRAY_ROW(xml, r, row) { if (!pi.add_status()) break; fname = *row; const TString& n = fname.name_only(); const int sn = atoi(n); if (sn > 0) { TToken_string& r = find_or_create_line(a, sn); tmpname = tmpdir; tmpname.add(fname.name()); TXmlItem i; bool scan = false; if (!tmpname.exist()) { scan = i.Load(fname); i.Save(tmpname); } else scan = i.Load(tmpname); if (scan) i.ForEach(XmlScanner, (long)&r); } } return !xml.empty(); } bool Tdninst_mask::get_remote_dninst() { TFilename rem12 = remote_dninst(12); TFilename loc12; loc12.temp("dni12", "zip"); if (rem12.full()) fcopy(rem12, loc12, false, true); TFilename rem11 = remote_dninst(11); TFilename loc11; loc11.temp("dni11", "zip"); if (rem11.full()) fcopy(rem11, loc11, false, true); if (fsize(loc12) >= fsize(loc11)) fcopy(loc12, DNINST_BAK); else fcopy(loc11, DNINST_BAK); loc11.fremove(); loc12.fremove(); const int minsize = 46*1024; const int size = fsize(DNINST_BAK); if (size > minsize) { fcopy(DNINST_BAK, DNINST_ZIP); remove(DNINST_BAK); return true; } TString msg; msg << TR("Il file dninst.zip remoto pesa solo ") << size << " bytes"; if (is_running()) error_box(msg); else log(2, msg); return false; } bool Tdninst_mask::fill_sheet() { TSheet_field& s = sfield(F_DNSHEET); s.destroy(); TString_array& a = s.rows_array(); load_dninst(a); if (a.empty()) return false; if (get_bool(F_DSN_ON) && !field(F_DSN_WWW).empty()) { if (!load_odbc(a)) return false; } if (get_bool(F_XML_ON) && !field(F_XML_WWW).empty()) load_xml(a); const int sort = get_int(F_SORT); a.TArray::sort(dongle_compare, (void*)&sort); FOR_EACH_ARRAY_ROW(a, r, row) { const char* o1 = row->get(_c_owner); const char* o2 = row->get(_c_dbowner); const char* o3 = row->get(_c_xmlowner); if (o2 && *o2 > ' ') { const double cmp = xvt_str_fuzzy_compare_ignoring_case(o1, o2); if (cmp < 0.7) { if (cmp == 0) s.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, r, _c_dbowner); else s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, r, _c_dbowner); } } if (o3 && *o3 > ' ') { const char* o1 = row->get(2); const double cmp = xvt_str_fuzzy_compare_ignoring_case(o1, o3); if (cmp < 0.7) { if (cmp == 0) s.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, r, _c_xmlowner); else s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, r, _c_xmlowner); } } TDate ds = row->get(_c_suspend); TDate dk = row->get(_c_killed); if (dk > ds) ds = dk; TDate dbs = row->get(_c_dbsuspend); TDate dbk = row->get(_c_dbkilled); if (dbk > dbs) dbs = dbk; if (ds != dbs) { if (dbs.ok()) s.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, r, _c_suspend); else s.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, r, _c_dbsuspend); } if (dk != dbk) { if (dbk.ok()) s.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, r, _c_killed); else s.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, r, _c_dbkilled); } } s.force_update(); const bool on = !s.empty(); enable(DLG_ELABORA, on); enable(DLG_SAVEREC, on); return true; } void Tdninst_mask::merge_sheet() { TLog_report log; TString msg; TSheet_field& sheet = sfield(F_DNSHEET); TString16 killed; TString o1, o2, o3; TString c1, c2, c3; TString d1, d2; int changed = 0; FOR_EACH_SHEET_ROW(sheet, r, row) { const int key = row->get_int(_c_key); c1 = row->get(_c_owner); c2 = row->get(_c_dbowner); c3 = row->get(_c_xmlowner); if (c1.blank()) { if (c2.full()) { c1 = c2; o1 = row->get(_c_dboem); } if (c3.full()) { c1 = c3; o1 = row->get(_c_xmloem); } if (c1.full()) { row->add(o1, _c_oem); row->add(c1, _c_owner); changed++; msg.cut(0) << key << " : "; msg << TR("Inserito cliente ") << c1; log.log(0, msg); } } else { o1 = row->get(_c_oem); if (o1.blank()) { o2 = row->get(_c_dboem); if (o2.full()) { row->add(o2, _c_oem); changed++; msg.cut(0) << key << " : "; msg << TR("Aggiornato agente del cliente ") << c1; log.log(0, msg); } } c2 = row->get(_c_dbowner); if (c2.full() && c1 != c2) { row->add(c2, _c_owner); changed++; if (xvt_str_fuzzy_compare_ignoring_case(c1, c2) < 0.7) { msg.cut(0) << key << " : "; msg << TR("Aggiornata ragione sociale da '") << c1 << "' a '" << c2 << "'"; log.log(0, msg); } } } d1 = row->get(_c_suspend); d1.trim(); d2 = row->get(_c_dbsuspend); d2.trim(); if (d2.full() && d1 != d2) { row->add(d2, _c_suspend); changed++; msg.cut(0) << key << " : "; msg << TR("Sospensione del cliente ") << c1 << TR(" dal ") << d2; log.log(1, msg); } d1 = row->get(_c_killed); d1.trim(); d2 = row->get(_c_dbkilled); d2.trim(); if (d2.full() && d1 != d2) { row->add(d2, _c_killed); changed++; msg.cut(0) << key << " : "; msg << TR("Disattivazione del cliente ") << c1 << TR(" dal ") << d2; log.log(2, msg); } } sheet.force_update(); log.preview(); } bool Tdninst_mask::send_remote_dninst(const TString& ftp) const { int at = ftp.find('@', 6); if (at < 0) at = 5; int slash = ftp.find('/', at+1); const TString& server = ftp.sub(at+1, slash); bool sent = false; TSocketClient aga; CONNID id = aga.QueryConnection("21", server); if (id > 0) { TString16 user = "guastalla", password = "tk0nmo4q3"; const int colon = ftp.find(':', 6); if (colon > 6 && colon < at) { user = ftp.sub(6, colon); password = ftp.sub(colon+1, at); } sent = aga.FtpSendFile(id, ftp.mid(slash), DNINST_ZIP, user, password); aga.RemoveConnection(id); } if (!sent) { if (is_running()) cantwrite_box(ftp); else { TString msg; msg << TR("Impossibile aggiornare il file ") << ftp; log(2, msg); } } return sent; } void Tdninst_mask::save_sheet() { TSheet_field& sheet = sfield(F_DNSHEET); TString str; FOR_EACH_SHEET_ROW(sheet, r, row) { const int key = row->get_int(0); if (key > 0) { str = row->get(_c_oem); _dninst.set(key, "OEM", str.trim()); str = row->get(_c_owner); _dninst.set(key, "Owner", str.trim()); str = row->get(_c_suspend); _dninst.set(key, "MustCall", str.trim()); str = row->get(_c_killed); _dninst.set(key, "*", str.trim()); } } if (fcopy(DNINST_ZIP, DNINST_BAK)) { int y, v, t, p; main_app().get_version_info(y, v, t, p); const int curr = v; for (int prev = 10; prev <= curr; prev++) if (_dninst.save(prev)) { fill_sheet(); const TFilename ftp = remote_dninst(prev); if (ftp != DNINST_ZIP && ftp.starts_with("ftp://")) if (!is_running() || yesno_box(FR("Copiare il DNINST locale in %s?"), (const char*)ftp)) send_remote_dninst(ftp); } fcopy(DNINST_BAK, DNINST_ZIP); remove(DNINST_BAK); _dninst.save(curr); } } bool Tdninst_mask::on_sheet_event(TSheet_field& s, TField_event e, long jolly) { static word _last_serno = 0; switch (e) { case se_query_add: // Lascio aggiungere una riga alla volta { TToken_string& r = s.row(s.items()-1); _last_serno = r.get_int(0); if (_last_serno > 0) { char str[8] = ""; xvt_dm_post_string_prompt(TR("Inserire il numero di serie"), str, sizeof(str)); _last_serno = atoi(str); if (_last_serno > 0) { FOR_EACH_SHEET_ROW(s, r, row) { if (row->get_int(0) == _last_serno) { error_box(TR("Chiave già inserita")); s.post_select(r); _last_serno = 0; break; } } } } return _last_serno > 0; } case se_notify_add: s.row(jolly).add(_last_serno, 0); break; case se_notify_modify: { TToken_string& r = s.row(jolly); const int serno = r.get_int(0); if (serno == _last_serno) { if (yesno_box(FR("Si desidera salvare la nuova chiave %d?"), serno)) send_key(K_SPACE, DLG_SAVEREC, &s); _last_serno = 0; } } break; case se_query_del: { TToken_string& r = s.row(jolly); const int serno = r.get_int(0); return delete_box("Si desidera eliminare la chiave %d", serno); } break; default: break; } return true; } bool Tdninst_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case DLG_RECALC: if (e == fe_button && check_fields()) { get_remote_dninst(); fill_sheet(); } break; case DLG_ELABORA: if (e == fe_button && yesno_box(TR("Aggiornare il DNINST in base al DB"))) merge_sheet(); break; case DLG_SAVEREC: if (e == fe_button) save_sheet(); break; case F_ZIP_ON: if (e == fe_init && o.get().empty()) set(F_ZIP_ON, "X", 0x1); break; case F_ZIP_WWW: if ((e == fe_init || e == fe_modify || e == fe_close) && o.empty()) { set(F_ZIP_WWW, "93.146.247.172"); set(F_ZIP_USR, "guastalla"); set(F_ZIP_PWD, "tk0nmo4q3"); } break; case F_DSN_WWW: if (e == fe_button) { if (o.empty()) { TConfig odbc("c:/windows/odbc.ini", "ODBC 32 bit Data Sources"); TAssoc_array& var = odbc.list_variables(); if (!var.empty()) { TArray_sheet dsn(-1, -1, 78, 20, TR("Sorgenti dati ODBC"), HR("Nome@25|Driver@50")); TToken_string row; FOR_EACH_ASSOC_OBJECT(var, obj, key, itm) { row = key; row.add(*(TString*)itm); dsn.add(row); } if (dsn.run() == K_ENTER) o.set(dsn.row(-1).get(0)); } } else { TString query; query << "ODBC(" << o.get() << ")\n" << "SELECT chiavette.Codice AS Chiave, chiavette.Cliente, clienti.RagioneSociale AS 'Ragione Sociale', " << "clienti.Stato, clienti.DataDisattivazione AS Data, " << "agenti.Codice AS Agente, agenti.RagioneSociale AS Rivenditore" << "\nFROM (chiavette JOIN clienti ON chiavette.cliente=clienti.codice) JOIN agenti ON clienti.Agente=agenti.Codice" << "\nORDER BY "; switch (get_int(F_SORT)) { case 1: query << "Agente,clienti.RagioneSociale,Chiave"; break; case 2: query << "clienti.RagioneSociale,Chiave"; break; default: query << "Chiave"; break; } TODBC_recordset att(query); bool connected = false; if (!connected) // Dummy test { TWait_cursor hourglass; connected = att.move_first(); } if (connected) { TRecordset_sheet sheet(att, TR("Chiavi"),0x10); sheet.run(); } } } break; case F_XML_WWW: if ((e == fe_init || e == fe_modify || e == fe_close) && o.empty()) { o.set("93.146.247.172"); set(F_XML_USR, "attivazioni"); set(F_XML_PWD, "viagra"); } break; case F_SORT: if (e == fe_modify) { TSheet_field& s = sfield(F_DNSHEET); const int sort = get_int(F_SORT); s.rows_array().TArray::sort(dongle_compare, (void*)&sort); s.force_update(); } break; case F_DNSHEET: if (o.is_sheet()) return on_sheet_event((TSheet_field&)o, e, jolly); break; case F_SUSPEND: case F_KILLED: if (e == fe_magic) { const TDate oggi(TODAY); o.set(oggi.string()); } break; case DLG_USER: if (e == fe_button && jolly > 0) { TAssoc_array* vars = _dninst.get_all(o.mask().get_int(F_NUMBER)); if (vars != NULL) { TToken_string str(255, '\n'); FOR_EACH_ASSOC_STRING((*vars), h, k, i) str << k << " = " << i << '\n'; TMask m(TR("Personalizzazioni"), 1, 78, 16); m.add_button_tool(DLG_OK, TR("OK"), TOOL_OK); m.add_button_tool(DLG_CANCEL, TR("Annulla"), TOOL_CANCEL); m.add_memo(101, 0, "", 1, 0, -1, -1); m.set(101, str); if (m.run() == K_ENTER) { str = m.get(101); if (str.items() > 1) { vars->destroy(); FOR_EACH_TOKEN(str, tok) { TToken_string line(tok, '='); if (line.items() == 2) { TString80 key = line.get(0); key.trim(); if (key.full()) { TString val = line.get(1); val.trim(); vars->add(key, val); } } } } } } } break; default: break; } return true; } Tdninst_mask::Tdninst_mask() : TAutomask("ba2800a") { const TSheet_field& s = sfield(F_DNSHEET); TMask& m = s.sheet_mask(); _c_key = s.cid2index(F_NUMBER); _c_oem = s.cid2index(F_OEM); _c_owner = s.cid2index(F_OWNER); _c_suspend = s.cid2index(F_SUSPEND); _c_killed = s.cid2index(F_KILLED); _c_dboem = s.cid2index(F_DBOEM); _c_dbowner = s.cid2index(F_DBOWNER); _c_dbsuspend= s.cid2index(F_DBSUSPEND); _c_dbkilled = s.cid2index(F_DBKILLED); _c_xmloem = s.cid2index(F_ATOEM); _c_xmlowner = s.cid2index(F_ATOWNER); _c_xmlyear = s.cid2index(F_ATYEAR); _c_xmlaccess= s.cid2index(F_ATACCESS); disable(DLG_ELABORA); disable(DLG_SAVEREC); } /////////////////////////////////////////////////////////// // Tdninst_manager /////////////////////////////////////////////////////////// class Tdninst_manager : public TSkeleton_application { protected: virtual bool use_files() const { return false; } virtual bool create(); virtual void main_loop(); virtual bool test_assistance_year(bool) const { return true; } }; bool Tdninst_manager::create() { if (user().compare(dongle().administrator(),-1,true) || !has_module(GDAUT)) return cantaccess_box(title()); TSheet_field::set_line_number_width(4); // Numero di chiavette ~ 1000 return TSkeleton_application::create(); } void Tdninst_manager::main_loop() { Tdninst_mask m; const TFixed_string a(argv(1)); if (a == "-A" || a == "/A") m.overnight_batch(); else m.run(); } int ba2800(int argc, char* argv[]) { Tdninst_manager a; a.run(argc, argv, TR("Gestione attivazioni")); return 0; }