From f8f3f0b24177ddda82d70af92376b737f7e163ae Mon Sep 17 00:00:00 2001 From: gianluca Date: Mon, 6 Nov 1995 10:41:27 +0000 Subject: [PATCH] Aggiunti metodi sget() per ottenere oggetti TString completi anziche' reference. git-svn-id: svn://10.65.10.50/trunk@2091 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/isam.h | 1026 +++++++++++------------ include/relapp.cpp | 1944 ++++++++++++++++++++++---------------------- include/strings.h | 9 + 3 files changed, 1497 insertions(+), 1482 deletions(-) diff --git a/include/isam.h b/include/isam.h index b9c94e585..8f54b9e25 100755 --- a/include/isam.h +++ b/include/isam.h @@ -1,510 +1,516 @@ -#ifndef __ISAM_H -#define __ISAM_H - -#ifndef __SYSFLD_H -#include -#endif - -#ifndef FOXPRO - -#ifndef __REAL_H -#include -#endif - -#endif - -#ifndef __DATE_H -#include -#endif - -#ifndef __STRINGS_H -#include -#endif - -#ifndef __FILES_H -#include -#endif - -#ifndef __LFFILES_H -#include -#endif - -#ifndef __TEXT_H -class TTextfile; -#endif - -// @M -#define FIELDERR -1 - -const int MAX_KEYS = 8; -// @END - -// @C -// Classe TRectype : public TObject -// -// Tipo record -// -// @END - -class TRectype : public TSortable -{ - friend class TExtrectype; - friend class TRecfield; - friend class TBaseisamfile; - friend class TLocalisamfile; - friend class TIsamtempfile; - - // DPRIV - char* _rec; // Puntatore a inizio record - int _logicnum; // Numero logico - int _length; // Lunghezza - bool _isempty; // Se il record e' vuoto - char _tab[5]; // identificatore della tabella - TRecfield * _cod; // campo "COD" della tabella - // @END - -protected: // TObject - virtual int compare(const TSortable& s) const; - -protected: - const char* start(int nf) const; - void setempty(bool val) { _isempty = val;} // Rende vero is_empty - -public: // TObject - virtual TObject* dup() const; // Duplica record - - virtual int read(TBaseisamfile& f, word op = _isequal); - virtual int next(TBaseisamfile& f); - virtual int write(TBaseisamfile& f) const; - virtual int rewrite(TBaseisamfile& f) const; - virtual int remove(TBaseisamfile& f) const; - virtual void renum_key(const char* field, const char* val); - -public: - // FPUB - int items() const; - void setdirty() { setempty(FALSE); } - void settab(const char *tab); - char* string() const { return _rec;} // Ritorna il puntatore all'inizio. NON dovrebbe essere usata! - - void discard() { *_rec = '*';} // Setta il flag di cancellazione - void recall() { *_rec = ' ';} // Ripristina il flag di cancellazione - bool isdeleted() const { return *_rec == '*';} // Chiede se e' cancellato - int len() const { return _length;} // Ritorna la lunghezza - TFieldtypes type(const char* fieldname) const; // Ritorna il tipo del campo - int length(const char* fieldname) const; // Ritorna lunghezza campo - int ndec(const char* fieldname) const; // Ritorna numero di decimali - bool exist(const char* fieldname) const; // Ritorna l'esistenza del campo - const char* fieldname(int i) const; // Ritorna il nome del campo i - - const char* get_str(const char* fieldname) const ; -#ifndef FOXPRO - const TString& get(const char* fieldname) const ; - int get_int(const char* fieldname) const ; - long get_long(const char* fieldname) const ; - word get_word(const char* fieldname) const ; - char get_char(const char* fieldname) const ; - bool get_bool(const char* fieldname) const ; - real get_real(const char* fieldname) const ; - bool get_memo(const char* fieldname, TTextfile& txt) const ; -#endif - TDate get_date(const char* fieldname) const ; - - - // @DES Put tipizzata - // @FPUB - -#ifndef FOXPRO - void put(const char* fieldname, int val); - void put(const char* fieldname, long val); - void put(const char* fieldname, word val); - void put(const char* fieldname, const TDate& val); - void put(const char* fieldname, char val); - void put(const char* fieldname, bool val); - void put(const char* fieldname, const real& val); - void put(const char* fieldname, TTextfile& txt); -#endif - - // @DES Put NON tipizzata - // @FPUB - void put(const char* fieldname, const char* val); - // void put(const char* fieldname, TString& val); - - void zero(const char * fieldname); // Vuota campo puntato da fieldname - void zero(); // Vuota tutto il record - void zero(char c); // Vuota tutto il record usando il carattere c - - TRectype& operator =(const TRectype& rec); // assegnazione tra TRectype - TRectype& operator =(const char* rec); // assegnazione tra TRectype - TRectype& operator =(const TBaseisamfile& f); - - virtual RecDes* rec_des() const; // Ritorna il descrittore del record - int num() const { return _logicnum;} // Ritorna il numero logico - bool empty() const {return _isempty;} // Ritorna se e' vuoto - bool valid() const {return _rec[0] == ' ';} // Ritorna se il record non e'cancellato - const char* key(int numkey = 1) const; // Ritorna l'espressione della chiave numero numkey - bool ok() const { return _rec != NULL; } - - TRectype(int logicnum); // Costruisce un record staccato da un file. Bisogna poi chiamare linkfile(). Sarebbe meglio utilizzare una delle altre due - TRectype(const TBaseisamfile* i); // Costruisce record e lo associa al file isam i - TRectype(const TRectype& r); // Costruisce il record a partire da r - - virtual ~TRectype(); -}; - -// @C -// Classe TBaseisamfile : public TObject -// -// File isam di base -// -// @END - -class TBaseisamfile : public TObject -{ - // @DPRIV - isdef* _isamfile; // Descrittore file isam - int _logicnum; // Numero logico del record corrente - int _lasterr; // Ultimo errore - bool _delrec; // Per sapere se rimuovere il record alla fine - bool _delopenrec; // Per sapere se rimuovere il record alla fine dalla lista interna di record - TRectype* _current; // Puntatore a record corrente - TFile _hf; - TFile _hfhd; - bool _historicfile; // Vero se il file e' archivio storico - TRecnotype _lasthf; - TRecnotype _recno; - - friend class TRectype; - friend class TLocalisamfile; - friend class TIsamfile; - friend class TIsamtempfile; - friend class TRecfield; - // friend class TCursor; - // @END - // @FPRIV - // friend TRecnotype __buildcursor(TFilecursor* tic, TRecnotype rp); - // friend TRecnotype __filtercursor(TFilecursor* tic); - // friend bool __evalcondition(TBaseisamfile* i,TString& condition); - // friend void __readrec(TFilecursor* tic); - - int gethr(TRectype& rec, TDate& atdate); - int addhr(const TRectype& rec, TDate& atdate); - int rewhr(const TRectype& rec, TDate& atdate); - int delhr(const TRectype& rec, TDate& atdate); - -protected: - // @FPROT - isdef** ptrfilehnd() const { return (isdef**) &_isamfile;} - void clearfilehnd() { _isamfile = NULL;} - - void recover(); - int _open(unsigned int mode = _manulock); // Apre isam file con lock - int _close(); - const char* filename() const; - -public: - // @FPUB - void setkey(int nkey); // Attiva una chiave - int getkey() const; // Ritorna la chiave - void setstatus(int status) { _lasterr = status; } // Setta _lasterr - virtual int first(word lockop = _nolock); - virtual int last(word lockop = _nolock); - virtual int next(word lockop = _nolock); - virtual int next(TDate& atdate); - virtual int prev(word lockop = _nolock); - virtual int prev(TDate& atdate); - virtual int reread(word lockop = _nolock, TDate& atdate = (TDate&)botime); - virtual int reread(TRectype& rec, word lockop = _nolock, TDate& atdate = (TDate&)botime); - virtual int skip(TRecnotype nrec, word lockop = _nolock); - virtual int read(word op = _isequal, word lockop = _nolock, TDate& atdate = (TDate&)botime); - virtual int read(TRectype& rec, word op = _isequal, word lockop = _nolock, TDate& atdate = (TDate&)botime); - virtual int readat(TRecnotype nrec, word lockop = _nolock); - virtual int readat(TRectype& rec, TRecnotype nrec, word lockop = _nolock); - virtual int write(TDate& atdate = (TDate&)botime); - virtual int write(const TRectype& rec, TDate& atdate = (TDate&)botime); - virtual int rewrite(TDate& atdate = (TDate&)botime); - virtual int rewrite(const TRectype& rec, TDate& atdate = (TDate&)botime); - virtual int rewriteat(TRecnotype nrec); - virtual int rewriteat(const TRectype& rec, TRecnotype nrec); - virtual int remove(TDate& atdate = (TDate&)botime); - virtual int remove(const TRectype& rec, TDate& atdate = (TDate&)botime); - virtual const char* name() const; - - TRecnotype recno() const { return _recno;} - int lock(); // Attiva lock di tutto il file - int unlock(); // Disattiva lock di tutto il file - void indexon(); // Accende gli indici - void indexoff(); // Spegne gli indici - int status() const { return _lasterr; } // Ritorna _lasterr - TRectype& curr() const {return *_current;} // Ritorna puntatore a record corrente - bool eof() const { return status() == _iseof || status() == _isemptyfile;} // Vero se siamo a fine file - bool bof() const { return status() == _isbof || status() == _isemptyfile;} // Vero se siamo a inizio file - bool good() const { return status() == NOERR;} // Vero se _lasterr non contiene codici d'errore - bool bad() const { return status() != NOERR;} // Vero se _lasterr contiene codici d'errore - bool empty(); // Vero se il file e' vuoto - int num() const { return _logicnum;} // Ritorna il numero logico del record corrente - const char* description() const; - TRecnotype eod() const ; - - isdef* filehnd() const { return (isdef*) _isamfile;} // Ritorna l'handle del file isam nella tabella - - long items() const; // n.o di records nel file - - // @DES Get tipizzata. Ritorna il contenuto del campo nei vari tipi - // @FPUB -#ifndef FOXPRO - int get_int(const char* fieldname) const - { return curr().get_int(fieldname);} - long get_long(const char* fieldname) const - { return curr().get_long(fieldname);} - word get_word(const char* fieldname) const - { return curr().get_word(fieldname);} - char get_char(const char* fieldname) const - { return curr().get_char(fieldname);} - bool get_bool(const char* fieldname) const - { return curr().get_bool(fieldname);} - real get_real(const char* fieldname) const - { return curr().get_real(fieldname);} - bool get_memo(const char* fieldname, TTextfile& txt) - { return curr().get_memo(fieldname, txt); } -#endif - TDate get_date(const char* fieldname) const - { return curr().get_date(fieldname);} - -#ifndef FOXPRO - const TString& get(const char* fieldname) const - { return curr().get(fieldname);} - void put(const char* fieldname, int val) - { curr().put(fieldname, val);} - void put(const char* fieldname, long val) - { curr().put(fieldname, val);} - void put(const char* fieldname, word val) - { curr().put(fieldname, val);} - void put(const char* fieldname, const TDate& val) - { curr().put(fieldname, val);} - void put(const char* fieldname, char val) - { curr().put(fieldname, val);} - void put(const char* fieldname, bool val) - { curr().put(fieldname, val);} - void put(const char* fieldname, const real& val) - { curr().put(fieldname, val);} - void put(const char* fieldname, TTextfile& txt) - { curr().put(fieldname, txt); } -#else - const char* get_str(const char* fieldname) const - { return curr().get_str(fieldname);} -#endif - - // @DES Put NON tipizzata - // @FPUB - void put(const char* fieldname, const char* val) - { curr().put(fieldname, val);} - - void zero(const char * fieldname) { curr().zero(fieldname);} - void zero() { curr().zero();} - void zero(char c) { curr().zero(c);} - TRectype& operator =(const TRectype& rec) { return curr() = rec;} - - TBaseisamfile(int logicnum, bool linkrecinst = FALSE); - virtual ~TBaseisamfile(); -}; - -// @C -// Classe TIsamfile : public TBaseisamfile -// -// File isam -// -// @END - -class TIsamfile : public TBaseisamfile -{ -public: - // @FPUB - int flags(bool updateeod = FALSE); - int open(unsigned int mode = _manulock) { return _open(mode);} // Apre isam file con lock - int close() { return _close();} - TIsamfile(int logicnum, bool linkrecinst); - virtual ~TIsamfile(); -}; - -// @C -// Classe TSystemisamfile : public TBaseisamfile -// -// @END - -class TSystemisamfile : public TIsamfile -{ - TArray _flds; - TArray _exps; - - bool getlcf(long flev); - bool exec_convapp(long flev, const bool before); - void makelc(TRectype& rec); - -public: - // @FPUB - int build(TRecnotype eox); // Costruisce un file isam - int extend(TRecnotype eox); // Estende un file preesistente - long size(TRecnotype eox); // Calcola lo spazio che il file occuperebbe se venisse esteso a eox - int update(TTrec& newrec, bool vis = TRUE); - - int pack(bool vis = TRUE); // Esegue packfile e packindex - int packfile(bool vis = TRUE); // Rimuove fisicamente i record cancellati - int packindex(bool vis = TRUE); // La stessa cosa sugli indici - - // @DES Importa un file ascii. from e' il nome del file da importare - int load(const char* from, char fs = '|', char fd = '\0', char rs = '\n', bool vis = TRUE, bool extended = FALSE) ; - - // @DES Esporta VERSO un file ascii. - int dump(const char* to, int nkey = 1, char fs = '|', char fd = '\0', char rs = '\n', bool vis = TRUE, bool withdeleted = FALSE); - - TSystemisamfile(int logicnum, bool linkrecinst = FALSE) - : TIsamfile(logicnum, linkrecinst) {} - virtual ~TSystemisamfile() {} -}; - -// @C -// Classe TLocalisamfile : public TBaseisamfile -// -// @END - -class TLocalisamfile : public TBaseisamfile -{ - // @DPRIV - bool _was_open; // Vero se il file e' stato aperto come Localisamfile - int _oldkey; // Old key if already open - -protected: - int open(unsigned int mode = _manulock); - int close() ; - -public: - // @FPUB - virtual int operator +=(const TRecnotype npos); // Avanza npos record - virtual int operator -=(const TRecnotype npos); // Sposta indietro di npos - virtual int operator ++(); // record successivo - virtual int operator --(); // record precedente - virtual bool tab() const { return FALSE;} // Ritorna vero se tabella - - // Costruttore. linkrecinst dice se il file deve utilizzare un area record separata oppure la stessa. - TLocalisamfile(int logicnum, bool linkrecinst = FALSE); - virtual ~TLocalisamfile(); -}; - -// @C -// Classe TIsamtempfile : public TLocalisamfile -// -// File isam temporaneo -// -// @END - -class TIsamtempfile : public TLocalisamfile -{ - bool _autodel; // Settato a true se create = 2: cancella il file in chiusura - -protected: - // Apre il file. radix e' la radice del path del file, - // se create e' falso vuol dire che il file esiste gia', - // e allora eod dice quanti record ci sono; eox quanti bisogna aggiungerne - int open(const char* radix, bool create, TRecnotype eod, TRecnotype eox); - int close(); - -public: - void set_autodel(bool val=TRUE) {_autodel = val;} - TIsamtempfile(int logicnum, const char* radix, bool create); - virtual ~TIsamtempfile(); -}; - -// @C -// Classe TRec_array : public TArray -// -// @END - -class TRec_array : public TArray -{ -public: - // @FPUB - TRec_array(int dimension, TBaseisamfile& i); -}; - -// @C -// Classe TRecfield : public TObject -// -// @END - -class TRecfield : public TObject -{ - // @DPRIV - char _name[12]; // Nome campo - TRectype* _rec; // Puntatore a inizio record - char* _p; // Puntatore a inizio campo - byte _len; // Lunghezza campo - byte _dec; // Numero di decimali - byte _type; // Tipo del campo - // @END - - // @FPRIV - void set(int from, int to); - -public: - // @FPUB - // @DES Operatore di assegnazione (=) per i vari tipi - // @FPUB - - int operator =(int i) ; - long operator =(long l) ; - const TDate& operator =(const TDate& d) ; - const char* operator =(const char* s) ; -#ifndef FOXPRO - const real& operator =(const real& r) ; -#endif // FOXPRO - - // @DES Operatore di estrazione per i vari tipi - // @FPUB - operator int() const ; - operator long() const ; - operator const char*() const ; - operator TDate() const ; -#ifndef FOXPRO - operator const real() const ; -#endif // FOXPRO - - - void setptr(TRecnotype r); // Scrive un campo packed. Sarebbe meglio non usare mai campi packed. - TRecnotype ptr() const; // Legge un campo packed. Sarebbe meglio non usare mai campi packed. - - const char* pos() const { return (const char*) _p;} // Ritorna un puntatore all'inizio del campo nel record. Dovrebbe essere protected! - int len() const { return (int) _len;} // Ritorna la lunghezza - int dec() const { return (int) _dec;} // Ritorna il numero di decimali - TFieldtypes type() const { return (TFieldtypes) _type;} // Ritorna il tipo del campo - TRectype& record() const { return *_rec;} // Ritorna puntatore a inizio record - - TRecfield(TRectype& rec, const char* name, int from = 0, int to = -1); -}; - -/* - - class TTransaction - { - public: - // @FPUB - void begin(); - void end(bool success = TRUE); - void abort() { end(FALSE);} - }; - - */ - -#ifdef __ISAM_CPP -#define extern -#endif - -// @DPUB -extern TRectype** openrec; -extern void get_idx_names(int logicnum, TToken_string& i_names); -// @END -#undef extern - -void set_autoload_new_files(bool on); - -#endif // __ISAM_ +#ifndef __ISAM_H +#define __ISAM_H + +#ifndef __SYSFLD_H +#include +#endif + +#ifndef FOXPRO + +#ifndef __REAL_H +#include +#endif + +#endif + +#ifndef __DATE_H +#include +#endif + +#ifndef __STRINGS_H +#include +#endif + +#ifndef __FILES_H +#include +#endif + +#ifndef __LFFILES_H +#include +#endif + +#ifndef __TEXT_H +class TTextfile; +#endif + +// @M +#define FIELDERR -1 + +const int MAX_KEYS = 8; +// @END + +// @C +// Classe TRectype : public TObject +// +// Tipo record +// +// @END + +class TRectype : public TSortable +{ + friend class TExtrectype; + friend class TRecfield; + friend class TBaseisamfile; + friend class TLocalisamfile; + friend class TIsamtempfile; + + // DPRIV + char* _rec; // Puntatore a inizio record + int _logicnum; // Numero logico + int _length; // Lunghezza + bool _isempty; // Se il record e' vuoto + char _tab[5]; // identificatore della tabella + TRecfield * _cod; // campo "COD" della tabella + // @END + +protected: // TObject + virtual int compare(const TSortable& s) const; + +protected: + const char* start(int nf) const; + void setempty(bool val) { _isempty = val;} // Rende vero is_empty + +public: // TObject + virtual TObject* dup() const; // Duplica record + + virtual int read(TBaseisamfile& f, word op = _isequal); + virtual int next(TBaseisamfile& f); + virtual int write(TBaseisamfile& f) const; + virtual int rewrite(TBaseisamfile& f) const; + virtual int remove(TBaseisamfile& f) const; + virtual void renum_key(const char* field, const char* val); + +public: + // FPUB + int items() const; + void setdirty() { setempty(FALSE); } + void settab(const char *tab); + char* string() const { return _rec;} // Ritorna il puntatore all'inizio. NON dovrebbe essere usata! + + void discard() { *_rec = '*';} // Setta il flag di cancellazione + void recall() { *_rec = ' ';} // Ripristina il flag di cancellazione + bool isdeleted() const { return *_rec == '*';} // Chiede se e' cancellato + int len() const { return _length;} // Ritorna la lunghezza + TFieldtypes type(const char* fieldname) const; // Ritorna il tipo del campo + int length(const char* fieldname) const; // Ritorna lunghezza campo + int ndec(const char* fieldname) const; // Ritorna numero di decimali + bool exist(const char* fieldname) const; // Ritorna l'esistenza del campo + const char* fieldname(int i) const; // Ritorna il nome del campo i + + const char* get_str(const char* fieldname) const ; +#ifndef FOXPRO + const TString& get(const char* fieldname) const ; + TString sget(const char* fieldname) const { return ((TString)get(fieldname)); } + int get_int(const char* fieldname) const ; + long get_long(const char* fieldname) const ; + word get_word(const char* fieldname) const ; + char get_char(const char* fieldname) const ; + bool get_bool(const char* fieldname) const ; + real get_real(const char* fieldname) const ; + bool get_memo(const char* fieldname, TTextfile& txt) const ; +#endif + TDate get_date(const char* fieldname) const ; + + + // @DES Put tipizzata + // @FPUB + +#ifndef FOXPRO + void put(const char* fieldname, int val); + void put(const char* fieldname, long val); + void put(const char* fieldname, word val); + void put(const char* fieldname, const TDate& val); + void put(const char* fieldname, char val); + void put(const char* fieldname, bool val); + void put(const char* fieldname, const real& val); + void put(const char* fieldname, TTextfile& txt); +#endif + + // @DES Put NON tipizzata + // @FPUB + void put(const char* fieldname, const char* val); + // void put(const char* fieldname, TString& val); + + void zero(const char * fieldname); // Vuota campo puntato da fieldname + void zero(); // Vuota tutto il record + void zero(char c); // Vuota tutto il record usando il carattere c + + void blank(const char * fieldname) { put(fieldname, " "); } // Riempie il campo di spazi + + TRectype& operator =(const TRectype& rec); // assegnazione tra TRectype + TRectype& operator =(const char* rec); // assegnazione tra TRectype + TRectype& operator =(const TBaseisamfile& f); + + virtual RecDes* rec_des() const; // Ritorna il descrittore del record + int num() const { return _logicnum;} // Ritorna il numero logico + bool empty() const {return _isempty;} // Ritorna se e' vuoto + bool valid() const {return _rec[0] == ' ';} // Ritorna se il record non e'cancellato + const char* key(int numkey = 1) const; // Ritorna l'espressione della chiave numero numkey + bool ok() const { return _rec != NULL; } + + TRectype(int logicnum); // Costruisce un record staccato da un file. Bisogna poi chiamare linkfile(). Sarebbe meglio utilizzare una delle altre due + TRectype(const TBaseisamfile* i); // Costruisce record e lo associa al file isam i + TRectype(const TRectype& r); // Costruisce il record a partire da r + + virtual ~TRectype(); +}; + +// @C +// Classe TBaseisamfile : public TObject +// +// File isam di base +// +// @END + +class TBaseisamfile : public TObject +{ + // @DPRIV + isdef* _isamfile; // Descrittore file isam + int _logicnum; // Numero logico del record corrente + int _lasterr; // Ultimo errore + bool _delrec; // Per sapere se rimuovere il record alla fine + bool _delopenrec; // Per sapere se rimuovere il record alla fine dalla lista interna di record + TRectype* _current; // Puntatore a record corrente + TFile _hf; + TFile _hfhd; + bool _historicfile; // Vero se il file e' archivio storico + TRecnotype _lasthf; + TRecnotype _recno; + + friend class TRectype; + friend class TLocalisamfile; + friend class TIsamfile; + friend class TIsamtempfile; + friend class TRecfield; + // friend class TCursor; + // @END + // @FPRIV + // friend TRecnotype __buildcursor(TFilecursor* tic, TRecnotype rp); + // friend TRecnotype __filtercursor(TFilecursor* tic); + // friend bool __evalcondition(TBaseisamfile* i,TString& condition); + // friend void __readrec(TFilecursor* tic); + + int gethr(TRectype& rec, TDate& atdate); + int addhr(const TRectype& rec, TDate& atdate); + int rewhr(const TRectype& rec, TDate& atdate); + int delhr(const TRectype& rec, TDate& atdate); + +protected: + // @FPROT + isdef** ptrfilehnd() const { return (isdef**) &_isamfile;} + void clearfilehnd() { _isamfile = NULL;} + + void recover(); + int _open(unsigned int mode = _manulock); // Apre isam file con lock + int _close(); + const char* filename() const; + +public: + // @FPUB + void setkey(int nkey); // Attiva una chiave + int getkey() const; // Ritorna la chiave + void setstatus(int status) { _lasterr = status; } // Setta _lasterr + virtual int first(word lockop = _nolock); + virtual int last(word lockop = _nolock); + virtual int next(word lockop = _nolock); + virtual int next(TDate& atdate); + virtual int prev(word lockop = _nolock); + virtual int prev(TDate& atdate); + virtual int reread(word lockop = _nolock, TDate& atdate = (TDate&)botime); + virtual int reread(TRectype& rec, word lockop = _nolock, TDate& atdate = (TDate&)botime); + virtual int skip(TRecnotype nrec, word lockop = _nolock); + virtual int read(word op = _isequal, word lockop = _nolock, TDate& atdate = (TDate&)botime); + virtual int read(TRectype& rec, word op = _isequal, word lockop = _nolock, TDate& atdate = (TDate&)botime); + virtual int readat(TRecnotype nrec, word lockop = _nolock); + virtual int readat(TRectype& rec, TRecnotype nrec, word lockop = _nolock); + virtual int write(TDate& atdate = (TDate&)botime); + virtual int write(const TRectype& rec, TDate& atdate = (TDate&)botime); + virtual int rewrite(TDate& atdate = (TDate&)botime); + virtual int rewrite(const TRectype& rec, TDate& atdate = (TDate&)botime); + virtual int rewriteat(TRecnotype nrec); + virtual int rewriteat(const TRectype& rec, TRecnotype nrec); + virtual int remove(TDate& atdate = (TDate&)botime); + virtual int remove(const TRectype& rec, TDate& atdate = (TDate&)botime); + virtual const char* name() const; + + TRecnotype recno() const { return _recno;} + int lock(); // Attiva lock di tutto il file + int unlock(); // Disattiva lock di tutto il file + void indexon(); // Accende gli indici + void indexoff(); // Spegne gli indici + int status() const { return _lasterr; } // Ritorna _lasterr + TRectype& curr() const {return *_current;} // Ritorna puntatore a record corrente + bool eof() const { return status() == _iseof || status() == _isemptyfile;} // Vero se siamo a fine file + bool bof() const { return status() == _isbof || status() == _isemptyfile;} // Vero se siamo a inizio file + bool good() const { return status() == NOERR;} // Vero se _lasterr non contiene codici d'errore + bool bad() const { return status() != NOERR;} // Vero se _lasterr contiene codici d'errore + bool empty(); // Vero se il file e' vuoto + int num() const { return _logicnum;} // Ritorna il numero logico del record corrente + const char* description() const; + TRecnotype eod() const ; + + isdef* filehnd() const { return (isdef*) _isamfile;} // Ritorna l'handle del file isam nella tabella + + long items() const; // n.o di records nel file + + // @DES Get tipizzata. Ritorna il contenuto del campo nei vari tipi + // @FPUB +#ifndef FOXPRO + int get_int(const char* fieldname) const + { return curr().get_int(fieldname);} + long get_long(const char* fieldname) const + { return curr().get_long(fieldname);} + word get_word(const char* fieldname) const + { return curr().get_word(fieldname);} + char get_char(const char* fieldname) const + { return curr().get_char(fieldname);} + bool get_bool(const char* fieldname) const + { return curr().get_bool(fieldname);} + real get_real(const char* fieldname) const + { return curr().get_real(fieldname);} + bool get_memo(const char* fieldname, TTextfile& txt) + { return curr().get_memo(fieldname, txt); } +#endif + TDate get_date(const char* fieldname) const + { return curr().get_date(fieldname);} + +#ifndef FOXPRO + const TString& get(const char* fieldname) const + { return curr().get(fieldname);} + TString sget(const char* fieldname) const + { return ((TString)get(fieldname)); } + void put(const char* fieldname, int val) + { curr().put(fieldname, val);} + void put(const char* fieldname, long val) + { curr().put(fieldname, val);} + void put(const char* fieldname, word val) + { curr().put(fieldname, val);} + void put(const char* fieldname, const TDate& val) + { curr().put(fieldname, val);} + void put(const char* fieldname, char val) + { curr().put(fieldname, val);} + void put(const char* fieldname, bool val) + { curr().put(fieldname, val);} + void put(const char* fieldname, const real& val) + { curr().put(fieldname, val);} + void put(const char* fieldname, TTextfile& txt) + { curr().put(fieldname, txt); } +#else + const char* get_str(const char* fieldname) const + { return curr().get_str(fieldname);} +#endif + + // @DES Put NON tipizzata + // @FPUB + void put(const char* fieldname, const char* val) + { curr().put(fieldname, val);} + + void zero(const char * fieldname) { curr().zero(fieldname);} + void zero() { curr().zero();} + void zero(char c) { curr().zero(c);} + void blank(const char * fieldname) { curr().blank(fieldname); } + TRectype& operator =(const TRectype& rec) { return curr() = rec;} + + TBaseisamfile(int logicnum, bool linkrecinst = FALSE); + virtual ~TBaseisamfile(); +}; + +// @C +// Classe TIsamfile : public TBaseisamfile +// +// File isam +// +// @END + +class TIsamfile : public TBaseisamfile +{ +public: + // @FPUB + int flags(bool updateeod = FALSE); + int open(unsigned int mode = _manulock) { return _open(mode);} // Apre isam file con lock + int close() { return _close();} + TIsamfile(int logicnum, bool linkrecinst); + virtual ~TIsamfile(); +}; + +// @C +// Classe TSystemisamfile : public TBaseisamfile +// +// @END + +class TSystemisamfile : public TIsamfile +{ + TArray _flds; + TArray _exps; + + bool getlcf(long flev); + bool exec_convapp(long flev, const bool before); + void makelc(TRectype& rec); + +public: + // @FPUB + int build(TRecnotype eox); // Costruisce un file isam + int extend(TRecnotype eox); // Estende un file preesistente + long size(TRecnotype eox); // Calcola lo spazio che il file occuperebbe se venisse esteso a eox + int update(TTrec& newrec, bool vis = TRUE); + + int pack(bool vis = TRUE); // Esegue packfile e packindex + int packfile(bool vis = TRUE); // Rimuove fisicamente i record cancellati + int packindex(bool vis = TRUE); // La stessa cosa sugli indici + + // @DES Importa un file ascii. from e' il nome del file da importare + int load(const char* from, char fs = '|', char fd = '\0', char rs = '\n', bool vis = TRUE, bool extended = FALSE) ; + + // @DES Esporta VERSO un file ascii. + int dump(const char* to, int nkey = 1, char fs = '|', char fd = '\0', char rs = '\n', bool vis = TRUE, bool withdeleted = FALSE); + + TSystemisamfile(int logicnum, bool linkrecinst = FALSE) + : TIsamfile(logicnum, linkrecinst) {} + virtual ~TSystemisamfile() {} +}; + +// @C +// Classe TLocalisamfile : public TBaseisamfile +// +// @END + +class TLocalisamfile : public TBaseisamfile +{ + // @DPRIV + bool _was_open; // Vero se il file e' stato aperto come Localisamfile + int _oldkey; // Old key if already open + +protected: + int open(unsigned int mode = _manulock); + int close() ; + +public: + // @FPUB + virtual int operator +=(const TRecnotype npos); // Avanza npos record + virtual int operator -=(const TRecnotype npos); // Sposta indietro di npos + virtual int operator ++(); // record successivo + virtual int operator --(); // record precedente + virtual bool tab() const { return FALSE;} // Ritorna vero se tabella + + // Costruttore. linkrecinst dice se il file deve utilizzare un area record separata oppure la stessa. + TLocalisamfile(int logicnum, bool linkrecinst = FALSE); + virtual ~TLocalisamfile(); +}; + +// @C +// Classe TIsamtempfile : public TLocalisamfile +// +// File isam temporaneo +// +// @END + +class TIsamtempfile : public TLocalisamfile +{ + bool _autodel; // Settato a true se create = 2: cancella il file in chiusura + +protected: + // Apre il file. radix e' la radice del path del file, + // se create e' falso vuol dire che il file esiste gia', + // e allora eod dice quanti record ci sono; eox quanti bisogna aggiungerne + int open(const char* radix, bool create, TRecnotype eod, TRecnotype eox); + int close(); + +public: + void set_autodel(bool val=TRUE) {_autodel = val;} + TIsamtempfile(int logicnum, const char* radix, bool create); + virtual ~TIsamtempfile(); +}; + +// @C +// Classe TRec_array : public TArray +// +// @END + +class TRec_array : public TArray +{ +public: + // @FPUB + TRec_array(int dimension, TBaseisamfile& i); +}; + +// @C +// Classe TRecfield : public TObject +// +// @END + +class TRecfield : public TObject +{ + // @DPRIV + char _name[12]; // Nome campo + TRectype* _rec; // Puntatore a inizio record + char* _p; // Puntatore a inizio campo + byte _len; // Lunghezza campo + byte _dec; // Numero di decimali + byte _type; // Tipo del campo + // @END + + // @FPRIV + void set(int from, int to); + +public: + // @FPUB + // @DES Operatore di assegnazione (=) per i vari tipi + // @FPUB + + int operator =(int i) ; + long operator =(long l) ; + const TDate& operator =(const TDate& d) ; + const char* operator =(const char* s) ; +#ifndef FOXPRO + const real& operator =(const real& r) ; +#endif // FOXPRO + + // @DES Operatore di estrazione per i vari tipi + // @FPUB + operator int() const ; + operator long() const ; + operator const char*() const ; + operator TDate() const ; +#ifndef FOXPRO + operator const real() const ; +#endif // FOXPRO + + + void setptr(TRecnotype r); // Scrive un campo packed. Sarebbe meglio non usare mai campi packed. + TRecnotype ptr() const; // Legge un campo packed. Sarebbe meglio non usare mai campi packed. + + const char* pos() const { return (const char*) _p;} // Ritorna un puntatore all'inizio del campo nel record. Dovrebbe essere protected! + int len() const { return (int) _len;} // Ritorna la lunghezza + int dec() const { return (int) _dec;} // Ritorna il numero di decimali + TFieldtypes type() const { return (TFieldtypes) _type;} // Ritorna il tipo del campo + TRectype& record() const { return *_rec;} // Ritorna puntatore a inizio record + + TRecfield(TRectype& rec, const char* name, int from = 0, int to = -1); +}; + +/* + + class TTransaction + { + public: + // @FPUB + void begin(); + void end(bool success = TRUE); + void abort() { end(FALSE);} + }; + + */ + +#ifdef __ISAM_CPP +#define extern +#endif + +// @DPUB +extern TRectype** openrec; +extern void get_idx_names(int logicnum, TToken_string& i_names); +// @END +#undef extern + +void set_autoload_new_files(bool on); + +#endif // __ISAM_ diff --git a/include/relapp.cpp b/include/relapp.cpp index 8a1ffac15..b84007bff 100755 --- a/include/relapp.cpp +++ b/include/relapp.cpp @@ -1,972 +1,972 @@ -// $Id: relapp.cpp,v 1.68 1995-10-25 09:43:44 guy Exp $ -#include -#include -#include -#include -#include -#include - -#if XVT_OS == XVT_OS_WIN -#include -#endif - -/////////////////////////////////////////////////////////// -// Array delle chiavi della maschera di ricerca -/////////////////////////////////////////////////////////// - -class TChiave : public TObject -{ - enum { MAX = 16 }; - int _pos[MAX]; - byte _num; - -public: - void add(int p); - int pos(byte n) const { return (n >= _num) ? -1 : _pos[n]; } - byte items() const { return _num; } - TChiave() : _num(0) {} - virtual ~TChiave() {} -}; - -void TChiave::add(int p) -{ - CHECKD(_num < MAX, "Too many fields in key : field n.", p); - _pos[_num++] = p; -} - -class TKey_array : public TArray -{ - const TMask* _mask; - -public: - TKey_array(const TMask* m); - virtual ~TKey_array() {} - - TChiave& key(byte k); -}; - -TChiave& TKey_array::key(byte k) -{ - k--; - TChiave* chiave = (TChiave*)objptr(k); - if (chiave == NULL) - { - chiave = new TChiave; - add(chiave, k); - } - return *chiave; -} - -TKey_array::TKey_array(const TMask* m) : _mask(m) -{ - const byte keys = m->num_keys(); - for (int f = 0; f < m->fields(); f++) - { - TMask_field& c = m->fld(f); - if (c.in_key(0)) - for (byte k = 1; k <= keys; k++) - if (c.in_key(k)) - key(k).add(f); - } -} - -/////////////////////////////////////////////////////////// -// TRelation_application -/////////////////////////////////////////////////////////// - -TRelation_application::TRelation_application() -: _mask(NULL), _maskeys(NULL), _search_id(-1), _lnflag(FALSE) -{} - -TRelation_application::~TRelation_application() -{ - if (_maskeys) delete _maskeys; -} - -void TRelation_application::setkey() -{ - if (has_filtered_cursor()) - { - TEdit_field* f = (TEdit_field*) get_search_field(); - TCursor* cur = f->browse()->cursor(); - cur->setkey(); - return; - } - file().setkey(1); -} - - -// what - meaning -// 0 - nop -// 1 - first -// 2 - last -// 3 - both -void TRelation_application::set_limits(byte what) -{ - if (has_filtered_cursor()) - { - TEdit_field* f = (TEdit_field*)get_search_field(); - CHECK(f, "Manca il campo di ricerca"); - - TBrowse* b = f->browse(); - TCursor* cur = b ? b->cursor() : NULL; - if (cur) - { - cur->setkey(); - f->browse()->do_input(TRUE); - if (cur->items() == 0) _first = _last = -1; - else - { - if (what & 0x1) - { - *cur = 0; - _first = cur->file().recno(); - } - if (what & 0x2) - { - *cur = cur->items() - 1; - _last = cur->file().recno(); - } - } - return; - } - } - - file().setkey(1); - if (what & 0x1) - { - if (file().empty()) _first = 1; - else - { - file().first(); - _first = file().recno(); - } - } - if (what & 0x2) - { - if (file().empty()) _last = 1; - else - { - file().last(); - _last = file().recno(); - } - } -} - -bool TRelation_application::create() -{ - TApplication::create(); - const bool ok = user_create(); - if (ok) - { - write_enable(); - _mask = get_mask(MODE_QUERY); - filter(); - _maskeys = new TKey_array(_mask); - set_limits(); - dispatch_e_menu(BAR_ITEM(1)); - } - return ok; -} - - -bool TRelation_application::menu(MENU_TAG m) -{ - if (m == BAR_ITEM(1)) - return main_loop(); - return TRUE; -} - - -bool TRelation_application::destroy() -{ - if (_maskeys) delete _maskeys; - user_destroy(); - return TApplication::destroy(); -} - - -void TRelation_application::set_fixed() -{ - TString256 s; - for (const char* f = _fixed.get(0); f && *f; f = _fixed.get()) - { - s = f; - const int u = s.find('='); - const int id = atoi(s.left(u)); - const char* val = s.mid(u+1); - if (*val) - _mask->set(id, val); - _mask->disable(id); - } -} - - -void TRelation_application::enable_query() -{ - const bool query = _mask->query_mode(); - const bool keyon = query || get_relation()->status() == _isreinsert; - - for (byte k = 1; k <= _maskeys->items(); k++) - { - const TChiave& chiave = _maskeys->key(k); - for (int i = 0; i < chiave.items(); i++) - { - const int num = chiave.pos(i); - TMask_field& c = _mask->fld(num); - if (c.enabled_default()) - { - if (k == 1) - c.enable(keyon); - if (c.has_query()) - ((TEdit_field&)c).enable_check(query); - } - } - } - - set_fixed(); -} - - -void TRelation_application::set_toolbar(bool all) -{ - const int mode = _mask->mode(); - int pos; - - if (all) - { - pos = _mask->id2pos(DLG_SAVEREC); - if (pos >= 0) _mask->fld(pos).enable(mode != MODE_QUERY); - pos = _mask->id2pos(DLG_DELREC); - if (pos >= 0) - { - bool enabdel = mode == MODE_MOD; - if (enabdel) - { - TRelation& r = *get_relation(); - const TRecnotype oldpos = r.lfile().recno(); - enabdel = !protected_record(r.curr()); - if (r.lfile().recno() != oldpos) - r.lfile().readat(oldpos); - } - _mask->fld(pos).enable(enabdel); - } - } - - enable_query(); -} - - -bool TRelation_application::save_and_new() const -{ return FALSE; } - -int TRelation_application::set_mode(int mode) -{ - static int _mode = NO_MODE; - if (mode < NO_MODE) mode = _mode; - - const int m = ((TMaskmode)mode == NO_MODE) ? (int) MODE_QUERY : mode; - _mask->set_mode(m); - - if (mode == _mode) - { - set_toolbar(FALSE); // Fast buttons update - } - else - { - set_toolbar(TRUE); // Full buttons update - _mode = mode; - } - - const char* t = ""; - switch(mode) - { - case MODE_QUERY: - t = "Ricerca"; break; - case MODE_MOD: - t = "Modifica"; break; - case NO_MODE: - t = "Ricerca/Inserimento"; break; - case MODE_INS: - t = "Inserimento"; break; - default: - break; - } - - xvt_statbar_set(t, TRUE); - - return _mode; -} - - -bool TRelation_application::autonum(TMask* m, bool rec) -{ - TToken_string k(get_next_key()); - - if (!rec && !m->query_mode()) - m->reset(); - _renum_message = ""; - - for (const char* n = k.get(0); n && *n; n = k.get()) - { - const short id = atoi(n); - CHECKD (id > 0, "Identificatore di autonumerazione errato: ", id); - const char* val = k.get(); - TMask_field& f = m->field(id); - if (rec || f.get().empty()) f.set(val); - if (rec) f.autosave(get_relation()); - if (_renum_message.empty() || f.in_key(1)) - _renum_message.format("Il documento e' stato registrato con :\n %s = %s", (const char *) f.prompt(), (const char *) f.get()); - } - return k.not_empty(); -} - - -void TRelation_application::query_mode(bool pre_ins) -{ - TMask* old = _mask; - const bool was_open = old != NULL && old->is_open(); - const bool changing = changing_mask(MODE_QUERY); - - if (changing && was_open) - old->close_modal(); - - _mask = get_mask(MODE_QUERY); - if (changing) - { - if (was_open) - _mask->open_modal(); - if (_maskeys) delete _maskeys; - _maskeys = new TKey_array(_mask); - set_limits(); - } - - _mask->reset(); - - if (pre_ins) - { - set_mode(NO_MODE); - init_query_insert_mode(*_mask); - } - else - { - set_mode(MODE_QUERY); - init_query_mode(*_mask); - } -} - - -void TRelation_application::insert_mode() -{ - if (_mask->query_mode()) - { - if (test_key(1, FALSE) == FALSE) - { - if (!autonum(_mask, FALSE)) - { - query_insert_mode(); - return; - } - } - - const bool changing = changing_mask(MODE_INS); - TFilename workname; workname.temp("msk"); - if (changing) - { - _mask->set_workfile(workname); - _mask->save(); - _mask->close_modal(); - } - _mask = get_mask(MODE_INS); - if (changing) - { - _mask->reset(); - _mask->set_workfile(workname); - _mask->load(); - ::remove(workname); - _mask->open_modal(); - delete _maskeys; - _maskeys = new TKey_array(_mask); - } - } - else - { - if (!autonum(_mask, FALSE)) - { - query_insert_mode(); - return; - } - } - - set_mode(MODE_INS); - - get_relation()->zero(); // Azzera tutta la relazione! - init_insert_mode(*_mask); -} - -bool TRelation_application::modify_mode() -{ - int err = get_relation()->read(_isequal, _testandlock); - if (err != NOERR) - { - if (err == _islocked) - message_box("I dati sono gia' in uso ad un altro programma"); - else - error_box("Impossibile leggere i dati: errore %d", err); - query_mode(); - return FALSE; - } - - const bool changing = changing_mask(MODE_MOD); - if (changing) - _mask->close_modal(); - - _mask = get_mask(MODE_MOD); - - if (changing) - { - _mask->open_modal(); - delete _maskeys; - _maskeys = new TKey_array(_mask); - } - - set_mode(MODE_MOD); - - err = read(*_mask); - if (err != NOERR) - { - query_mode(); - return FALSE; - } - - get_relation()->save_status(); - init_modify_mode(*_mask); - return TRUE; -} - - -TMask_field* TRelation_application::get_search_field() const -{ - if (_search_id > 0) - return &_mask->field(_search_id); - - const TChiave& k = _maskeys->key(1); - for (int i = 0; i < k.items(); i++) - { - TMask_field* f = &_mask->fld(k.pos(i)); - if (f->required()) return f; - } - return NULL; -} - -bool TRelation_application::search_mode() -{ - if (_mask->mode() != MODE_QUERY) - query_mode(); - - TMask_field* prima = get_search_field(); - while (prima) - { - if (prima->on_key(K_F9)) - { - if (find(1)) - return modify_mode(); - } - - TMask_field* dopo = &_mask->focus_field(); - prima = (dopo == prima) ? NULL : dopo; - } - return FALSE; -} - - -bool TRelation_application::test_key(byte k, bool err) -{ - const TChiave& chiave = _maskeys->key(k); - bool onereq = FALSE, onefill = FALSE; - - for (int i = 0; i < chiave.items(); i++) - { - const int num = chiave.pos(i); - TMask_field& c = _mask->fld(num); - - if (c.required()) - { - onereq = TRUE; - if (c.get().empty()) - { - if (err) - { - _mask->first_focus(-c.dlg()); - error_box("Manca un valore indispensabile per la ricerca"); - } - return FALSE; - } - } - else - /* if (k == 1 && !onereq && !onefill && c.get().not_empty()) */ - if (!onereq && !onefill && c.is_edit() && c.get().not_empty()) - onefill = TRUE; - } - if (k == 1 && !onereq && !onefill) - { - if (err) - error_box("Manca un valore indispensabile per la ricerca"); - return FALSE; - } - return onefill || onereq; -} - -// Guy: doesn't change fields -bool TRelation_application::find(byte k) -{ - if (changing_keys()) - { - delete _maskeys; - _maskeys= new TKey_array(_mask); - } - - const byte numkeys = _maskeys->items(); - - if (k == 0) - { - for (k = 1; k <= numkeys && !test_key(k, FALSE); k++); - if (k > numkeys) - return test_key(1, TRUE); - } - - file().setkey(k); - file().zero(); - const TChiave& chiave = _maskeys->key(k); - for (int i = 0; i < chiave.items(); i++) - { - const TMask_field& c = _mask->fld(chiave.pos(i)); - if (c.shown()) // Ignora campi invisibili - c.autosave(get_relation()); - } - - const int err = file().read(_isequal); - return err == NOERR; -} - - -bool TRelation_application::save(bool check_dirty) -{ - static bool was_dirty = FALSE; - - int err = NOERR; - const int mode = _mask->mode(); - - if (check_dirty) - { - const int dirty = _mask->dirty(); - - const char* ms = (mode == MODE_MOD) ? "le modifiche" : "i dati inseriti"; - - if (mode == MODE_QUERY) - { - const bool cont = !dirty || yesno_box("Annullare %s?", ms); - return cont; - } - - if (!dirty && !was_dirty) - { - if (mode == MODE_MOD) - { - get_relation()->restore_status(); - get_relation()->lfile().reread(_unlock); // Unlock main file - } - return TRUE; - } - - const KEY last = _mask->last_key(); - const bool annulla = last == K_ESC || last == K_QUIT || last == K_F9; - const bool errore = dirty && _mask->field(dirty).dirty() > TRUE; - - KEY k; - if (errore) - { - if (annulla) - { - TString80 w(_mask->field(dirty).warning()); - if (w.empty()) w = "Campo inconsistente"; - w << ": si desidera "; - switch (last) - { - case K_ESC: - w << "annullare?"; break; - case K_QUIT: - w << "uscire?"; break; - default: - w << "continuare?"; break; - } - k = yesno_box(w) ? K_NO : K_ESC; - if (k == K_ESC) - _mask->first_focus(-dirty); - } - else k = K_ESC; - } - else - k = yesnocancel_box("Registrare %s?", ms); - - if (k == K_ESC || k == K_NO) - { - if (mode == MODE_MOD) - { - get_relation()->restore_status(); - get_relation()->lfile().reread(_unlock); // Unlock main file - } - was_dirty = FALSE; - return k == K_NO; - } - - if (annulla) - { - if (!_mask->check_fields()) // Exit with ESC didn't check values - { - _mask->first_focus(-_mask->focus_field().dlg()); - was_dirty = TRUE; - return FALSE; - } - } - } - was_dirty = FALSE; - - begin_wait(); - if (mode == MODE_INS) - { - bool changed = TRUE; - bool changed_key = FALSE; - - while (changed) - { - err = write(*_mask); - if (err == _isreinsert) - { - changed = autonum(_mask, TRUE); - if (!changed) - { - _mask->disable_starting_check(); - enable_query(); // Abilita chiave 1 per rinumerazione manuale - } - else - changed_key = TRUE; - } - else - changed = FALSE; - } - if (err == NOERR) - { - if (changed_key) - message_box(_renum_message); - get_relation()->save_status(); - set_limits(); - get_relation()->restore_status(); - } - } - else - { - get_relation()->restore_status(); - err = rewrite(*_mask); - } - end_wait(); - - switch(err) - { - case NOERR: - _recins = get_relation()->lfile().recno(); - break; - case _isreinsert: - warning_box("Esiste gia' un documento con la stessa chiave"); - break; - default: - error_box("Impossibile registrare i dati: errore %d", err); - break; - } - return err == NOERR; -} - - -int TRelation_application::read(TMask& m) -{ - const TRelation *r = get_relation(); - m.autoload(r); - return NOERR; -} - - -int TRelation_application::write(const TMask& m) -{ - TRelation *r = get_relation(); - m.autosave(r); - r->write(); - return r->status(); -} - - -int TRelation_application::rewrite(const TMask& m) -{ - TRelation *r = get_relation(); - m.autosave(r); - r->rewrite(); - return r->status(); -} - - -bool TRelation_application::relation_remove() -{ - CHECK(_mask->mode() == MODE_MOD, "You can call remove in MODE_MOD only"); - TRelation *r = get_relation(); - - r->restore_status(); - - if (protected_record(r->curr())) - return message_box("Registrazione non eliminabile"); - - if (yesno_box("Confermare l'eliminazione")) - { - r->restore_status(); - const bool ok = remove(); - if (ok) - set_limits(); - else - return error_box("Errore di cancellazione %d", r->status()); - } - return TRUE; -} - - -bool TRelation_application::remove() -{ - const int err = get_relation()->remove(); - return err == NOERR; -} - -bool TRelation_application::firm_change_enabled() const -{ - bool ok = TApplication::firm_change_enabled(); - if (ok) ok = curr_mask().query_mode(); - return ok; -} - -bool TRelation_application::main_loop() -{ - _recins = -1; - - query_mode(); - _mask->open_modal(); - - KEY k; - - // Provoca l'autopremimento per il messaggio di LINK - if (_lnflag) _mask->send_key(K_AUTO_ENTER, 0); - - do - { - const bool change = firm_change_enabled(); - // Dis/abilita cambio ditta - enable_menu_item(M_FILE_NEW, change); - // Dis/abilita cambio parametri - enable_menu_item(M_FILE_REVERT, change); - - k = _mask->run(); - - switch (k) - { - case K_ESC: - if (save(TRUE)) - query_mode(); - if (_lnflag) - k = K_QUIT; - break; - case K_QUIT: - if (!save(TRUE)) - k = K_ENTER; - break; - case K_ENTER: - if (find(0)) modify_mode(); - else insert_mode(); - break; - case K_SAVE: - if (save(FALSE)) - { - if (_autoins_caller.not_empty()) - { - k = K_QUIT; - } - else - { - if (save_and_new()) - { - if (_mask->insert_mode()) - insert_mode(); - else - query_mode(); - } - else - modify_mode(); - } - } - break; - case K_INS: - if (_mask->query_mode() || save(TRUE)) - insert_mode(); - break; - case K_DEL: - if (relation_remove()) - query_mode(); - if (_autoins_caller.not_empty()) - { - if (_lnflag) _recins = 0; - k = K_QUIT; - } - break; - case K_F9: - if (save(TRUE)) - search_mode(); - break; - default: - if (save(TRUE)) - { - setkey(); - int err = ~NOERR; - switch (k) - { - case K_HOME: - err = file().readat(_first, _testandlock); - break; - case K_NEXT: - err = file().reread(); - err = file().next(_testandlock); - break; - case K_PREV: - err = file().reread(); - err = file().prev(_testandlock); - break; - case K_END: - err = file().readat(_last, _testandlock); - break; - default: - break; - } - if (err == NOERR || err == _islocked) modify_mode(); - else query_mode(); - } - break; - } - } while (k != K_QUIT); - - if (_mask->is_open()) - _mask->close_modal(); - - _mask->set_mode(NO_MODE); - - if (autoins_caller().not_empty() && _recins >= 0) - { - TMessage msg(autoins_caller(), _lnflag ? MSG_LN : MSG_AI, format("%ld", _recins)); - msg.send(); - } - - return k != K_QUIT; -} - -bool TRelation_application::filter() -{ - TMailbox mail; - TMessage* msg = mail.next_s(MSG_FS); - - if (msg) - { - _mask = get_mask(MODE_MOD); - TToken_string body = msg->body(); - - short id = body.get_int(); - while (id > 0) - { - _search_id = id; - TEdit_field& f = (TEdit_field&)_mask->field(id); - TCursor* cur = f.browse()->cursor(); - TRectype& rec = cur->curr(); - rec.zero(); - - TString80 t; - const char* s; - while((s = body.get()) != NULL) - { - t = s; - const int u = t.find('='); - if (u < 0) - { - id = atoi(t); - break; - } - _fixed.add(t); - const short fid = atoi(t.left(u)); - const TFieldref* campo = _mask->field(fid).field(); - if (campo != NULL) - campo->write(t.mid(u+1), rec); - } - cur->setfilter(""); - cur->setregion(rec, rec); - if (s == NULL) id = 0; - } - } - - mail.restart(); - msg = mail.next_s(MSG_AI); - if (msg) _autoins_caller = msg->from(); - - mail.restart(); - msg = mail.next_s(MSG_LN); - if (msg) - { - TToken_string body(msg->body()); - const int key = body.get_int(); - - _autoins_caller = msg->from(); - _lnflag = TRUE; - - const char* v = body.get(); - TString80 s; - for (int i = 0; v != NULL && i < _mask->fields(); i++) - { - TMask_field& f = _mask->fld(i); - - if (f.active() && f.dlg() > 0 && f.in_key(key)) - { - s = v; - _fixed.add(format("%d=%s", f.dlg(), (const char*)s)); - v = body.get(); - } - } - } - - return TRUE; -} - -void TRelation_application::set_link(TMask & m, const char * keyexpr) - -{ - CHECK(keyexpr != NULL, "Invalid expression"); - TToken_string body(keyexpr); - const int key = body.get_int(); - - _lnflag = TRUE; - - const char* v = body.get(); - - const int max = m.fields(); - for (int i = 0; i < max && v != NULL; i++) - { - TMask_field& f = m.fld(i); - - if (f.active() && f.dlg() > 0 && f.in_key(key)) - { - const TString s(v); - _fixed.add(format("%d=%s", f.dlg(), (const char*) s)); - v = body.get(); - } - } -} - - +// $Id: relapp.cpp,v 1.69 1995-11-06 10:41:25 gianluca Exp $ +#include +#include +#include +#include +#include +#include + +#if XVT_OS == XVT_OS_WIN +#include +#endif + +/////////////////////////////////////////////////////////// +// Array delle chiavi della maschera di ricerca +/////////////////////////////////////////////////////////// + +class TChiave : public TObject +{ + enum { MAX = 16 }; + int _pos[MAX]; + byte _num; + +public: + void add(int p); + int pos(byte n) const { return (n >= _num) ? -1 : _pos[n]; } + byte items() const { return _num; } + TChiave() : _num(0) {} + virtual ~TChiave() {} +}; + +void TChiave::add(int p) +{ + CHECKD(_num < MAX, "Too many fields in key : field n.", p); + _pos[_num++] = p; +} + +class TKey_array : public TArray +{ + const TMask* _mask; + +public: + TKey_array(const TMask* m); + virtual ~TKey_array() {} + + TChiave& key(byte k); +}; + +TChiave& TKey_array::key(byte k) +{ + k--; + TChiave* chiave = (TChiave*)objptr(k); + if (chiave == NULL) + { + chiave = new TChiave; + add(chiave, k); + } + return *chiave; +} + +TKey_array::TKey_array(const TMask* m) : _mask(m) +{ + const byte keys = m->num_keys(); + for (int f = 0; f < m->fields(); f++) + { + TMask_field& c = m->fld(f); + if (c.in_key(0)) + for (byte k = 1; k <= keys; k++) + if (c.in_key(k)) + key(k).add(f); + } +} + +/////////////////////////////////////////////////////////// +// TRelation_application +/////////////////////////////////////////////////////////// + +TRelation_application::TRelation_application() +: _mask(NULL), _maskeys(NULL), _search_id(-1), _lnflag(FALSE) +{} + +TRelation_application::~TRelation_application() +{ + if (_maskeys) delete _maskeys; +} + +void TRelation_application::setkey() +{ + if (has_filtered_cursor()) + { + TEdit_field* f = (TEdit_field*) get_search_field(); + TCursor* cur = f->browse()->cursor(); + cur->setkey(); + return; + } + file().setkey(1); +} + + +// what - meaning +// 0 - nop +// 1 - first +// 2 - last +// 3 - both +void TRelation_application::set_limits(byte what) +{ + if (has_filtered_cursor()) + { + TEdit_field* f = (TEdit_field*)get_search_field(); + CHECK(f, "Manca il campo di ricerca"); + + TBrowse* b = f->browse(); + TCursor* cur = b ? b->cursor() : NULL; + if (cur) + { + cur->setkey(); + f->browse()->do_input(TRUE); + if (cur->items() == 0) _first = _last = -1; + else + { + if (what & 0x1) + { + *cur = 0; + _first = cur->file().recno(); + } + if (what & 0x2) + { + *cur = cur->items() - 1; + _last = cur->file().recno(); + } + } + return; + } + } + + file().setkey(1); + if (what & 0x1) + { + if (file().empty()) _first = 1; + else + { + file().first(); + _first = file().recno(); + } + } + if (what & 0x2) + { + if (file().empty()) _last = 1; + else + { + file().last(); + _last = file().recno(); + } + } +} + +bool TRelation_application::create() +{ + TApplication::create(); + const bool ok = user_create(); + if (ok) + { + write_enable(); + _mask = get_mask(MODE_QUERY); + filter(); + _maskeys = new TKey_array(_mask); + set_limits(); + dispatch_e_menu(BAR_ITEM(1)); + } + return ok; +} + + +bool TRelation_application::menu(MENU_TAG m) +{ + if (m == BAR_ITEM(1)) + return main_loop(); + return TRUE; +} + + +bool TRelation_application::destroy() +{ + if (_maskeys) delete _maskeys; + user_destroy(); + return TApplication::destroy(); +} + + +void TRelation_application::set_fixed() +{ + TString256 s; + for (const char* f = _fixed.get(0); f && *f; f = _fixed.get()) + { + s = f; + const int u = s.find('='); + const int id = atoi(s.left(u)); + const char* val = s.mid(u+1); + if (*val) + _mask->set(id, val); + _mask->disable(id); + } +} + + +void TRelation_application::enable_query() +{ + const bool query = _mask->query_mode(); + const bool keyon = query || get_relation()->status() == _isreinsert; + + for (byte k = 1; k <= _maskeys->items(); k++) + { + const TChiave& chiave = _maskeys->key(k); + for (int i = 0; i < chiave.items(); i++) + { + const int num = chiave.pos(i); + TMask_field& c = _mask->fld(num); + if (c.enabled_default()) + { + if (k == 1) + c.enable(keyon); + if (c.has_query()) + ((TEdit_field&)c).enable_check(query); + } + } + } + + set_fixed(); +} + + +void TRelation_application::set_toolbar(bool all) +{ + const int mode = _mask->mode(); + int pos; + + if (all) + { + pos = _mask->id2pos(DLG_SAVEREC); + if (pos >= 0) _mask->fld(pos).enable(mode != MODE_QUERY); + pos = _mask->id2pos(DLG_DELREC); + if (pos >= 0) + { + bool enabdel = mode == MODE_MOD; + if (enabdel) + { + TRelation& r = *get_relation(); + const TRecnotype oldpos = r.lfile().recno(); + enabdel = !protected_record(r.curr()); + if (r.lfile().recno() != oldpos) + r.lfile().readat(oldpos); + } + _mask->fld(pos).enable(enabdel); + } + } + + enable_query(); +} + + +bool TRelation_application::save_and_new() const +{ return FALSE; } + +int TRelation_application::set_mode(int mode) +{ + static int _mode = NO_MODE; + if (mode < NO_MODE) mode = _mode; + + const int m = ((TMaskmode)mode == NO_MODE) ? (int) MODE_QUERY : mode; + _mask->set_mode(m); + + if (mode == _mode) + { + set_toolbar(FALSE); // Fast buttons update + } + else + { + set_toolbar(TRUE); // Full buttons update + _mode = mode; + } + + const char* t = ""; + switch(mode) + { + case MODE_QUERY: + t = "Ricerca"; break; + case MODE_MOD: + t = "Modifica"; break; + case NO_MODE: + t = "Ricerca/Inserimento"; break; + case MODE_INS: + t = "Inserimento"; break; + default: + break; + } + + xvt_statbar_set(t, TRUE); + + return _mode; +} + + +bool TRelation_application::autonum(TMask* m, bool rec) +{ + TToken_string k(get_next_key()); + + if (!rec && !m->query_mode()) + m->reset(); + _renum_message = ""; + + for (const char* n = k.get(0); n && *n; n = k.get()) + { + const short id = atoi(n); + CHECKD (id > 0, "Identificatore di autonumerazione errato: ", id); + const char* val = k.get(); + TMask_field& f = m->field(id); + if (rec || f.get().empty()) f.set(val); + if (rec) f.autosave(get_relation()); + if (_renum_message.empty() || f.in_key(1)) + _renum_message.format("Il documento e' stato registrato con :\n %s = %s", (const char *) f.prompt(), (const char *) f.get()); + } + return k.not_empty(); +} + + +void TRelation_application::query_mode(bool pre_ins) +{ + TMask* old = _mask; + const bool was_open = old != NULL && old->is_open(); + const bool changing = changing_mask(MODE_QUERY); + + if (changing && was_open) + old->close_modal(); + + _mask = get_mask(MODE_QUERY); + if (changing) + { + if (was_open) + _mask->open_modal(); + if (_maskeys) delete _maskeys; + _maskeys = new TKey_array(_mask); + set_limits(); + } + + _mask->reset(); + + if (pre_ins) + { + set_mode(NO_MODE); + init_query_insert_mode(*_mask); + } + else + { + set_mode(MODE_QUERY); + init_query_mode(*_mask); + } +} + + +void TRelation_application::insert_mode() +{ + if (_mask->query_mode()) + { + if (test_key(1, FALSE) == FALSE) + { + if (!autonum(_mask, FALSE)) + { + query_insert_mode(); + return; + } + } + + const bool changing = changing_mask(MODE_INS); + TFilename workname; workname.temp("msk"); + if (changing) + { + _mask->set_workfile(workname); + _mask->save(); + _mask->close_modal(); + } + _mask = get_mask(MODE_INS); + if (changing) + { + _mask->reset(); + _mask->set_workfile(workname); + _mask->load(); + ::remove(workname); + _mask->open_modal(); + delete _maskeys; + _maskeys = new TKey_array(_mask); + } + } + else + { + if (!autonum(_mask, FALSE)) + { + query_insert_mode(); + return; + } + } + + set_mode(MODE_INS); + + get_relation()->zero(); // Azzera tutta la relazione! + init_insert_mode(*_mask); +} + +bool TRelation_application::modify_mode() +{ + int err = get_relation()->read(_isequal, _testandlock); + if (err != NOERR) + { + if (err == _islocked) + message_box("I dati sono gia' in uso ad un altro programma"); + else + error_box("Impossibile leggere i dati: errore %d", err); + query_mode(); + return FALSE; + } + + const bool changing = changing_mask(MODE_MOD); + if (changing) + _mask->close_modal(); + + _mask = get_mask(MODE_MOD); + + if (changing) + { + _mask->open_modal(); + delete _maskeys; + _maskeys = new TKey_array(_mask); + } + + set_mode(MODE_MOD); + + err = read(*_mask); + if (err != NOERR) + { + query_mode(); + return FALSE; + } + + get_relation()->save_status(); + init_modify_mode(*_mask); + return TRUE; +} + + +TMask_field* TRelation_application::get_search_field() const +{ + if (_search_id > 0) + return &_mask->field(_search_id); + + const TChiave& k = _maskeys->key(1); + for (int i = 0; i < k.items(); i++) + { + TMask_field* f = &_mask->fld(k.pos(i)); + if (f->required()) return f; + } + return NULL; +} + +bool TRelation_application::search_mode() +{ + if (_mask->mode() != MODE_QUERY) + query_mode(); + + TMask_field* prima = get_search_field(); + while (prima) + { + if (prima->on_key(K_F9)) + { + if (find(1)) + return modify_mode(); + } + + TMask_field* dopo = &_mask->focus_field(); + prima = (dopo == prima) ? NULL : dopo; + } + return FALSE; +} + + +bool TRelation_application::test_key(byte k, bool err) +{ + const TChiave& chiave = _maskeys->key(k); + bool onereq = FALSE, onefill = FALSE; + + for (int i = 0; i < chiave.items(); i++) + { + const int num = chiave.pos(i); + TMask_field& c = _mask->fld(num); + + if (c.required()) + { + onereq = TRUE; + if (c.get().empty()) + { + if (err) + { + _mask->first_focus(-c.dlg()); + error_box("Manca un valore indispensabile per la ricerca"); + } + return FALSE; + } + } + else + /* if (k == 1 && !onereq && !onefill && c.get().not_empty()) */ + if (!onereq && !onefill && c.is_edit() && c.get().not_empty()) + onefill = TRUE; + } + if (k == 1 && !onereq && !onefill) + { + if (err) + error_box("Manca un valore indispensabile per la ricerca"); + return FALSE; + } + return onefill || onereq; +} + +// Guy: doesn't change fields +bool TRelation_application::find(byte k) +{ + if (changing_keys()) + { + delete _maskeys; + _maskeys= new TKey_array(_mask); + } + + const byte numkeys = _maskeys->items(); + + if (k == 0) + { + for (k = 1; k <= numkeys && !test_key(k, FALSE); k++); + if (k > numkeys) + return test_key(1, TRUE); + } + + file().setkey(k); + file().zero(); + const TChiave& chiave = _maskeys->key(k); + for (int i = 0; i < chiave.items(); i++) + { + const TMask_field& c = _mask->fld(chiave.pos(i)); + if (c.shown()) // Ignora campi invisibili + c.autosave(get_relation()); + } + + const int err = file().read(_isequal); + return err == NOERR; +} + + +bool TRelation_application::save(bool check_dirty) +{ + static bool was_dirty = FALSE; + + int err = NOERR; + const int mode = _mask->mode(); + + if (check_dirty) + { + const int dirty = _mask->dirty(); + + const char* ms = (mode == MODE_MOD) ? "le modifiche" : "i dati inseriti"; + + if (mode == MODE_QUERY) + { + const bool cont = !dirty || yesno_box("Annullare %s?", ms); + return cont; + } + + if (!dirty && !was_dirty) + { + if (mode == MODE_MOD) + { + get_relation()->restore_status(); + get_relation()->lfile().reread(_unlock); // Unlock main file + } + return TRUE; + } + + const KEY last = _mask->last_key(); + const bool annulla = last == K_ESC || last == K_QUIT || last == K_F9; + const bool errore = dirty && _mask->field(dirty).dirty() > TRUE; + + KEY k; + if (errore) + { + if (annulla) + { + TString80 w(_mask->field(dirty).warning()); + if (w.empty()) w = "Campo inconsistente"; + w << ": si desidera "; + switch (last) + { + case K_ESC: + w << "annullare?"; break; + case K_QUIT: + w << "uscire?"; break; + default: + w << "continuare?"; break; + } + k = yesno_box(w) ? K_NO : K_ESC; + if (k == K_ESC) + _mask->first_focus(-dirty); + } + else k = K_ESC; + } + else + k = yesnocancel_box("Registrare %s?", ms); + + if (k == K_ESC || k == K_NO) + { + if (mode == MODE_MOD) + { + get_relation()->restore_status(); + get_relation()->lfile().reread(_unlock); // Unlock main file + } + was_dirty = FALSE; + return k == K_NO; + } + + if (annulla) + { + if (!_mask->check_fields()) // Exit with ESC didn't check values + { + _mask->first_focus(-_mask->focus_field().dlg()); + was_dirty = TRUE; + return FALSE; + } + } + } + was_dirty = FALSE; + + begin_wait(); + if (mode == MODE_INS) + { + bool changed = TRUE; + bool changed_key = FALSE; + + while (changed) + { + err = write(*_mask); + if (err == _isreinsert) + { + changed = autonum(_mask, TRUE); + if (!changed) + { + _mask->disable_starting_check(); + enable_query(); // Abilita chiave 1 per rinumerazione manuale + } + else + changed_key = TRUE; + } + else + changed = FALSE; + } + if (err == NOERR) + { + if (changed_key) + message_box(_renum_message); + get_relation()->save_status(); + set_limits(); + get_relation()->restore_status(); + } + } + else + { + get_relation()->restore_status(); + err = rewrite(*_mask); + } + end_wait(); + + switch(err) + { + case NOERR: + _recins = get_relation()->lfile().recno(); + break; + case _isreinsert: + warning_box("Esiste gia' un documento con la stessa chiave"); + break; + default: + error_box("Impossibile registrare i dati: errore %d", err); + break; + } + return err == NOERR; +} + + +int TRelation_application::read(TMask& m) +{ + const TRelation *r = get_relation(); + m.autoload(r); + return NOERR; +} + + +int TRelation_application::write(const TMask& m) +{ + TRelation *r = get_relation(); + m.autosave(r); + r->write(); + return r->status(); +} + + +int TRelation_application::rewrite(const TMask& m) +{ + TRelation *r = get_relation(); + m.autosave(r); + r->rewrite(); + return r->status(); +} + + +bool TRelation_application::relation_remove() +{ + CHECK(_mask->mode() == MODE_MOD, "You can call remove in MODE_MOD only"); + TRelation *r = get_relation(); + + r->restore_status(); + + if (protected_record(r->curr())) + return message_box("Registrazione non eliminabile"); + + if (yesno_box("Confermare l'eliminazione")) + { + r->restore_status(); + const bool ok = remove(); + if (ok) + set_limits(); + else + return error_box("Errore di cancellazione %d", r->status()); + } + return TRUE; +} + + +bool TRelation_application::remove() +{ + const int err = get_relation()->remove(); + return err == NOERR; +} + +bool TRelation_application::firm_change_enabled() const +{ + bool ok = TApplication::firm_change_enabled(); + if (ok) ok = _mask == NULL || _mask->query_mode(); + return ok; +} + +bool TRelation_application::main_loop() +{ + _recins = -1; + + query_mode(); + _mask->open_modal(); + + KEY k; + + // Provoca l'autopremimento per il messaggio di LINK + if (_lnflag) _mask->send_key(K_AUTO_ENTER, 0); + + do + { + const bool change = firm_change_enabled(); + // Dis/abilita cambio ditta + enable_menu_item(M_FILE_NEW, change); + // Dis/abilita cambio parametri + enable_menu_item(M_FILE_REVERT, change); + + k = _mask->run(); + + switch (k) + { + case K_ESC: + if (save(TRUE)) + query_mode(); + if (_lnflag) + k = K_QUIT; + break; + case K_QUIT: + if (!save(TRUE)) + k = K_ENTER; + break; + case K_ENTER: + if (find(0)) modify_mode(); + else insert_mode(); + break; + case K_SAVE: + if (save(FALSE)) + { + if (_autoins_caller.not_empty()) + { + k = K_QUIT; + } + else + { + if (save_and_new()) + { + if (_mask->insert_mode()) + insert_mode(); + else + query_mode(); + } + else + modify_mode(); + } + } + break; + case K_INS: + if (_mask->query_mode() || save(TRUE)) + insert_mode(); + break; + case K_DEL: + if (relation_remove()) + query_mode(); + if (_autoins_caller.not_empty()) + { + if (_lnflag) _recins = 0; + k = K_QUIT; + } + break; + case K_F9: + if (save(TRUE)) + search_mode(); + break; + default: + if (save(TRUE)) + { + setkey(); + int err = ~NOERR; + switch (k) + { + case K_HOME: + err = file().readat(_first, _testandlock); + break; + case K_NEXT: + err = file().reread(); + err = file().next(_testandlock); + break; + case K_PREV: + err = file().reread(); + err = file().prev(_testandlock); + break; + case K_END: + err = file().readat(_last, _testandlock); + break; + default: + break; + } + if (err == NOERR || err == _islocked) modify_mode(); + else query_mode(); + } + break; + } + } while (k != K_QUIT); + + if (_mask->is_open()) + _mask->close_modal(); + + _mask->set_mode(NO_MODE); + + if (autoins_caller().not_empty() && _recins >= 0) + { + TMessage msg(autoins_caller(), _lnflag ? MSG_LN : MSG_AI, format("%ld", _recins)); + msg.send(); + } + + return k != K_QUIT; +} + +bool TRelation_application::filter() +{ + TMailbox mail; + TMessage* msg = mail.next_s(MSG_FS); + + if (msg) + { + _mask = get_mask(MODE_MOD); + TToken_string body = msg->body(); + + short id = body.get_int(); + while (id > 0) + { + _search_id = id; + TEdit_field& f = (TEdit_field&)_mask->field(id); + TCursor* cur = f.browse()->cursor(); + TRectype& rec = cur->curr(); + rec.zero(); + + TString80 t; + const char* s; + while((s = body.get()) != NULL) + { + t = s; + const int u = t.find('='); + if (u < 0) + { + id = atoi(t); + break; + } + _fixed.add(t); + const short fid = atoi(t.left(u)); + const TFieldref* campo = _mask->field(fid).field(); + if (campo != NULL) + campo->write(t.mid(u+1), rec); + } + cur->setfilter(""); + cur->setregion(rec, rec); + if (s == NULL) id = 0; + } + } + + mail.restart(); + msg = mail.next_s(MSG_AI); + if (msg) _autoins_caller = msg->from(); + + mail.restart(); + msg = mail.next_s(MSG_LN); + if (msg) + { + TToken_string body(msg->body()); + const int key = body.get_int(); + + _autoins_caller = msg->from(); + _lnflag = TRUE; + + const char* v = body.get(); + TString80 s; + for (int i = 0; v != NULL && i < _mask->fields(); i++) + { + TMask_field& f = _mask->fld(i); + + if (f.active() && f.dlg() > 0 && f.in_key(key)) + { + s = v; + _fixed.add(format("%d=%s", f.dlg(), (const char*)s)); + v = body.get(); + } + } + } + + return TRUE; +} + +void TRelation_application::set_link(TMask & m, const char * keyexpr) + +{ + CHECK(keyexpr != NULL, "Invalid expression"); + TToken_string body(keyexpr); + const int key = body.get_int(); + + _lnflag = TRUE; + + const char* v = body.get(); + + const int max = m.fields(); + for (int i = 0; i < max && v != NULL; i++) + { + TMask_field& f = m.fld(i); + + if (f.active() && f.dlg() > 0 && f.in_key(key)) + { + const TString s(v); + _fixed.add(format("%d=%s", f.dlg(), (const char*) s)); + v = body.get(); + } + } +} + + diff --git a/include/strings.h b/include/strings.h index ac218d78c..c3cbfb5d1 100755 --- a/include/strings.h +++ b/include/strings.h @@ -110,6 +110,15 @@ public: // @cmember Ritorna l'oggetto TString composto dai count caratteri da destra const TString& right(int count) const; + // @cmember Ritorna un oggetto TString temporaneo composto dai count caratteri da sinistra + TString sleft(int count) const { return ((TString)left(count)); } + // @cmember Ritorna un oggetto TString temporaneo composto dai count caratteri a partire da from + TString smid(int from, int count = -1) const { return ((TString)mid(from, count)); } + // @cmember Ritorna un oggetto TString temporaneo composto dai caratteri da from a to (escluso) + TString ssub(int from, int to = -1) const { return ((TString)sub(from, to)); } + // @cmember Ritorna un oggetto TString temporaneo composto dai count caratteri da destra + TString sright(int count) const { return ((TString)right(count)); } + // @cmember Riempe la stringa con n caratteri c TString& fill(char c, int n = -1); // @cmember Riempe la stringa con n caratteri spazio (chiama )