#include #include #include #include #include #include #include "ve5400.h" #include "velib.h" #include #include //----------------------------------------------------------------------------------------------- //-------MASCHERA----------------------------- class TArchive_mask : public TMask { public: TArchive_mask(); virtual ~TArchive_mask() { } }; TArchive_mask::TArchive_mask() : TMask("ve5400") { TList_field& lf = (TList_field&)field(F_DRIVE); TToken_string codes, values; TString4 str; int k = 0; for (int d = 0; d < 26; d++) { str.format("%c:/", d+'A'); const bool isrem = xvt_fsys_is_removable_drive(str) != 0; const bool isfix = !isrem && xvt_fsys_is_fixed_drive(str); if (isrem || isfix) { str.rtrim(1); // Togli slash finale codes.add(str); values.add(str); TToken_string& message = *lf.message(k++, TRUE); if (isrem) message.format("CLEAR,%d", F_PATH); else message.format("ENABLE,%d", F_PATH); } } lf.replace_items(codes, values); } //----------------------------------------------------------------------------------------------- //-------APPLICAZIONE----------------------------- class TArchive_doc : public TSkeleton_application { TArray _file; TIsamtempfile *_tdoc; //dichiaro un puntatore al file documenti (non posso dichiarare un file) TIsamtempfile *_trdoc; // righe documenti TIsamtempfile *_trcf; // clienti/ fornitori TIsamtempfile *_trcfv; // clienti/ fornitori vendite TFilename _tmp_dir, _path; TArchive _arc; TString _desc; char _unit; protected: // TSkeleton_application virtual void main_loop(); void open_files(int logicnum, ...); virtual bool create(); void create_tmp_files(bool create); void delete_tmp_files(bool remove); void archivia(const TMask& m); void ripristina(const TMask& m); bool restore_file(TIsamtempfile& src, bool update); bool restore_clifo(bool update); bool restore_docs(); public: TArchive_doc() { } virtual ~TArchive_doc() { } }; void TArchive_doc::open_files(int logicnum, ...) { va_list marker; va_start(marker, logicnum); while (logicnum > 0) { CHECKD(_file.objptr(logicnum) == NULL, "File gia' aperto: ", logicnum); _file.add(new TLocalisamfile(logicnum), logicnum); logicnum = va_arg(marker, int); } } bool TArchive_doc::create() { open_files(LF_TABCOM, LF_TAB, LF_CLIFO, LF_OCCAS, LF_INDSP, LF_CFVEN, LF_DOC, LF_RIGHEDOC, LF_ANAMAG, LF_MOVMAG, LF_RMOVMAG, LF_CONDV, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, LF_CESS, 0); _tmp_dir.temp(); _tmp_dir = _tmp_dir.path(); _tmp_dir << "VE"; if (!_tmp_dir.exist()) make_dir(_tmp_dir); _tmp_dir.insert("%"); // Add % sign _tdoc = _trdoc = _trcf = _trcfv = NULL; return TSkeleton_application::create(); } void TArchive_doc::create_tmp_files(bool create) //crea i files temporanei (nella directory temp) { TFilename tf(_tmp_dir); tf.add("f1"); _tdoc = new TIsamtempfile(LF_DOC, tf, create); tf.rtrim(1); tf << "2"; _trdoc = new TIsamtempfile(LF_RIGHEDOC, tf, create); tf.rtrim(1); tf << "3"; _trcf = new TIsamtempfile(LF_CLIFO, tf, create); tf.rtrim(1); tf << "4"; _trcfv = new TIsamtempfile(LF_CFVEN, tf, create); } void TArchive_doc::delete_tmp_files(bool remove) //cancella i files temporanei al termine dell'archiviazione { if (remove) // Cosi' posso forzare la cancellazione in chiusura { _tdoc->set_autodel(); _trdoc->set_autodel(); _trcf->set_autodel(); _trcfv->set_autodel(); } delete _tdoc; delete _trdoc; delete _trcf; delete _trcfv; _tdoc = NULL; _trdoc = NULL; _trcf = NULL; _trcfv = NULL; } void TArchive_doc::archivia(const TMask& m) { const bool with_clifor = m.get_bool(F_WITHCLI); TRelation rel(LF_DOC); //crea una relazione sul file identificato dal numero LF_DOC m.autosave(rel); //scrive, in base alla rel, i valori del campo con specifica LF_DOC TRectype recini(rel.curr()); //crea recini di TRectype che costruisce il record corrente del file TRectype recfin(rel.curr()); //crea recfin di TRectype che costruisce il record corrente del file recini.put(DOC_NDOC, m.get(F_NUMFR)); //setta il contenuto del campo DOC_NDOC con il numero che arriva da m.get (é il numero del primo record da leggere) recfin.put(DOC_NDOC, m.get(F_NUMTO)); //come sopra ma per l'ultimo record (questi due numeri gli servono nel cursore) _unit = m.get(F_DRIVE)[0]; //legge solo i drive dei floppy e quelli locali _path = m.get(F_PATH); //path di destinazione del file da creare (se non floppy) _desc = m.get(F_DESCRFILE); //descrizione nel file .ini TString filter; //crea l'ogetto filter da TString TCursor cur(&rel, filter, 1, &recini, &recfin); //crea un cursore (cur) basato sulla relazione rel, il filtro filter, da recini a recfin const long total = cur.items(); //mette in total il numero totale di record if (total > 0) //se c'é almeno un record... { TString msg = "Confermare l'invio di "; //istanza della TString (compare una box con la richiesta di conferma) msg.add_plural(total, "documento"); //cerca il plurale della stringa "documento" se total é>1 if (yesno_box(msg)) //se si conferma l'archiviazione (OK nella box)... { //chiamo la funzione che crea i file temporanei in modo da creare un create_tmp_files(TRUE); //file di intestazione ed un file di righe temporanei (N.B. non devo //creare alcun oggetto perché la funzione é un metodo della TArchive_doc //e quindi l'oggetto é giá creato TProgind pi(total, "Elaborazione in corso...", TRUE, TRUE); //istanza pi di TProgind che fa comparire la finestra di elaborazione in corso TDocumento* doc = new TDocumento; //doc é un puntatore ad una istanza di TDocumento rel.lfile().set_curr(doc); //applica set_curr al localisamfile che viene ritornato da rel.lfile() //set_curr sostituisce il record corrente del file doc int err = NOERR; for (cur = 0; cur.pos() < total && !pi.iscancelled() && err==NOERR; ++cur) //for cur che va da 0 alla posizione corrente (che deve essere < del numero totale //dei record (total) and non essere interrotto e non esserci errore { err = _tdoc->write(doc->head()); //scrive l'intestazione sul file temp delle testate if (with_clifor) { TString key(doc->get(DOC_TIPOCF)); key << "|" << doc->get(DOC_CODCF); TRectype clifor(cache().get(LF_CLIFO, key)); TRectype cfven(cache().get(LF_CFVEN, key)); if (!clifor.empty()) clifor.write(*_trcf); if (!cfven.empty()) cfven.write(*_trcfv); } if (err != NOERR) //se invece c'é un errore.. { error_box("Errore %d durante la copia dell'intestazione", err); break; } for (int r = 1; r <= doc->physical_rows() && err==NOERR; r++) //scrive le righe sul file temp delle { //righe; err = _trdoc->write((*doc)[r]); //scrive le righe sul file if (err != NOERR) { error_box("Errore %d durante la copia delle righe", err); break; } } pi.addstatus(1L); //mette la barra di work in progress } delete_tmp_files(false); //chiude i files temp in modo da risparmiare memoria const char * dir = &_tmp_dir[1]; //fa puntare dir alla directory temp bool rt = _arc.backup(dir,_unit,_desc, TRUE); //esegue la compressione ed il salvataggio sul device scelto create_tmp_files(false); //apre i files temp, riallocandoli (NON li crea effettvam.) delete_tmp_files(true); //cancella fisicamente i files temp TFilename unit; unit << _unit << ':' << SLASH; if (!xvt_fsys_is_removable_drive(unit) && _path != "") //se il drive non e' rimovibile,sposta i files dalla root del drive { //alla target dir scritta sulla maschera for (int i = 0; i <= 1; i++) { TFilename orig = unit; TFilename dest; dest << unit << _path; const char * name = i == 0 ? "backup.ini" : "ve.z00"; orig << name; dest << SLASH << name; fcopy(orig, dest); xvt_fsys_remove_file(orig); //elimina il file di origine dopo averlo copiato } } } } } bool TArchive_doc::restore_file(TIsamtempfile& src, bool update) { TFast_isamfile dst(src.num()); TString msg; msg << TR("Trasferimento") << ' ' << dst.description(); TProgress_monitor pi(src.items(), msg); for (int err = src.first(); err == NOERR; err = src.next()) { err = src.curr().write(dst); if (err == _isreinsert) { if (update) err = src.curr().rewrite(dst); else err = NOERR; } if (err != NOERR) return cantwrite_box(src.description()); if (!pi.add_status(1)) break; } return true; } bool TArchive_doc::restore_clifo(bool update) { return restore_file(*_trcf, update) && restore_file(*_trcfv, update); } bool TArchive_doc::restore_docs() { bool ok = restore_file(*_trdoc, true); if (ok) { _tdoc->set_curr(new TDocumento); ok = restore_file(*_tdoc, false); } return ok; } void TArchive_doc::ripristina(const TMask& m) { _unit = m.get(F_DRIVE)[0]; _path = m.get(F_PATH); TFilename src; src << _unit << ':' << SLASH; if (!xvt_fsys_is_removable_drive(src) && _path.full()) src.add(_path); src.add("ve.z00"); const char* dst = & _tmp_dir[1]; if (::aga_unzip(src, dst)) { create_tmp_files(FALSE); // In realta' ci sono gia' if (m.get_bool(F_WITHCLI)) restore_clifo(m.get_bool(F_UPDATE)); restore_docs(); delete_tmp_files(true); // Removes temp files! } else error_box(TR("Errore nella scompattazione dei file. Nessun documento ricevuto.")); } ////////////////////////////////////////////////////////// ////////// Main loop del programma /////////// ////////////////////////////////////////////////////////// void TArchive_doc::main_loop() { TArchive_mask m; KEY key = K_ENTER; while (key != K_QUIT) { key=m.run(); if (key == K_ENTER) archivia(m); if (key == K_DEL) ripristina(m); } } int ve5400(int argc, char* argv[]) { TArchive_doc a; a.run(argc, argv, "Invio/Ricezione"); return 0; }