diff --git a/include/filetext.cpp b/include/filetext.cpp index a3b7edd51..0d5058143 100755 --- a/include/filetext.cpp +++ b/include/filetext.cpp @@ -3,7 +3,9 @@ //////////////////////////////////////// TTracciato_Campo //////////////////////////////////////// TTracciato_campo::TTracciato_campo(int position, int length, int decimal, const char align, const char filler) - :_position(position), _length(length), _decimal(decimal), _align(align), _filler(filler) {} + : _position(position), _length(length), _decimal(decimal), + _datatype('S'), _align(align), _filler(filler) +{} TObject* TTracciato_campo::dup() const { @@ -70,8 +72,6 @@ const TString& TFile_text::fpicture(const TTracciato_campo &tc ) const return ((TTracciato_campo &)_tipi[tc.ftype()]).picture(); } - - //////////////////////////////////////// TTracciato_record //////////////////////////////////////// void TTracciato_record::set_relation(TRelation* rel) @@ -507,8 +507,14 @@ int TFile_text::read(TRecord_text& rec) } else { - TString16 tipo = buffer.mid(_typepos, _typelen); - tipo.trim(); + TString16 tipo; + + if (_typepos >= 0 && _typelen > 0) + { + tipo = buffer.mid(_typepos, _typelen); + tipo.trim(); + } + rec.set_type(tipo);//istanzio il tipo del record text TTracciato_record* tr = t_rec(tipo); if (tr != NULL) @@ -521,8 +527,11 @@ int TFile_text::read(TRecord_text& rec) TTracciato_campo& tc = tr->get(i); const int pos = tc.position(); const int len = tc.length(); - const char* lavoro = buffer.mid(pos, len); - rec.add(lavoro, i); + if (pos >= 0 && len > 0) + { + const char* lavoro = buffer.mid(pos, len); + rec.add(lavoro, i); + } } } } @@ -720,10 +729,10 @@ int TFile_text::_autosave(TRelation& rel, const TRecord_text& rec, TTracciato_re valore = numero.string(fpicture(tc));//formatta il numero secondo le specifiche del tracciato int length = flength(tc,rel_rec); - if (falign(tc) == 'R') - valore.right_just(length, ffiller(tc)); - else + if (falign(tc) == 'L') valore.left_just(length, ffiller(tc)); + else + valore.right_just(length, ffiller(tc)); int j = valore.replace('.', _decsep); //!?!?! consento decsep diversi per isam e text ? CHECK(j >= 0 && j <= 1 , "Impossibile scrivere più separatori decimali."); } @@ -762,10 +771,16 @@ const TString& TFile_text::get_field(const TRecord_text& rec, int ncampo) //Scarica dal record_text il campo const TString& TFile_text::get_field(const TRecord_text& rec, const char* name) { - TTracciato_record& tr = *t_rec(rec.type()); - int ncampo = tr.get_pos(name); - CHECKS(ncampo >= 0, "Campo inesistente ", name); - return rec.row(ncampo); + TTracciato_record* tr = t_rec(rec.type()); + if (tr != NULL) + { + const int ncampo = tr->get_pos(name); + if (ncampo >= 0) + return rec.row(ncampo); + } + + NFCHECK("Campo inesistente %s", name); + return EMPTY_STRING; } //Carica nel record_text il campo alla posizione con il valore già formattato @@ -780,11 +795,22 @@ void TFile_text::add_field(TRecord_text& rec, const int ncampo, const char* val) void TFile_text::add_field(TRecord_text& rec, const char* name, const char* val) { TTracciato_record& tr = *t_rec(rec.type()); - int ncampo = tr.get_pos(name); - CHECKS(ncampo >= 0, "Campo inesistente ", name); - rec.add(val, ncampo); + const int ncampo = tr.get_pos(name); + if (ncampo >= 0) + rec.add(val, ncampo); + else + NFCHECK("Campo inesistente %s", name); } +//Carica nel record_text il campo con il valore già formattato +void TFile_text::add_field(TRecord_text& rec, const char* name, long val) +{ + TString16 str; + str.format("%ld", val); + add_field(rec, name, str); +} + + //Formatta la data in base al tracciato void TFile_text::format_date(const TDate& data, const TString& form, TString& data_str) { diff --git a/include/filetext.h b/include/filetext.h index c60bb779f..673256d15 100755 --- a/include/filetext.h +++ b/include/filetext.h @@ -48,7 +48,7 @@ protected: void copy(const TTracciato_campo& tc);//copia membro a membro public: - TTracciato_campo(int position = -1, int length = -1, int decimal = -1, const char align = 'R', const char filler = ' '); + TTracciato_campo(int position = -1, int length = -1, int decimal = -1, const char align = ' ', const char filler = ' '); TTracciato_campo(const TTracciato_campo& tc){copy(tc);} virtual ~TTracciato_campo() {} virtual TObject* dup() const; @@ -249,6 +249,8 @@ public: void add_field(TRecord_text& rec, const int ncampo, const char* val); //carica nel record_text il campo con il valore già formattato void add_field(TRecord_text& rec, const char* name, const char* val); + //carica nel record_text il campo con il valore + void add_field(TRecord_text& rec, const char* name, long val); //scarica dal record_text il campo alla posizione const TString& get_field(const TRecord_text& rec, int ncampo); //scarica dal record_text il campo di nome diff --git a/include/form.cpp b/include/form.cpp index e36dfb142..12cffbdd8 100755 --- a/include/form.cpp +++ b/include/form.cpp @@ -1765,14 +1765,16 @@ bool TForm_number::update() if (read()) // valuta il campo { TForm_item::update(); - const int nm = (_message.objptr(1) != NULL ? 1 : 0); - do_message(nm); - real n(get()); - n.round(decimals()); - if (!n.is_zero()) + const real oldn(get()); + const int nm = (_message.objptr(1) != NULL && oldn.is_zero()) ? 1 : 0; + do_message(nm); + + TString80 s(get()); + real n(s); + n.round(decimals()); + if (!n.is_zero() || picture().find('@') >= 0) { - TString s(get()); apply_format(s); put_paragraph(s); } @@ -1787,7 +1789,7 @@ void TForm_number::apply_format(TString& s) const { real n(s); TToken_string delim(4, ','); // Stringa con i due delimitatori - TString pic(picture()); // Picture senza delimitatori + TString80 pic(picture()); // Picture senza delimitatori int maxlen = -1; if (pic[0] == '(') // Se ci sono i delimitatori ... @@ -1811,7 +1813,7 @@ void TForm_number::apply_format(TString& s) const } } - s=n.string(pic); // riempi la stringa col valore pitturato + s = n.string(pic); // riempi la stringa col valore pitturato if (maxlen >= 0 && maxlen < s.size()) s.cut(maxlen); @@ -1826,30 +1828,30 @@ void TForm_number::apply_format(TString& s) const if (spc < ld) { TString16 spazi; - spazi.spaces(ld - spc); - s.insert(spazi,0); - spc = ld; - } - s.overwrite(d,spc - ld); - } - d = delim.get(); - if (d.not_empty()) // Se il secondo delimitatore e' valido ... - s << d; // ... aggiungilo alla fine + spazi.spaces(ld - spc); + s.insert(spazi,0); + spc = ld; + } + s.overwrite(d,spc - ld); + } + d = delim.get(); + if (d.not_empty()) // Se il secondo delimitatore e' valido ... + s << d; // ... aggiungilo alla fine } } -// else s = n.string(); } void TForm_number::set_picture(const char *p) { TForm_string::set_picture(p); const int comma = picture().find(','); - if (comma > 0) set_decimals(picture().len() - comma -1); + if (comma >= 0) + set_decimals(picture().len() - comma -1); } const char* TForm_number::example() const { - TString s("123456789120.00"); + TString80 s("123456789120.00"); apply_format(s); return strcpy(__tmp_string, s); } @@ -4241,13 +4243,18 @@ void TForm::arrange_form() // CHR(15), allora prima del posizionamento scrivo il chr(15) sulla stampante! { + TPrinter& pr = printer(); + + if (!os_open_spool_row(pr.printername())) + { + error_box("Impossibile aprire il device %s.", (const char*)pr.printername()); + return; + } + int i, x; TString str_pos; TMask m("ba2100c"); - if (!os_open_spool_row(printer().printername())) - fatal_box("Impossibile aprire il device %s.", (const char*)printer().printername()); - // _ipy viene assunto uguale per entrambi i posizionamneti str_pos = "\017"; // Questo e' 15 in ottale... for (i=1; i < _ipy; i++) str_pos << "\n"; @@ -4271,7 +4278,7 @@ void TForm::arrange_form() os_close_spool_row(); - printer().set_offset(-(_ipy-1), printer().get_column_offset()); + pr.set_offset(-(_ipy-1), printer().get_column_offset()); } long TForm::records() const @@ -4438,6 +4445,8 @@ bool TForm::genera_intestazioni( case 'r': p.right_just(fi.width()); break; + default: + break; } s = new TForm_string(header); s->id() = -1; @@ -4564,7 +4573,8 @@ bool TForm::print( { if (height(t)> (word)pr.formlen()) { - TString s("La lunghezza totale della sezione "); + TString s; + s = "La lunghezza totale della sezione "; switch ( t ) { case odd_page: @@ -4662,9 +4672,10 @@ bool TForm::print( i++; } // fine ciclo di stampa + TPrintrow empty_line; // Perche' static ??? while (fixed_pages() && page(pr) % _npages !=0) { - static TPrintrow empty_line; +// static TPrintrow empty_line; pr.formfeed(); pr.print(empty_line); } diff --git a/include/form.h b/include/form.h index b8dbdac40..ef82905db 100755 --- a/include/form.h +++ b/include/form.h @@ -508,7 +508,7 @@ class TPrint_section : public TObject // @cmember:(INTERNAL) Puntatore alla sezione soprastante (!= NULL se si è in una sottosezione) TForm_subsection * _upsection; // @cmember:(INTERNAL) Array di sottosezioni - TArray _subsections; + TPointer_array _subsections; // @cmember:(INTERNAL) Lista dei campi da stampare TArray _item; // @cmember:(INTERNAL) Numero di ripetizione eseguite diff --git a/include/isam.cpp b/include/isam.cpp index ead524ee1..50ba88e36 100755 --- a/include/isam.cpp +++ b/include/isam.cpp @@ -20,6 +20,58 @@ #include #include +#ifdef DBG +#define JOURNAL +#endif + +#ifdef JOURNAL +#include + +static FILE* _journal = (FILE*)0xFFFF; + +FILE* get_journal() +{ + if (_journal == (FILE*)0xFFFF) + { + TConfig ini(CONFIG_INSTALL, "Main"); + const TString& name = ini.get("Journal"); + if (name.not_empty()) + _journal = fopen(name, "ab"); + else + _journal = NULL; + } + return _journal; +} + +TJournalHeader& get_journal_header(int num, const char* op, const char* type) +{ + static TJournalHeader jh; + const int size = sizeof(TJournalHeader); + CHECKD(size == 64, "Invalid journal header: ", size); + + memset(&jh, 0, size); + strcpy(jh._signature, "J00"); + jh._header_length = size; + time(&jh._time); + jh._firm = prefix().get_codditta(); + jh._logic_num = num; + strcpy(jh._operation, op); + strcpy(jh._type, type); + jh._data_size = 0; + return jh; +} + +void write_journal(TJournalHeader& jh, void* data, int len) +{ + FILE* j = get_journal(); + jh._data_size = len; + fwrite(&jh, sizeof(TJournalHeader), 1, j); + fwrite(data, len, 1, j); + fflush(j); +} + +#endif + #define RECLOCKTYPES 0xFF00 #define READTYPES 0x00FF #define INVFLD 255 @@ -170,7 +222,7 @@ void __putfieldbuff(byte l, byte d, byte t, const char* s, char* recout) else if (t == _boolfld) { - strcpy(s2, (*s && strchr("STXY", toupper(*s)) != NULL) ? "T" : "F"); + strcpy(s2, (*s && strchr("1STXY", toupper(*s)) != NULL) ? "T" : "F"); s = s2; } else @@ -769,7 +821,6 @@ int TBaseisamfile::_readat(TRectype& rec, TRecnotype nrec, word lockop) return _lasterr; } - int TBaseisamfile::_write(const TRectype& rec) { CHECK(!rec.empty(), "Can't write an empty record"); @@ -794,11 +845,25 @@ int TBaseisamfile::_write(const TRectype& rec) browse_null(rec.string(), dst_len); memcpy(DB_getrecord(fhnd), rec.string(), dst_len); _lasterr = DB_add(fhnd); - if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + + if (_lasterr == NOERR) + { + prefix().notify_change(_isam_handle); +#ifdef JOURNAL + if (get_journal()) + { + TJournalHeader& jh = get_journal_header(num(), "ADD", "REC"); + write_journal(jh, rec.string(), dst_len); + } +#endif + } + else + _lasterr = get_error(_lasterr); _recno = DB_recno(fhnd); if (_lasterr == NOERR && rec.has_memo()) ((TRectype &)rec).write_memo( fhnd, _recno ); + return _lasterr; } @@ -835,7 +900,18 @@ int TBaseisamfile::_rewrite(const TRectype& rec) { memcpy(DB_getrecord(fhnd), rec.string(), len); _lasterr = DB_rewrite(fhnd); - if (_lasterr != NOERR) + if (_lasterr == NOERR) + { + prefix().notify_change(_isam_handle); +#ifdef JOURNAL + if (get_journal()) + { + TJournalHeader& jh = get_journal_header(num(), "MOD", "REC"); + write_journal(jh, rec.string(), len); + } +#endif + } + else _lasterr = get_error(_lasterr); } else @@ -844,6 +920,7 @@ int TBaseisamfile::_rewrite(const TRectype& rec) if(_lasterr == NOERR && curr().has_memo( )) ((TRectype &)rec).write_memo( fhnd, _recno ); } + return _lasterr; } @@ -885,12 +962,28 @@ int TBaseisamfile::_remove(const TRectype& rec) { CHECK(!rec.empty(), "Can't remove an empty record"); + TRectype save_rec(rec); + // Forza l'uso della chiave principale (per chiavi duplicate?) const int fhnd = handle(1); - memcpy(DB_getrecord(fhnd),rec.string(),DB_reclen(fhnd)); - if ((_lasterr=cisread(fhnd, 1, (TRectype&)rec, _isequal + _nolock, _recno))==NOERR) + _lasterr = cisread(fhnd, 1, save_rec, _isequal + _nolock, _recno); // Si Posiziona per sicurezza... + + if (_lasterr == NOERR) { _lasterr = DB_delete(fhnd); // Put only deletion flag on record, must remove keys too! - if (_lasterr != NOERR) + if (_lasterr == NOERR) + { + prefix().notify_change(_isam_handle); + DB_flush(fhnd); +#ifdef JOURNAL + if (get_journal()) + { + const int len = DB_reclen(fhnd); + TJournalHeader& jh = get_journal_header(num(), "DEL", "REC"); + write_journal(jh, rec.string(), len); + } +#endif + } + else { _lasterr = get_error(_lasterr); DB_recall(fhnd); @@ -2247,8 +2340,8 @@ TRectype::TRectype(const TRectype& r) } _length = r.len(); _rec = new char [ _length ]; - _rec[0] = r._rec[0]; - memcpy(_rec + 1, r._rec + 1, _length - 1); + memcpy(_rec, r._rec, _length); + strcpy(_tab, r._tab); if (r._cod != NULL) _cod = new TRecfield(*this, "COD"); @@ -2601,7 +2694,6 @@ TDate TRectype::get_date(const char* fieldname) const #ifndef FOXPRO void TRectype::put(const char* fieldname, int val) - { sprintf(_isam_string, "%d", val); put_str( fieldname, _isam_string); @@ -2660,7 +2752,6 @@ void TRectype::put(const char* fieldname, const TDate& val) } void TRectype::put(const char* fieldname, char val) - { const char w[2] = {val, '\0'}; @@ -2670,7 +2761,6 @@ void TRectype::put(const char* fieldname, char val) void TRectype::put(const char* fieldname, bool val) - { char s[2] = { val ? 'X' : ' ', '\0'}; put_str( fieldname, s); diff --git a/include/isam.h b/include/isam.h index d645d6461..f7c23f6e1 100755 --- a/include/isam.h +++ b/include/isam.h @@ -291,7 +291,7 @@ protected: virtual int _write(const TRectype& rec); virtual int _rewrite(const TRectype& rec); virtual int _remove(const TRectype& rec); - + // @cmember UNUSED void recover(); // @cmember Apre il file isam di base con lock, permettendo di specificare se usare gli indici o no diff --git a/include/maskfld.cpp b/include/maskfld.cpp index 51b6ce48b..5510a1e2a 100755 --- a/include/maskfld.cpp +++ b/include/maskfld.cpp @@ -2174,13 +2174,13 @@ bool TBrowse::do_link(bool insert) app = "ba3 -0 "; if (stricmp(module,"ba") !=0 ) { - TConfig c(CONFIG_STUDIO); - app = c.get("TabPrg",module); + TConfig c(CONFIG_STUDIO, module); + app = c.get("TabPrg"); if (app.empty()) - app = "ba3 -0 "; + app = "ba3 -0"; } nm.ltrim(2); - app << nm; + app << ' ' << nm; } else { diff --git a/include/modaut.h b/include/modaut.h index 5dd09cd33..615f96a68 100755 --- a/include/modaut.h +++ b/include/modaut.h @@ -37,6 +37,7 @@ #define DBAUT 35 #define PRAUT 36 #define SVAUT 38 +#define MRAUT 39 #define ESAUT 47 #define ENDAUT 48