From 3ad7d27b0d7926330b92816462f0c7174b478adb Mon Sep 17 00:00:00 2001 From: guy Date: Mon, 22 Sep 2014 13:54:13 +0000 Subject: [PATCH] supporto per cancellazione di gruppi di file git-svn-id: svn://10.65.10.50/branches/R_10_00@22993 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/applicat.cpp | 15 +++++++ include/applicat.h | 4 +- include/checks.cpp | 2 +- include/codeb.c | 69 +++++++++++++++++------------ include/dongle.cpp | 17 ++++++++ include/expr.cpp | 4 +- include/isam.cpp | 20 ++++----- include/maskfld.cpp | 8 ++-- include/msksheet.cpp | 3 ++ include/prefix.cpp | 22 +++++----- include/prefix.h | 2 +- include/printer.cpp | 11 +++-- include/progind.cpp | 44 ++++++++++--------- include/progind.h | 10 ++--- include/sqlset.cpp | 60 ++++++++++++++++--------- include/strings.cpp | 101 ++++++++++++++----------------------------- include/text.cpp | 56 +++++++++++++++--------- include/utility.cpp | 44 ++++++++++++++++++- include/utility.h | 2 + 19 files changed, 296 insertions(+), 198 deletions(-) diff --git a/include/applicat.cpp b/include/applicat.cpp index f2245118c..70e427e11 100755 --- a/include/applicat.cpp +++ b/include/applicat.cpp @@ -375,6 +375,20 @@ const char* TApplication::get_module_name() const return module; } +void TApplication::set_title(const char* t) +{ + if (_title != t) + { + _title = t; + if (is_running()) + { + xvt_dwin_invalidate_rect(TASK_WIN, NULL); + xvtil_statbar_set(""); + } + } +} + + void TApplication::set_perms() { @@ -697,6 +711,7 @@ void TApplication::open_files(int logicnum, ...) _used_files.add(new TLocalisamfile(logicnum), logicnum); logicnum = va_arg(marker, int); } + va_end(marker); } bool TApplication::get_spotlite_path(TFilename& path) const diff --git a/include/applicat.h b/include/applicat.h index cbb339569..b2a2f3bf8 100755 --- a/include/applicat.h +++ b/include/applicat.h @@ -159,8 +159,8 @@ public: { return _argc_; } // @cmember Setta il titolo da assegnare all'applicazione - void set_title(const char* t) - { _title = t; } + void set_title(const char* t); + // @cmember Ritorna il titolo da assegnare all'applicazione const TString& title() const { return _title; } diff --git a/include/checks.cpp b/include/checks.cpp index 8babd37c0..bac805374 100755 --- a/include/checks.cpp +++ b/include/checks.cpp @@ -218,7 +218,7 @@ bool __trace( { static FILE* f = NULL; if (f == NULL) - f = fopen("trace.log", "w"); + fopen_s(&f, "trace.log", "w"); if (f != NULL) { buildmsg(); diff --git a/include/codeb.c b/include/codeb.c index 8b9a97746..ae223403a 100755 --- a/include/codeb.c +++ b/include/codeb.c @@ -619,7 +619,7 @@ int DB_packfile(short vis, const char* filename, long eod) char s[_MAX_PATH]; strcpy(s,"Compattamento "); strcat(s, filename); - progind_create(1,s,0,0,60); + progind_create(1,s,FALSE,FALSE); } rc = d4recCount(dbdata[handle]); if (eod < rc) @@ -652,7 +652,7 @@ int DB_packmemo(short vis, const char * filename) char s[256]; strcpy(s, "Compattamento memo file : "); strcat(s, filename); - progind_create(100L,s,0,0,60); + progind_create(100L,s,FALSE,FALSE); } rt=d4memoCompress(dbdata[handle]); if (vis) @@ -686,16 +686,17 @@ static int DB_clean_file(int handle, const char* filename, memset(tags, 0, sizeof(tags)); do_key(tagname, r, tags, 1); strcat((char *) tags[0].expression, "+STR(RECNO(),9)"); - w = i4create(dbdata[handle],(char*)filename,tags); + w = i4create(dbdata[handle],(char*)filename,tags); // non "production" index ??? u4free((char *) tags[0].name); u4free((char *) tags[0].expression); u4free((char *) tags[0].filter); - if (w == NULL) return code_base.errorCode; + if (w == NULL) + return code_base.errorCode; t = d4tagDefault(dbdata[handle]); lt = expr4len(t->tagFile->expr); l = lt - 9; if (vis) - progind_create(items,"Ricerca record duplicati",0,1,60); + progind_create(items,"Ricerca record duplicati",FALSE,FALSE); rt = tfile4bottom(t->tagFile); @@ -737,52 +738,62 @@ static int DB_yesnobox(const char* msg) int DB_packindex(short vis, const char* filename, const RecDes *r, long *peod, bool ask) { int handle = 0, rt = 0; - char s[256]; - strcpy(s,"Ricostruzione indici file : "); - strcat(s,filename); - code_base.autoOpen=0 ; + code_base.autoOpen = 0; + handle=DB_open(filename,1,0); /* Exclusive mode open */ if (handle >= 0) { - TAG4INFO tags[MaxKeys+1]; + TAG4INFO tags[MaxKeys+1]; INDEX4 * w = NULL; int i = 0; const char *ff = find_slash_backslash(filename); - if (vis) - progind_create(1,s,0,1,60); - if ((ff == NULL) || *ff == '\0') + if (ff == NULL || *ff == '\0') ff = (const char*)filename; else ff++; memset(tags, 0, sizeof(tags)); do_key(ff, r, tags, r->NKeys); - w = i4create(dbdata[handle],NULL,tags); - if (vis) - progind_destroy(); + { + char s[_MAX_PATH+32]; sprintf(s,"Creazione di %d indici su %s", (int)r->NKeys, ff); + progind_create(1, s, FALSE, FALSE); // No bar + } + w = i4create(dbdata[handle],NULL,tags); // NULL filename -> "production" index if (w == NULL) rt = code_base.errorCode; + + if (vis) progind_destroy(); + if (rt == e4unique || rt == r4unique) { rt = 0; if (!ask || DB_yesnobox("Sono stati rilevati alcuni records duplicati:\nsi desidera eliminarli?")) + { + if (vis) + { + char s[_MAX_PATH+32]; strcpy(s,"Rimozione duplicati "); strcat(s, ff); + progind_create(1, s, FALSE, FALSE); // No bar + } rt = DB_clean_file(handle, filename, ff, r, vis); + if (vis) progind_destroy(); + } else tags[0].unique = r4unique_continue; if (rt == 0) { - if (vis) - progind_create((long)r->NKeys,s,0,1,60); - w = i4create(dbdata[handle],filename,tags); - if (w == NULL) rt = code_base.errorCode; if (vis) { - progind_set_status((long)r->NKeys); - progind_destroy(); + char s[_MAX_PATH+32]; sprintf(s,"Creazione di %d indici su %s", (int)r->NKeys, ff); + progind_create(1, s, FALSE, FALSE); // no bar } + // w = i4create(dbdata[handle],filename,tags); + w = i4create(dbdata[handle], NULL ,tags); // NULL filename -> "production" index 6/8/2014 + if (w == NULL) + rt = code_base.errorCode; + if (vis) progind_destroy(); } } for (i=0; i < r->NKeys && tags[i].name; i++) @@ -796,13 +807,17 @@ int DB_packindex(short vis, const char* filename, const RecDes *r, long *peod, b } code_base.autoOpen = 1; + #ifdef DBG - strcpy(s, filename); - strcat(s, ".cdx"); - if (xvt_fsys_file_attr(s, XVT_FILE_ATTR_SIZE) == 0) { - strcat(s, " e' appena stato sputtanato!"); - xvt_dm_post_error(s); + char s[_MAX_PATH+20]; + strcpy(s, filename); + strcat(s, ".cdx"); + if (xvt_fsys_file_attr(s, XVT_FILE_ATTR_SIZE) == 0) + { + strcat(s, " e' stato compromesso!"); + xvt_dm_post_error(s); + } } #endif diff --git a/include/dongle.cpp b/include/dongle.cpp index 27380a4c6..28351e5ac 100755 --- a/include/dongle.cpp +++ b/include/dongle.cpp @@ -520,6 +520,23 @@ bool TDongle::login(bool test_all_keys) } } + if (!ok && hw == _dongle_ssa) + { + TString_array ssa; + const int n = list_files("*.ssa", ssa); + switch (n) + { + case 0: error_box(FR("Non esistono file SSA validi")); break; + case 1: error_box(FR("File SSA non valido:\n%s"), + (const char*)ssa.row(0)); + break; + default: + error_box(FR("Sono presenti troppi file SSA:\n%s,%s,..."), + (const char*)ssa.row(0), (const char*)ssa.row(1)); + break; + } + } + return ok; } diff --git a/include/expr.cpp b/include/expr.cpp index 50825fb1c..ca371cd1d 100755 --- a/include/expr.cpp +++ b/include/expr.cpp @@ -1133,7 +1133,7 @@ TCodesym TExpression::__factor(TCodesym startsym) char* quadra = strchr(_tok, '['); if (quadra) { - if (sscanf(quadra, "[%d,%d]", &from, &to) == 0) + if (sscanf_s(quadra, "[%d,%d]", &from, &to) == 0) { sym = _invalid; break; @@ -1172,7 +1172,7 @@ TCodesym TExpression::__factor(TCodesym startsym) const int index = parse_user_func(val.string(), parms_found); if (index < 0) { - strncpy(_tok, val.string(), sizeof(_tok)); + strncpy_s(_tok, sizeof(_tok), val.string(), sizeof(_tok)-1); sym = _invalid; } else diff --git a/include/isam.cpp b/include/isam.cpp index 43b0c914d..ac6c6fd98 100755 --- a/include/isam.cpp +++ b/include/isam.cpp @@ -1927,7 +1927,7 @@ void TSystemisamfile::makelc(TRectype& rec) int TSystemisamfile::update( const TTrec& newrec, // @parm Nuovo tracciato record con cui aggiornare il file - bool interactive) // @parm Indica se riportare i campi personalizzati (!interactive + bool interactive) // @parm Indica se riportare i campi personalizzati { if (newrec.len() == 0) @@ -2059,10 +2059,10 @@ int TSystemisamfile::update( if (err != NOERR) return err; - TString s(256); s << TR("Aggiornamento") << ' ' << fname; + TString s; s << TR("Aggiornamento") << ' ' << fname; const TRecnotype nitems = items(); - TProgind p(nitems > 0 ? nitems : 1, s, is_power_station(), true); + TProgress_monitor p(nitems > 0 ? nitems : 1, s, is_power_station()); TExtrectype nrec(wrec); @@ -2079,7 +2079,7 @@ int TSystemisamfile::update( const bool memo_inside = rec_has_memo(nrec.rec_des()); for (int errore = first(); errore == NOERR; errore = next()) { - if (!p.addstatus(1)) + if (!p.add_status()) { err = _iseof; // Simula errore in caso di interruzione break; @@ -2144,10 +2144,9 @@ int TSystemisamfile::update( if (err != NOERR) err = get_error(err); - if (p.iscancelled()) + + if (!p.setstatus(nitems)) err = _iseof; - - p.setstatus(nitems); } if (err == NOERR) @@ -2202,7 +2201,7 @@ int TSystemisamfile::update( prefix().update_recdes(num()); if (toconvert) - packindex(); + packindex(true); if (err == NOERR) err = exec_convapp(lev, FALSE); // Post - conversion } @@ -2283,16 +2282,17 @@ int TSystemisamfile::packindex( err = get_error(err); if (err != NOERR) { - if (vis) + if (vis || ask) error_box("Errore in compattamento indici.\nFile %d : %d", num(),err); } else + { if (peod >= 0 && peod != d.eod()) { d.set_eod(peod); d.put(num(), is_com ? _comdir : _nordir); } - + } setstatus(err); return err; } diff --git a/include/maskfld.cpp b/include/maskfld.cpp index ba48c0add..d6e32e0f1 100755 --- a/include/maskfld.cpp +++ b/include/maskfld.cpp @@ -3105,11 +3105,11 @@ void TReal_field::create(WINDOW w) if (has_query_button() && browse() != NULL && browse()->cursor() != NULL) { TCursor& cur = *browse()->cursor(); - const TRectype& esc = cur.curr(); - if (esc.num() == LF_TAB) // ... codice esercizio? + const TRecnotype ne = cur.items(); + if (ne > 0 && xvt_str_compare_ignoring_case(cur.file(0).name(), "ESC") == 0) // ... codice esercizio? { - const TRecnotype ne = cur.items(); - for (cur = ne-1; cur.ok(); --cur) + const TRectype& esc = cur.curr(); + for (cur = ne-1; cur.pos() > 0; --cur) { const TDate dataini = esc.get("D0"); const TDate datafin = esc.get("D1"); diff --git a/include/msksheet.cpp b/include/msksheet.cpp index a62e25f76..25d8efd7d 100755 --- a/include/msksheet.cpp +++ b/include/msksheet.cpp @@ -1218,7 +1218,10 @@ bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev) } } else + { + xiev->v.cell_request.color = COLOR_BLACK; // Ignored :-( src = format("%d", rec+1); // Numero riga + } char* dst = xiev->v.cell_request.s; if (src && *src) diff --git a/include/prefix.cpp b/include/prefix.cpp index c06c14046..199e8a1a6 100755 --- a/include/prefix.cpp +++ b/include/prefix.cpp @@ -28,6 +28,7 @@ HIDDEN TPrefix* _prefhndl = NULL; TPrefix& prefix_init() { CHECK(_prefhndl == NULL, "Can't create two prefix objects"); + TFilename n; n.tempdir(); // Forza creazione dir temporanea indispensabile a Codebase! _prefhndl = new TPrefix; return *_prefhndl; } @@ -349,11 +350,16 @@ public: virtual ~TFile_info(); }; +static int _open_files = 0; int TFile_info::open_low(bool exclusive, bool index) { if (_handle < 0) + { _handle = DB_open(_name, exclusive, index); + if (_handle >= 0) + _open_files++; + } #ifdef DBG else error_box("You shouldn't reopen file %s", (const char*)_name); @@ -393,6 +399,7 @@ int TFile_info::close_low() _handle = -1; _last_key = -1; _exclusive = _locked = false; + _open_files--; } else { @@ -621,7 +628,6 @@ bool TFile_manager::close_oldest() { TFile_info& i = (TFile_info&)_fileinfo[oldest]; i.auto_close(); - _open_files--; } return oldest != 0; //verificare @@ -689,13 +695,10 @@ int TFile_manager::close(TIsam_handle& name) TFile_info* i = (TFile_info*)_fileinfo.objptr(name); if (i != NULL) { - const bool was_open = i->is_open(); err = i->close(); // Se chiuso veramente ... (Per efficienza non chiude sempre) if (err == NOERR && !i->is_open()) { - if (was_open) - _open_files--; if (name >= LF_EXTERNAL && i->ref_count() <= 0) { _fileinfo.remove(name); @@ -732,11 +735,8 @@ TCodeb_handle TFile_manager::get_handle(TIsam_handle name, int key) // Se ho passato key = -1 mi va bene la chiave principale if (key < 0) - key = 1; - + key = 1; handle = i.auto_open(key); - if (handle >= 0) - _open_files++; } else { @@ -803,19 +803,18 @@ long TFile_manager::last_change(TIsam_handle name) const int TFile_manager::close_closeable() { - _open_files = 0; + _open_files = 0; // Ricalcolo per sicurezza for (TIsam_handle n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n)) { TFile_info& i = fileinfo(n); if (i.is_open()) { + _open_files++; if (!i.is_locked() && !i.is_exclusive()) { cache().discard(i.num()); i.auto_close(); } - else - _open_files++; } if (i.ref_count() <= 0) _fileinfo.destroy(n); @@ -866,7 +865,6 @@ const TFilename& TFile_manager::get_filename(TIsam_handle id) const TFile_manager::TFile_manager() - : _open_files(0) { _max_open_files = xvt_sys_get_profile_int(NULL, "Main", "MaxHandles", 32); if (_max_open_files < 16) diff --git a/include/prefix.h b/include/prefix.h index c05b9f9f7..327dad57e 100755 --- a/include/prefix.h +++ b/include/prefix.h @@ -23,7 +23,7 @@ class TFile_manager : public TObject { TArray _fileinfo; TArray _recinfo; - int _open_files, _max_open_files; + int _max_open_files; protected: TFile_info& fileinfo(TIsam_handle handle) const; diff --git a/include/printer.cpp b/include/printer.cpp index 12a665e56..2b010e962 100755 --- a/include/printer.cpp +++ b/include/printer.cpp @@ -2356,7 +2356,7 @@ int TTab_info::intersection(int s, int e) const { int i = 0; if (e >= _start && s <= _end) - i = min(_end, e) - max(_start, s); + i = min(_end, e) - max(_start, s) + 1; return i; } @@ -2422,12 +2422,17 @@ void TTabulator::add_field(int column, int width) int idx, col; if (find_column(column, width, idx, col)) { - const TTab_info& ti = (const TTab_info&)_tab[idx]; + TTab_info& ti = (TTab_info&)_tab[idx]; if (ti.intersection(start, end) < width) { split(start, end, ti.start(), ti.end()); _tab.destroy(idx, true); } + else + { + if (ti.start() == column && end > ti.end() && end < ti.end()+4) + ti.set_end(end); + } } else add(start, end); @@ -2454,7 +2459,7 @@ void TTabulator::sort() TTab_info& t0 = (TTab_info&)_tab[i-1]; TTab_info& t1 = (TTab_info&)_tab[i]; if (t1 == t0 || t1.width() <= 0) - _tab.destroy(i); + _tab.destroy(i, true); else { const int gap = t1.start() - t0.end(); diff --git a/include/progind.cpp b/include/progind.cpp index 49c9320a4..6e6911566 100755 --- a/include/progind.cpp +++ b/include/progind.cpp @@ -11,7 +11,7 @@ // TIndwin /////////////////////////////////////////////////////////// -int TIndwin::_indwin_count = 0; +static int _indwin_count = 0; word TIndwin::measure_text(TToken_string& s, word& maxlen) const { @@ -36,7 +36,7 @@ TIndwin::TIndwin(long tot, const char* txt, bool cancel, bool bar, int div) const int hor = min(maxlen+3, 78); const int ver = lines+3 + (bar ? 2 : 0); - const int y = _indwin_count == 0 ? 3 : 12; + const int y = _indwin_count == 0 ? 3 : (_indwin_count == 1 ? 11 : -2); long flags = WSF_INVISIBLE; if (_can_cancel) @@ -50,8 +50,7 @@ TIndwin::TIndwin(long tot, const char* txt, bool cancel, bool bar, int div) if (bar) { - XVT_COLOR_COMPONENT xcc[4]; - memset(xcc, 0, sizeof(xcc)); + XVT_COLOR_COMPONENT xcc[4] = { 0 }; xcc[0].type = XVT_COLOR_BACKGROUND; xcc[0].color = MASK_BACK_COLOR; xcc[1].type = XVT_COLOR_BLEND; @@ -88,8 +87,8 @@ void TIndwin::set_text( FOR_EACH_TOKEN(txt, tok) _text.add(tok); - RCT r; get_txt_rct(r); - xvt_dwin_invalidate_rect(win(), &r); + if (is_open()) // Draw it immediately + update_txt(); } void TIndwin::setmax(long m) @@ -102,9 +101,9 @@ void TIndwin::setmax(long m) TIndwin::~TIndwin() { + _indwin_count--; if (is_open()) close_modal(); - _indwin_count--; } bool TIndwin::can_be_closed() const @@ -130,7 +129,7 @@ void TIndwin::get_bar_rct(RCT& r) const { xvt_vobj_get_client_rect(win(), &r); r.left += CHARX; - r.right -= CHARX; + r.right -= 3*CHARX/2; r.top = _bar_top; r.bottom = r.top + ROWY; } @@ -138,8 +137,8 @@ void TIndwin::get_bar_rct(RCT& r) const void TIndwin::get_txt_rct(RCT& r) const { get_bar_rct(r); - r.bottom = r.top - ROWY/2; - r.top = ROWY/2; + r.bottom = r.top - ROWY/4; + r.top = ROWY/4; } void TIndwin::sec2str(unsigned long ss, TString& str) const @@ -274,14 +273,15 @@ TProgind::TProgind(long max, const char* txt, bool cancel, bool bar, int div) bool TProgind::setstatus(long l) { - const bool ok = TIndwin::setstatus(l); + const bool ok = TIndwin::setstatus(l); // Aggiorna barra comunque + const clock_t c = clock(); if (ok && c > _next_update) { - update(); - do_events(); - _next_update = c+CLOCKS_PER_SEC; // Prossimo aggiornamento tra un secondo + _next_update = c+CLOCKS_PER_SEC; // Prossimo aggiornamento ... + update_bar(); // ... tempi stimati } + do_events(); return ok; } @@ -330,8 +330,8 @@ bool TProgress_monitor::set_status(long n) if (_status <= 0L && n <= 0L) _start = clock(); - // Se sono passati 1 secondi e sono a meno di metà lavoro allora crea la TProgind - if (_pi == NULL && n < _total/2 && (clock() - _start) >= CLOCKS_PER_SEC) + // Se è passato un secondo allora crea la TProgind + if (_pi == NULL && (clock() - _start) >= CLOCKS_PER_SEC) { _pi = new TProgind(_total, _txt, _cancellable); _pi->set_start_time(_start); @@ -382,10 +382,11 @@ TProgress_monitor::~TProgress_monitor() // uses static pointer for single instance of TIndwin static TIndwin* __indwin__p = NULL; -void progind_create(long m, const char* t, bool b, bool c, int n) +void progind_create(long m, const char* t, bool b, bool c) { CHECK(__indwin__p == NULL, "Cannot have more than one progress indicator"); - __indwin__p = new TProgind(m,t,b,c,n); + __indwin__p = new TProgind(m, t, b, c, 60); + do_events(); } bool progind_set_status(long l) @@ -410,15 +411,17 @@ bool progind_isfinished() void progind_destroy() { + CHECK(__indwin__p != NULL, "No progress indicator to delete"); delete __indwin__p; __indwin__p = NULL; } +/* void timerind_create(long l, const char* title, bool bar, bool cancel, - int divisions, int interval) + int interval) { CHECK(__indwin__p == NULL, "Cannot have more than one progress indicator"); - __indwin__p = new TTimerind(l,title,bar,cancel,divisions,interval); + __indwin__p = new TTimerind(l,title,bar,cancel,60,interval); } void timerind_cancel() @@ -442,3 +445,4 @@ void timerind_destroy() __indwin__p = NULL; } +*/ diff --git a/include/progind.h b/include/progind.h index ae025708b..0e15e50d6 100755 --- a/include/progind.h +++ b/include/progind.h @@ -40,8 +40,6 @@ class TIndwin : public TWindow // @cmember:(INTERNAL) Flag che indica quali operazioni sono state effettuate byte _flags; - static int _indwin_count; - // @access Protected Member protected: // @cmember Massimo valore da ricercare @@ -192,18 +190,20 @@ public: extern "C" { #endif // Non commentate perche' destinate a sparire - void progind_create(long, const char*, bool, bool, int); + void progind_create(long, const char*, bool, bool); bool progind_set_status(long s); void progind_cancel(); bool progind_iscancelled(); bool progind_isfinished(); void progind_destroy(); - void timerind_create(long, const char*, bool, bool, int, int); + + /* NEVER used stuff! + void timerind_create(long, const char*, bool, bool, int); void timerind_cancel(); bool timerind_iscancelled(); bool timerind_isfinished(); void timerind_destroy(); - + */ #ifdef __cplusplus } #endif diff --git a/include/sqlset.cpp b/include/sqlset.cpp index 3b2f27853..47e2d6032 100755 --- a/include/sqlset.cpp +++ b/include/sqlset.cpp @@ -238,7 +238,7 @@ bool TSQLite::import(int logicnum) TString sql; if (exists(table)) { - // Drop old table + // Drop old table (and associated indexes?) sql.cut(0) << "DROP TABLE "<< table << ';'; exec(sql); } @@ -265,16 +265,15 @@ bool TSQLite::import(int logicnum) TRelation rel(logicnum); TCursor cur(&rel); const TRecnotype items = cur.items(); + TString msg; + if (items > 0) { cur.freeze(); - TString msg; msg << TR("Importazione tabella") << ' ' << table; msg << ": " << items << ' ' << TR("righe"); - TProgind pi(items, msg, true, true); - - exec("BEGIN"); // Inizio transazione + TProgress_monitor pi(items, msg); // Creo il comando INSERT INTO table VALUES(?,?,?,?,?,?); sql.cut(0) << "INSERT INTO " << table << " VALUES("; @@ -285,38 +284,50 @@ bool TSQLite::import(int logicnum) } sql << ");"; + exec("BEGIN"); // Inizio transazione + sqlite3_stmt* pStatement = NULL; int rc = sqlite3_prepare(_handle, sql, sql.len(), &pStatement, NULL); - + const TRectype& curr = rel.curr(); for (cur = 0; cur.pos() < items; ++cur) { - pi.addstatus(1); - if (pi.iscancelled()) + if (!pi.add_status()) break; bind_record(curr, rd, pStatement); // Sostituisce i ? coi veri valori rc = sqlite3_step(pStatement); // Ritorna sempre 101 (SQLITE_DONE) rc = sqlite3_reset(pStatement); // Azzero lo statement per ricominciare } rc = sqlite3_finalize(pStatement); + exec("COMMIT"); // Fine transazione } - - // Creo gli indici DOPO l'importazione per maggiore velocita' - TProgind pi(rd.NKeys, TR("Creazione indici"), false, true); - for (int index = 0; index < rd.NKeys; index++) + + if (rd.NKeys > 0) { - pi.addstatus(1); - sql.cut(0) << "CREATE INDEX " << table << '_' << (index+1) << " ON "<< table << "\n("; - const KeyDes& kd = rd.Ky[index]; - for (int k = 0; k < kd.NkFields; k++) + // Creo gli indici DOPO l'importazione per maggiore velocita' + msg.format("Creazione di %d indici sulla tabella %s", rd.NKeys, (const char*)table); + TProgress_monitor pi(rd.NKeys, msg); + + for (int index = 0; index < rd.NKeys; index++) { - if (k > 0) sql << ','; - const int ndx = kd.FieldSeq[k] % MaxFields; - sql << rd.Fd[ndx].Name; + if (!pi.addstatus(1)) + break; + const KeyDes& kd = rd.Ky[index]; + sql = "CREATE "; + if (!kd.DupKeys) sql << "UNIQUE "; + sql << "INDEX " << table << '_' << (index+1) << " ON "<< table << "\n("; + for (int k = 0; k < kd.NkFields; k++) + { + if (k > 0) sql << ','; + const int ndx = kd.FieldSeq[k] % MaxFields; + sql << rd.Fd[ndx].Name; + } + sql << ");"; + exec("BEGIN"); // Inizio transazione + exec(sql); + exec("COMMIT"); // Fine transazione } - sql << ");"; - exec(sql); } set_dbf_time(table, last); // Aggiorna ora di ultima modifica @@ -340,8 +351,12 @@ bool TSQLite::parse_select_from(const char* szSql) const int where_pos = sql.find("WHERE", from); TToken_string tables(sql.sub(from+5, where_pos), ','); TString table; + + TProgress_monitor pi(tables.items(), TR("Importazione tabelle")); FOR_EACH_TOKEN(tables, tok) { + if (!pi.add_status()) + break; table = tok; const int join_pos = table.find("JOIN "); if (join_pos > 0) @@ -359,7 +374,10 @@ bool TSQLite::parse_select_from(const char* szSql) const int logicnum = (table == "MAG") ? LF_MAG : table2logic(table); if (logicnum >= LF_USER) + { + pi.set_text(table); import(logicnum); + } } return true; diff --git a/include/strings.cpp b/include/strings.cpp index 0b726fe79..ae5b3a5eb 100755 --- a/include/strings.cpp +++ b/include/strings.cpp @@ -1266,48 +1266,38 @@ const TFilename& TFilename::tempdir() xvt_sys_get_env("TEMP", _tempdir.get_buffer(), _tempdir.size()); if (_tempdir.empty()) xvt_sys_get_env("TMP", _tempdir.get_buffer(), _tempdir.size()); - if (_tempdir.empty()) + + bool ok = dexist(_tempdir); + if (!ok) // Codebase NON funziona senza una temp esistente! { - _tempdir = __argv[0]; - _tempdir.cut(3); - _tempdir << "temp"; - } - if (!_tempdir.exist()) - { - _tempdir = __argv[0]; - _tempdir.cut(3); - _tempdir << "tmp"; + ok = make_dir(_tempdir); + if (!ok) + fatal_box("La cartella temporanea '%s' non esiste", (const char*)_tempdir); } const int last = len()-1; if (!is_not_slash(_str[last])) _tempdir.cut(last); - - bool ok = true; - _tempdir.lower(); - if (!dexist(_tempdir)) - ok = make_dir(_tempdir); - if (ok) - { - TString theuser(user()); - if (theuser.empty()) - theuser = ::dongle().administrator(); - theuser.lower(); - const int f = _tempdir.find(theuser); - if (f < 0 || f != _tempdir.len() - theuser.len()) - _tempdir << SLASH << theuser; - _tempdir.lower(); - if (!dexist(_tempdir)) - ok = make_dir(_tempdir); - } + TString theuser(user()); + if (theuser.empty()) + theuser = ::dongle().administrator(); + theuser.lower(); + const int f = _tempdir.find(theuser); + if (f < 0 || f != _tempdir.len() - theuser.len()) + _tempdir.add(theuser); + _tempdir.lower(); + ok = dexist(_tempdir); if (!ok) - fatal_box("Impossibile creare la directory '%s' per i file temporanei", - (const char*)_tempdir); + { + ok = make_dir(_tempdir); + if (!ok) + fatal_box("Impossibile creare la cartella temporanea '%s'", (const char*)_tempdir); + } - xvt_sys_set_env("TMP", _tempdir); + xvt_sys_set_env("TMP", _tempdir); // Usata da _tmpnam } set(_tempdir); @@ -1332,56 +1322,29 @@ const TFilename& TFilename::temp( const char* prefix, // @parm Eventuale prefisso da assegnare al file temporaneo const char* extension) // @parm Eventuale estensione da assegnare al file temporaneo - // @comm Nel generare il nome del file controlla se esistone dei caratteri jolly - // e li elimina. + // @comm Nel generare il nome del file controlla se esistono dei caratteri jolly e li elimina. { if (extension && *extension) { - /* Vengono creati file in posti fantasiosi - TFilename mask(prefix); - if (mask.empty()) - mask.tempdir(); - mask.add("*"); - mask.ext(extension); - */ - TFilename mask; - mask.tempdir(); + TFilename root; root.tempdir(); if (prefix && *prefix) { bool has_path = false; for (const char *s = prefix; !has_path && *s; s++) has_path = *s ==':' || is_slash(*s); if (has_path) - mask = prefix; + root = prefix; else - mask.add(prefix); - mask << '*'; + root.add(prefix); } - else - mask.add("*"); - mask.ext(extension); - - const int star = mask.find('*'); - CHECK(star>=0, "Invalid temp file mask"); - TString_array list; - const int count = list_files(mask, list); - - if (count > 0) - { - FOR_EACH_ARRAY_ROW(list, i, row) - { - const char* name = row->mid(star); - const long numero = atol(name) + 1; - mask = row->left(star); - mask << numero; - mask.ext(extension); - if (list.find(mask) < 0) - break; - } + for (unsigned int n = (unsigned int)clock(); ; n++) + { + TString8 name; name.format("%05lu", n % 100000); + set(root); operator<<(name); + ext(extension); + if (!exist()) + break; } - else - mask[star] = '1'; - set(mask); } else { diff --git a/include/text.cpp b/include/text.cpp index da1022149..a0c226bb0 100755 --- a/include/text.cpp +++ b/include/text.cpp @@ -13,15 +13,11 @@ class _HotSpot : public TObject public: // TArray _spots; // tokenstrings char _bg, _fg; - _HotSpot (char fg, char bg) { _fg = fg; _bg = bg; } - virtual ~ _HotSpot () - { - } }; // @doc EXTERNAL @@ -837,8 +833,8 @@ void TTextfile::write( // Determina il tipo di una stringa: 0=ignoto; 1=stringa; 2=numero static int str_type(TString& str) { - str.trim(); - if (str.empty()) + str.rtrim(); + if (str.blank()) return 0; bool is_string = false; bool is_number = true; @@ -860,6 +856,18 @@ static int str_type(TString& str) return is_number ? 2 : (is_string ? 1 : 0); } +static bool is_text_line(TString& str) +{ + const int l = str.trim().len(); + if (l >= 64) + { + const char c = str[0]; + if (strchr("_-=", c) != NULL && str[l/2] == c && str[l-1] == c) + return true; + } + return false; +} + bool TTextfile::write_xls(const TFilename& xls) { int headerlen = printer().headersize(); @@ -871,24 +879,32 @@ bool TTextfile::write_xls(const TFilename& xls) int tabstop = pagelen - footerlen; if (_lines < tabstop) tabstop = _lines; - if (headerlen <= 0) // Cerca di capire l'inizio della testata + + int header_end = 12; + if (headerlen > 3) + header_end = headerlen; + if (header_end > tabstop) + header_end = tabstop; + + for (long j = 1; j < header_end; j++) { - for (long j = 1; j < 12 && j < tabstop; j++) + read_line(j); + str = piece(); + if (is_text_line(str)) { - read_line(j); - str = piece(); str.trim(); - if (str.len() >= 64 && (str.starts_with("________") || str.starts_with("--------") || str.starts_with("========"))) + if (tabstart <= 1) + tabstart = j+1; + else { - if (tabstart <= 1) - tabstart = j+1; - else - { - tabstop = j; - headerlen = j; - } + tabstop = j; + headerlen = j; } } } + if (tabstart <= 1 && headerlen > 0) + tabstart = headerlen; + if (tabstart < 2) + tabstart = 2; TTabulator tab; for (long j = tabstart; j < tabstop; j++) @@ -900,7 +916,7 @@ bool TTextfile::write_xls(const TFilename& xls) str = cp; const int len = str.len(); if (str_type(str) > 0) - tab.add_field(x, len); + tab.add_field(x, str.len()); x += len; } } @@ -927,7 +943,7 @@ bool TTextfile::write_xls(const TFilename& xls) if (st > 0) { int idx, pos; - if (tab.find_column(x, len, idx, pos)) + if (tab.find_column(x, str.len(), idx, pos)) { const char* old = riga.get(pos); if (old && *old) diff --git a/include/utility.cpp b/include/utility.cpp index c921197e1..dd59a4d4a 100755 --- a/include/utility.cpp +++ b/include/utility.cpp @@ -3,6 +3,7 @@ #include #include +#include #include /////////////////////////////////////////////////////////// @@ -185,11 +186,52 @@ bool make_dir(const char* dir) // @parm Nome della directory da creare // // @flag TRUE | Se l'operazione e' avvenuta con successo // @flag FALSE | Se l'operazione non e' riuscita -bool remove_file(const char* file) // @parm Nome della directory da creare +bool remove_file(const char* file) // @parm Nome del file da cancellare { return xvt_fsys_remove_file(file) != 0; } +int remove_files(const char* path, bool subdirs) // @parm maschera files da cancellare, es: "c:\temp\*.tmp" +{ + TFilename dir(path); + if (dir.find('*') < 0 && dir.find('?') < 0 && dexist(dir)) + dir.add("*.*"); + + SLIST files = xvt_fsys_list_files("", dir, subdirs); + const int count = xvt_slist_count(files); + if (count > 0) + { + dir = dir.path(); + // Windows XP doesn't support multi file deletion ... + if (xvt_fsys_files_remove(dir, files) <= 0) + { + dir.insert(TR("Cancellazione cartella ")); // ... do it manually + TProgress_monitor bar(count, dir); + for (SLIST_ELT e = xvt_slist_get_first(files); e && bar.add_status(); e = xvt_slist_get_next(files, e)) + { + const char* n = xvt_slist_get(files, e, NULL); + if (dexist(n)) + xvt_fsys_rmdir(n); + else + xvt_fsys_remove_file(n); + } + } + } + xvt_slist_destroy(files); + return count; +} + +int count_files(const char* dir, bool subdirs) +{ + TFilename d(dir); + if (d.find('*') < 0 && d.find('?') < 0) + d.add("*.*"); + SLIST files = xvt_fsys_list_files("", d, subdirs); + const int count = xvt_slist_count(files); + xvt_slist_destroy(files); + return count; +} + // @doc EXTERNAL // @func Ritorna la lista dei file il cui nome corrisponde alla stringa (con caratteri diff --git a/include/utility.h b/include/utility.h index e5cd3b959..cfc8ad788 100755 --- a/include/utility.h +++ b/include/utility.h @@ -37,6 +37,8 @@ void log_message(const char* fmt, ...); bool make_dir(const char* dir); bool remove_file(const char* file); +int remove_files(const char* mask, bool subdirs); +int count_files(const char* dir, bool subdirs); int list_files(const char* mask, TString_array& result); bool input_filename(TFilename& file);