326 lines
12 KiB
C++
326 lines
12 KiB
C++
|
#include <applicat.h>
|
|||
|
#include <mask.h>
|
|||
|
#include <progind.h>
|
|||
|
#include <relation.h>
|
|||
|
#include <archives.h>
|
|||
|
#include <utility.h>
|
|||
|
|
|||
|
#include "ve5400.h"
|
|||
|
#include "velib.h"
|
|||
|
|
|||
|
#include <doc.h>
|
|||
|
|
|||
|
#include <agasys.h>
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------------------------
|
|||
|
//-------MASCHERA-----------------------------
|
|||
|
class TArchive_mask : public TMask
|
|||
|
{
|
|||
|
public:
|
|||
|
TArchive_mask();
|
|||
|
virtual ~TArchive_mask() { }
|
|||
|
};
|
|||
|
|
|||
|
TArchive_mask::TArchive_mask() : TMask("ve5400")
|
|||
|
{
|
|||
|
TList_field& lf = lfield(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
|
|||
|
{
|
|||
|
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();
|
|||
|
virtual bool create();
|
|||
|
void create_tmp_files(bool create);
|
|||
|
void delete_tmp_files(bool remove);
|
|||
|
void archivia(const TMask& m);
|
|||
|
bool ripristina(const TMask& m);
|
|||
|
|
|||
|
bool restore_file(TIsamtempfile& src, bool update);
|
|||
|
bool restore_clifo(bool update);
|
|||
|
bool restore_docs();
|
|||
|
|
|||
|
public:
|
|||
|
TArchive_doc() { }
|
|||
|
};
|
|||
|
|
|||
|
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 (<28> 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'<27> 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 <20>>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<63> la funzione <20> un metodo della TArchive_doc
|
|||
|
//e quindi l'oggetto <20> gi<67> 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 <20> 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'<27> 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; //fa puntare dir alla directory temp
|
|||
|
if (*dir == '%') dir++;
|
|||
|
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())
|
|||
|
{
|
|||
|
dst.curr() = src.curr();
|
|||
|
err = dst.write_rewrite();
|
|||
|
if (err != NOERR)
|
|||
|
return cantwrite_box(dst.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;
|
|||
|
}
|
|||
|
|
|||
|
bool 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");
|
|||
|
if (!src.exist())
|
|||
|
return cantread_box(src);
|
|||
|
|
|||
|
const char* dst = _tmp_dir;
|
|||
|
if (*dst == '%') dst++;
|
|||
|
|
|||
|
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
|
|||
|
return error_box(TR("Errore nella scompattazione dei file. Nessun documento ricevuto."));
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////
|
|||
|
////////// 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;
|
|||
|
}
|