From efeee74b795f187b1fedc4fb05d0355c6360a8f7 Mon Sep 17 00:00:00 2001 From: bonazzi Date: Fri, 21 Apr 2017 01:33:36 +0000 Subject: [PATCH] rimosso commit errato git-svn-id: svn://10.65.10.50/branches/R_10_00@23752 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- src/include/alex.cpp | 5 - src/include/applicat.cpp | 10 +- src/include/applicat.h | 431 ++-- src/include/causali.h | 2 - src/include/dongle.h | 2 +- src/include/filebar.h | 4 +- src/include/fraction.cpp | 5 - src/include/isam.cpp | 6 +- src/include/lffiles.h | 3 - src/include/navbar.h | 2 - src/include/postman.cpp | 5 - src/include/prefix.cpp | 6 +- src/include/printapp.cpp | 18 +- src/include/rdoc.h | 5 - src/include/real.cpp | 419 +++- src/include/real.h | 192 +- src/include/recset.cpp | 6 +- src/include/relapbar.h | 4 +- src/include/relapp.cpp | 4403 +++++++++++++++++++------------------- src/include/textset.h | 3 - src/include/tokens.h | 3 - src/include/uml.h | 2 - src/include/urldefid.h | 2 +- src/include/xml.cpp | 4 - 24 files changed, 2982 insertions(+), 2560 deletions(-) diff --git a/src/include/alex.cpp b/src/include/alex.cpp index 37dd01e0f..12cdfa7c9 100755 --- a/src/include/alex.cpp +++ b/src/include/alex.cpp @@ -1170,12 +1170,7 @@ bool TAlex_virtual_machine::execute(const TBytecode& bc) bool TAlex_virtual_machine::compile(const char* cmd, TBytecode& bc) { -#ifdef LINUX - string s(cmd); - istringstream instr(s); -#else istrstream instr((const char*)cmd, strlen(cmd)); -#endif return compile(instr, bc); } diff --git a/src/include/applicat.cpp b/src/include/applicat.cpp index 51074267e..10a56da3b 100755 --- a/src/include/applicat.cpp +++ b/src/include/applicat.cpp @@ -296,11 +296,12 @@ void TApplication::stop_run() { if (_savefirm) prefix().set_codditta(_savefirm); - terminate(); + terminate(); xvt_app_destroy(); } + bool TApplication::add_menu(TString_array& menu, MENU_TAG id) { TTemp_window tw(TASK_WIN); @@ -315,10 +316,11 @@ bool TApplication::remove_menu(MENU_TAG id) TApplication::TApplication() - : _god_vars(NULL),_savefirm(0), _running(false), _create_ok(false), _force(false) + : _god_vars(NULL),_savefirm(0), _running(FALSE), _create_ok(FALSE) { } + TApplication::~TApplication() { if (_god_vars != NULL) @@ -339,8 +341,7 @@ void TApplication::terminate() if (_create_ok) destroy(); // Distruzione files e maschere - if(!_force) - do_events(); + do_events(); if (use_files()) { @@ -583,7 +584,6 @@ void TApplication::run( set_xvt_hooks(); _running = TRUE; - message_box("a"); xvt_app_create(argc, argv, 0L, task_eh, &cfg); } diff --git a/src/include/applicat.h b/src/include/applicat.h index 21afb9d6e..f2a0695f2 100755 --- a/src/include/applicat.h +++ b/src/include/applicat.h @@ -1,219 +1,214 @@ -#pragma once -#ifndef __APPLICATION_H -#define __APPLICATION_H - -#ifndef __DICTION_H -#include -#endif - -#ifndef __CONFIG_H -#include -#endif - -#define MSG_AI "AI" // message auto_insert (relapp) -#define MSG_FS "FS" // message filtered start (relapp) -#define MSG_LN "LN" // message link (printapp -> relapp) -#define MSG_ED "ED" // message edit (maskfld -> relapp) -#define CHK_ALL -1 // all authorization checks -#define CHK_DONGLE 0 // dongle authorization checks -//#define CHK_USER 1 // user authorization checks - -// @doc EXTERNAL - -// @class TApplication | Classe per la gestione di tutte le applicazioni PRASSI -class TApplication - -// @author:(INTERNAL) Guido - -// @access:(INTERNAL) Private Member -{ -// // @cmember:(INTERNAL) Identificatore del menu' legato all'applicazione -// int _bar; - // @cmember:(INTERNAL) Numero di argomenti passati all'applicazione - int _argc_; - // @cmember:(INTERNAL) Array di argomenti passati all'applicazione - const char** _argv_; - // @cmember:(INTERNAL) Ora di inizio utilizzo del programma (per versioni DEMO) - time_t _start_time; - // @cmember:(INTERNAL) Array di autorizzazione concessa all'utente - TBit_array _user_aut; - // @cmember:(INTERNAL) Array di valori dei modi speciali - TAssoc_array * _god_vars; - - // @cmember:(INTERNAL) Codice dell'applicazione - TString _name; - // @cmember:(INTERNAL) Nome della applicazione - TString _title; - // @cmember:(INTERNAL) Nome del modulo principale applicazione - TString _module_name; - // @cmember:(INTERNAL) Elenco dei files - TArray _used_files; - - // @cmember:(INTERNAL) Codice della ditta - long _savefirm; - // @cmember:(INTERNAL) Chiusura forzata per programmi senza interfaccia - bool _force; - - - // @cmember:(INTERNAL) Indica se l'applicazione e' partita - bool _running; - // @cmember:(INTERNAL) Indica se l'applicazione e' stata creata con successo - bool _create_ok; - - // @cmember:(INTERNAL) Termine dell'applicazione - void terminate(); - -// @access Protected Member -protected: - // @cmember Ritorna il nome del modulo dell'applicazione - const char* get_module_name() const; - // @cmember Event handler della finestra principale del programma - static long task_eh(WINDOW win, EVENT* ep); - - // @cmember Handler degli eventi della finestra principale, chiamato da - virtual long handler(WINDOW win, EVENT* ep); - // @cmember Estende il dialog box della set_firm - virtual bool extended_firm() const - { return false; } - // @cmember Indica se si intendono usare i files DBF - virtual bool use_files() const - { return true; } - - // @cmember Inizilizzazzioni di bassissimo livello - virtual bool pre_create() - { return true; } - // @cmember Crea la finestra principale - virtual bool create(); - // @cmember Controlla il menu' - virtual bool menu(MENU_TAG) - { return true; } - // @cmember Rimuove l'applicazione - virtual bool destroy(); - - // @cmember Chiamata ogni volta che l'utente usa il menu Cambia Parametri - virtual void on_config_change(); - // @cmember Chiamata ogni volta che l'utente cambia ditta - virtual void on_firm_change(); - - virtual bool test_assistance_year(bool verbose) const; - - // @cmember Setta i permessi di utilizzo dei moduli - void set_perms(); - - // @cmember apre i files necessari - void open_files(int logicnum, ...); - - // @cmember Percorso documenti archiviati - bool get_spotlite_path(TFilename& path) const; - - // @access Public Member -public: - // @cmember Fa partire l'applicazione - void run(int argc, char* argv[], const char* name); - - // @cmember Ritorna l'identificatore della classe - virtual word class_id() const - { return CLASS_APPLICATION; } - - // @cmember Controlla se il programa e' partito - bool is_running() const { return _running; } - // @cmember Controlla se si tratta di una applicazione valida - virtual bool ok() const - { return _create_ok; } - // @cmember Risposta alla selezione Stampa del menu File - virtual void print(); - virtual void preview(); - - virtual bool get_next_pdf(int anno, long ditta, const char* codnum, long numdoc, long codcf, TFilename& pdf) const; - virtual bool get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, - TString& subj, TString& text, TToken_string& attach, short& flags) const; - - // @cmember Controlla se al programma corrente e' concesso cambiare ditta da menu. - virtual bool firm_change_enabled() const; - // @cmember Ritorna la con la lista dei moduli cui appartiene il programma - virtual const char * extra_modules() const { return ""; } - // @cmember Abilita la verifica del modulo cui appartiene il programma - virtual bool check_autorization() const; - virtual void on_idle(); - - // @cmember Forza la chiusura dell'applicazione - void stop_run(); - void TApplication::force_stop() {_force = true;} - - - // @cmember Mette il segno Check a fianco di una voce di menu - void check_menu_item(MENU_TAG item, bool on = true); - // @cmember Toglie il segno Check a fianco di una voce di menu - void uncheck_menu_item(MENU_TAG item); - // @cmember Permette di abilitare/disabilitare una voce di menu' - void enable_menu_item(MENU_TAG item, bool on = true); - // @cmember Permette di disabilitare una voce di menu' (chiama ) - void disable_menu_item(MENU_TAG item) - { enable_menu_item(item, false); } - // @cmember Simula la selezione di una voce di menu - void dispatch_e_menu(MENU_TAG item); - - // @cmember Ritorna il nome dell'applicazione - const TString& name() const - { return _name; } - // @cmember Ritorna l'array di parametri da passare all'applicazione - const char** argv() const - { return _argv_; } - // @cmember Ritroan il parametro

-esimo da passare all'applicazione - const char* argv(int i) const { return _argv_[i]; } - // @cmember Ritorna il numero di paramentri da passare all'applicazione - int argc() const - { return _argc_; } - - // @cmember Setta il titolo da assegnare all'applicazione - void set_title(const char* t); - - // @cmember Ritorna il titolo da assegnare all'applicazione - const TString& title() const - { return _title; } - - // @cmember static void | check_parameters | int & argc, char *argv[] | - // Legge il parametro /uUTENTE e lo toglie dalla lista - static void check_parameters(int& argc, char *argv[]); - - // @cmember Ritorna i numeri della versione del programma - static bool get_version_info(int& year, int& release, int& tag, int& patch); - static int get_version(); - - // @cmember Controlla se il modulo

ha l'autorizzazione all'esecuzione - bool has_module(int module, int checktype = CHK_ALL) const; - // @cmember Setta la ditta corrente (Ritorna se ce l'ha fatta) - bool set_firm(long cod = -1); - // @cmember Ritorna la ditta corrente - long get_firm() const; - // @cmember Ritorna la directory in cui si trovano i dati della ditta corrente - const char* get_firm_dir() const; - - // @cmember Interfaccia runtime del menu' della finestra principale??? - bool add_menu(TString_array& menu, MENU_TAG id = 0); - // @cmember Elimina il menu'

(Ritorna se ce l'ha fatta???) - bool remove_menu(MENU_TAG id); - - // @cmember Costruttore - TApplication(); - // @cmember Distruttore - virtual ~TApplication(); -}; - -class TSkeleton_application : public TApplication -{ -protected: - virtual bool create(); - virtual bool menu(MENU_TAG); - -protected: - virtual void main_loop() pure; - -public: - TSkeleton_application() { } - virtual ~TSkeleton_application() { } -}; - -TApplication& main_app(); - +#pragma once +#ifndef __APPLICATION_H +#define __APPLICATION_H + +#ifndef __DICTION_H +#include +#endif + +#ifndef __CONFIG_H +#include +#endif + +#define MSG_AI "AI" // message auto_insert (relapp) +#define MSG_FS "FS" // message filtered start (relapp) +#define MSG_LN "LN" // message link (printapp -> relapp) +#define MSG_ED "ED" // message edit (maskfld -> relapp) +#define CHK_ALL -1 // all authorization checks +#define CHK_DONGLE 0 // dongle authorization checks +//#define CHK_USER 1 // user authorization checks + +// @doc EXTERNAL + +// @class TApplication | Classe per la gestione di tutte le applicazioni PRASSI +class TApplication + +// @author:(INTERNAL) Guido + +// @access:(INTERNAL) Private Member +{ +// // @cmember:(INTERNAL) Identificatore del menu' legato all'applicazione +// int _bar; + // @cmember:(INTERNAL) Numero di argomenti passati all'applicazione + int _argc_; + // @cmember:(INTERNAL) Array di argomenti passati all'applicazione + const char** _argv_; + // @cmember:(INTERNAL) Ora di inizio utilizzo del programma (per versioni DEMO) + time_t _start_time; + // @cmember:(INTERNAL) Array di autorizzazione concessa all'utente + TBit_array _user_aut; + // @cmember:(INTERNAL) Array di valori dei modi speciali + TAssoc_array * _god_vars; + + // @cmember:(INTERNAL) Codice dell'applicazione + TString _name; + // @cmember:(INTERNAL) Nome della applicazione + TString _title; + // @cmember:(INTERNAL) Nome del modulo principale applicazione + TString _module_name; + // @cmember:(INTERNAL) Elenco dei files + TArray _used_files; + + // @cmember:(INTERNAL) Codice della ditta + long _savefirm; + + // @cmember:(INTERNAL) Indica se l'applicazione e' partita + bool _running; + // @cmember:(INTERNAL) Indica se l'applicazione e' stata creata con successo + bool _create_ok; + + // @cmember:(INTERNAL) Termine dell'applicazione + void terminate(); + +// @access Protected Member +protected: + // @cmember Ritorna il nome del modulo dell'applicazione + const char* get_module_name() const; + // @cmember Event handler della finestra principale del programma + static long task_eh(WINDOW win, EVENT* ep); + + // @cmember Handler degli eventi della finestra principale, chiamato da + virtual long handler(WINDOW win, EVENT* ep); + // @cmember Estende il dialog box della set_firm + virtual bool extended_firm() const + { return false; } + // @cmember Indica se si intendono usare i files DBF + virtual bool use_files() const + { return true; } + + // @cmember Inizilizzazzioni di bassissimo livello + virtual bool pre_create() + { return true; } + // @cmember Crea la finestra principale + virtual bool create(); + // @cmember Controlla il menu' + virtual bool menu(MENU_TAG) + { return true; } + // @cmember Rimuove l'applicazione + virtual bool destroy(); + + // @cmember Chiamata ogni volta che l'utente usa il menu Cambia Parametri + virtual void on_config_change(); + // @cmember Chiamata ogni volta che l'utente cambia ditta + virtual void on_firm_change(); + + virtual bool test_assistance_year(bool verbose) const; + + // @cmember Setta i permessi di utilizzo dei moduli + void set_perms(); + + // @cmember apre i files necessari + void open_files(int logicnum, ...); + + // @cmember Percorso documenti archiviati + bool get_spotlite_path(TFilename& path) const; + + // @access Public Member +public: + // @cmember Fa partire l'applicazione + void run(int argc, char* argv[], const char* name); + + // @cmember Ritorna l'identificatore della classe + virtual word class_id() const + { return CLASS_APPLICATION; } + + // @cmember Controlla se il programa e' partito + bool is_running() const { return _running; } + // @cmember Controlla se si tratta di una applicazione valida + virtual bool ok() const + { return _create_ok; } + // @cmember Risposta alla selezione Stampa del menu File + virtual void print(); + virtual void preview(); + + virtual bool get_next_pdf(int anno, long ditta, const char* codnum, long numdoc, long codcf, TFilename& pdf) const; + virtual bool get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, + TString& subj, TString& text, TToken_string& attach, short& flags) const; + + // @cmember Controlla se al programma corrente e' concesso cambiare ditta da menu. + virtual bool firm_change_enabled() const; + // @cmember Ritorna la con la lista dei moduli cui appartiene il programma + virtual const char * extra_modules() const { return ""; } + // @cmember Abilita la verifica del modulo cui appartiene il programma + virtual bool check_autorization() const; + virtual void on_idle(); + + // @cmember Forza la chiusura dell'applicazione + void stop_run(); + + // @cmember Mette il segno Check a fianco di una voce di menu + void check_menu_item(MENU_TAG item, bool on = true); + // @cmember Toglie il segno Check a fianco di una voce di menu + void uncheck_menu_item(MENU_TAG item); + // @cmember Permette di abilitare/disabilitare una voce di menu' + void enable_menu_item(MENU_TAG item, bool on = true); + // @cmember Permette di disabilitare una voce di menu' (chiama ) + void disable_menu_item(MENU_TAG item) + { enable_menu_item(item, false); } + // @cmember Simula la selezione di una voce di menu + void dispatch_e_menu(MENU_TAG item); + + // @cmember Ritorna il nome dell'applicazione + const TString& name() const + { return _name; } + // @cmember Ritorna l'array di parametri da passare all'applicazione + const char** argv() const + { return _argv_; } + // @cmember Ritroan il parametro

-esimo da passare all'applicazione + const char* argv(int i) const { return _argv_[i]; } + // @cmember Ritorna il numero di paramentri da passare all'applicazione + int argc() const + { return _argc_; } + + // @cmember Setta il titolo da assegnare all'applicazione + void set_title(const char* t); + + // @cmember Ritorna il titolo da assegnare all'applicazione + const TString& title() const + { return _title; } + + // @cmember static void | check_parameters | int & argc, char *argv[] | + // Legge il parametro /uUTENTE e lo toglie dalla lista + static void check_parameters(int& argc, char *argv[]); + + // @cmember Ritorna i numeri della versione del programma + static bool get_version_info(int& year, int& release, int& tag, int& patch); + static int get_version(); + + // @cmember Controlla se il modulo

ha l'autorizzazione all'esecuzione + bool has_module(int module, int checktype = CHK_ALL) const; + // @cmember Setta la ditta corrente (Ritorna se ce l'ha fatta) + bool set_firm(long cod = -1); + // @cmember Ritorna la ditta corrente + long get_firm() const; + // @cmember Ritorna la directory in cui si trovano i dati della ditta corrente + const char* get_firm_dir() const; + + // @cmember Interfaccia runtime del menu' della finestra principale??? + bool add_menu(TString_array& menu, MENU_TAG id = 0); + // @cmember Elimina il menu'

(Ritorna se ce l'ha fatta???) + bool remove_menu(MENU_TAG id); + + // @cmember Costruttore + TApplication(); + // @cmember Distruttore + virtual ~TApplication(); +}; + +class TSkeleton_application : public TApplication +{ +protected: + virtual bool create(); + virtual bool menu(MENU_TAG); + +protected: + virtual void main_loop() pure; + +public: + TSkeleton_application() { } + virtual ~TSkeleton_application() { } +}; + +TApplication& main_app(); + #endif /* __APPLICATION_H */ \ No newline at end of file diff --git a/src/include/causali.h b/src/include/causali.h index 3f2acea0f..02b857a97 100755 --- a/src/include/causali.h +++ b/src/include/causali.h @@ -29,7 +29,5 @@ #define CAU_CODCAUREG "CODCAUREG" #define CAU_REGSPIVA "REGSPIVA" #define CAU_MOVCGIND "MOVCGIND" -#define CAU_RILFTEMRI "RILFTEMRI" -#define CAU_DATAREGPR "DATAREGPR" #endif \ No newline at end of file diff --git a/src/include/dongle.h b/src/include/dongle.h index d78f3cec5..87fba2205 100755 --- a/src/include/dongle.h +++ b/src/include/dongle.h @@ -17,7 +17,7 @@ #include #endif -enum TDongleHardware { _dongle_unknown, _dongle_hardlock, _dongle_eutron, _dongle_network, _dongle_ssa, _dongle_ssanet,_dongle_software }; +enum TDongleHardware { _dongle_unknown=0, _dongle_network=3, _dongle_ssa=4, _dongle_ssanet=5 }; enum TDongleType { _no_dongle, _user_dongle, _developer_dongle }; class TDongle : public TObject diff --git a/src/include/filebar.h b/src/include/filebar.h index 89ca6b760..4a118bceb 100755 --- a/src/include/filebar.h +++ b/src/include/filebar.h @@ -25,6 +25,4 @@ BEGIN PICTURE 0 END -#include - -// leave a newline at the end +#include \ No newline at end of file diff --git a/src/include/fraction.cpp b/src/include/fraction.cpp index 716502841..2a11a7ce6 100755 --- a/src/include/fraction.cpp +++ b/src/include/fraction.cpp @@ -122,11 +122,7 @@ void fraction::build_fraction (const char *s) } } n.strip(",.-+/[]"); -#ifdef WIN32 sscanf_s(n, "%I64d", &_num); -#else - sscanf_s(n, "%Ld", &_num); -#endif if (len_periodo > 0) { _den = 9; @@ -178,7 +174,6 @@ fraction::fraction(const real& num, const real& den) } } - int fraction::sign() const { if (_num == 0 || _den == 0) diff --git a/src/include/isam.cpp b/src/include/isam.cpp index d18ce552b..270163727 100755 --- a/src/include/isam.cpp +++ b/src/include/isam.cpp @@ -985,7 +985,7 @@ int TBaseisamfile::_rewrite(const TRectype& rec) // Forza l'uso della chiave principale (per chiavi duplicate?) const int fhnd = handle(1); - while ((_lasterr = cisread(fhnd, 1, save_rec, _isequal + _testandlock, _recno)) == _islocked) ;// Si Posiziona e locca per sicurezza... + _lasterr = cisread(fhnd, 1, save_rec, _isequal + _nolock, _recno); // Si Posiziona per sicurezza... if (_lasterr == NOERR) { @@ -1276,7 +1276,11 @@ int TBaseisamfile::is_valid(bool exclusive) { const int dbfreclen = DB_reclen(fhnd); if (dbfreclen != trcreclen) + { err = _istrcerr; + if (_logicnum == LF_CLIFO) + error_box("Clifo trc=%d dbf=%d", trcreclen, dbfreclen); + } } } else diff --git a/src/include/lffiles.h b/src/include/lffiles.h index 68ebe58cf..7b15d32a0 100755 --- a/src/include/lffiles.h +++ b/src/include/lffiles.h @@ -198,6 +198,3 @@ #define CNF_DITTA CNF_GENERAL + 2 #endif // __LFFILES_H - -// leave a newline at the end - diff --git a/src/include/navbar.h b/src/include/navbar.h index 819e30e8e..3bbf8af78 100755 --- a/src/include/navbar.h +++ b/src/include/navbar.h @@ -32,5 +32,3 @@ BEGIN MESSAGE EXIT,K_END PICTURE TOOL_LASTREC END - -// leave a newline at the end diff --git a/src/include/postman.cpp b/src/include/postman.cpp index 8d33b6960..7d811ae3d 100755 --- a/src/include/postman.cpp +++ b/src/include/postman.cpp @@ -368,12 +368,7 @@ bool TPostman::dispatch_transaction(const TRectype& rec, TSocketClient socket; char * buf = new char[1024 * 256]; -#ifdef WIN32 ostrstream stream(buf, 1024 * 256); -#else - ostringstream stream(buf); -#endif - bool ok = true; item.SetTag("m:CampoTransaction"); diff --git a/src/include/prefix.cpp b/src/include/prefix.cpp index c04352c69..b7485fc5f 100755 --- a/src/include/prefix.cpp +++ b/src/include/prefix.cpp @@ -495,7 +495,7 @@ const TFilename& TFile_info::load_filedes() { _dir = _filedes.SysName[0] != '$' ? _comdir : _nordir; _name = CAddPref(_filedes.SysName); - strncpy_s(_filedes.Des, dictionary_translate(_filedes.Des), sizeof(_filedes.Des)-1); + strncpy(_filedes.Des, dictionary_translate(_filedes.Des), sizeof(_filedes.Des)-1); } else _name.cut(0); @@ -534,7 +534,7 @@ TFile_info::TFile_info(int logicnum, TFilename& name) int err = DB_recinfo(_name, &_filedes, (RecDes*)&rec.rec(), keys.get_buffer()); if (err == NOERR && prefix().add_recdes(logicnum, rec, keys)) { - strncpy_s(_filedes.SysName, _name, sizeof(_filedes.SysName)); + strncpy(_filedes.SysName, _name, sizeof(_filedes.SysName)); _filedes.SysName[41] = '\0'; } else @@ -1036,7 +1036,7 @@ void TPrefix::set( { const TString saved_prf = __ptprf; // Salvo __ptprf che viene cambiato da CGetPref char* prfx = (char*)CGetPref(); // Safe non const cast for StPath cprefix - strcpy_s(__ptprf, saved_prf); + strcpy(__ptprf, saved_prf); xvt_fsys_build_pathname(prfx, NULL, __ptprf, _prefix, NULL, NULL); } else diff --git a/src/include/printapp.cpp b/src/include/printapp.cpp index cece39952..88d8e9697 100755 --- a/src/include/printapp.cpp +++ b/src/include/printapp.cpp @@ -891,7 +891,11 @@ void TPrint_application::set_row ( if (ch == 't' || ch == 'a') formato << 's'; else if (ch == 'r') +#ifdef __LONGDOUBLE__ + formato << "Lf"; +#else formato << 't'; +#endif else formato << ch; if (ccc == '%') @@ -950,7 +954,13 @@ void TPrint_application::set_row ( q = rrr.string(_picture); } else + { +#ifdef __LONGDOUBLE__ + q.format(formato, (long double)rrr); +#else q = rrr.format(formato); +#endif + } if (rrr.is_zero () && !_print_zero) q.fill (' ', q.len()); } @@ -1471,7 +1481,13 @@ bool TPrint_application::print_one ( ps = rrr.string(_picture); } else - ps = rrr.format(fff); + { +#ifdef __LONGDOUBLE__ + ps.format(fff, (long double)rrr); +#else + ps = rrr.format(fff); +#endif + } if (rrr.is_zero () && !_print_zero) ps.fill (' ', ps.len()); } diff --git a/src/include/rdoc.h b/src/include/rdoc.h index 32b02ea05..2db5aff9c 100755 --- a/src/include/rdoc.h +++ b/src/include/rdoc.h @@ -47,11 +47,6 @@ #define RDOC_MOVMAG "MOVMAG" #define RDOC_CODMAGC "CODMAGC" #define RDOC_DATACONS "DATACONS" -#define RDOC_QTAGG1 "QTAGG1" -#define RDOC_QTAGG2 "QTAGG2" -#define RDOC_QTAGG3 "QTAGG3" -#define RDOC_QTAGG4 "QTAGG4" -#define RDOC_QTAGG5 "QTAGG5" #define RDOC_IMPIANTO "IMPIANTO" #define RDOC_LINEA "LINEA" #define RDOC_IDRIGA "IDRIGA" diff --git a/src/include/real.cpp b/src/include/real.cpp index 3adc26289..b254f534b 100755 --- a/src/include/real.cpp +++ b/src/include/real.cpp @@ -3,40 +3,381 @@ #include const real ZERO(0.0); -const real PUNTO_UNO(UNO/DIECI); -const real PUNTO_DUE(DUE/DIECI); -const real PUNTO_TRE(TRE/DIECI); -const real PUNTO_QUATTRO(DUE/CINQUE); -const real MEZZO(UNO/DUE); -const real PUNTO_SEI(TRE/CINQUE); -const real PUNTO_SETTE(SETTE/DIECI); -const real PUNTO_OTTO(QUATTRO/CINQUE); -const real PUNTO_NOVE(NOVE/DIECI); const real UNO(1.0); const real DUE(2.0); const real TRE(3.0); -const real QUATTRO(4.0); -const real CINQUE(5.0); -const real SEI(6.0); -const real SETTE(7.0); -const real OTTO(8.0); -const real NOVE(9.0); -const real DIECI(10.0); -const real UNDICI(11.0); -const real DODICI(12.0); -const real TREDICI(13.0); -const real QUATTORDICI(14.0); -const real QUINDICI(15.0); -const real SEDICI(16.0); -const real DICIASSETTE(17.0); -const real DICIOTTO(18.0); -const real DICIANNOVE(19.0); -const real VENTI(20.0); -const real VENTUNO(21.0); -const real VENTIDUE(22.0); -const real CINQUANTA(50.0); const real CENTO(100.0); +#ifdef __LONGDOUBLE__ + +#include + +#ifdef WIN32 + +#include +inline long double _atold(const char* str) +{ + long double num = 0.0; + sscanf(str, "%Lf", &num); + return num; +} + +#endif + +real::real () : _dec(0.0) +{ } + +real::real (const real& b) : _dec(b._dec) +{ } + +real::real (long double a) : _dec(a) +{ } + +void real::set_int64(__int64 b) +{ + _dec = (long double)b; +} + +bool real::is_real (const char *s) +{ + if (s && *s) + { + const long double n = _atold(s); + if (n == 0.0) + { + for(; *s; s++) + { + if (strchr("0. ", *s) == NULL) + return false; + } + } + } + return true; +} + +real::real (const char *s) +{ + _dec = (s && *s) ? _atold(s) : 0.0; +} + +real& real::operator = (const real& b) +{ + _dec = b._dec; + return *this; +} + +real& real::operator = (long double b) +{ + _dec = b; + return *this; +} + +real& real::operator += (long double b) +{ + _dec += b; + return *this; +} + +real& real::operator -= (long double b) +{ + _dec -= b; + return *this; +} + +real& real::operator *= (long double b) +{ + _dec *= b; + return *this; +} + +real& real::operator /= (long double b) +{ + CHECK(b != 0.0, "Division by zero"); + _dec /= b; + return *this; +} + + +// @doc EXTERNAL + +// @mfunc Ritorna il segno del reale +// +// @rdesc Ritorna i seguenti valori: +// +// @flag 0 | Se il numero e' minore di 0 +// @flag = 0 | Se il numero e' uguale a 0 +// @flag 0 | Se il numero e' maggiore di 0 +int real::sign () const +{ + const int s = _dec > 0.0 ? +1 : (_dec < 0.0 ? -1 : 0); + return s; +} + +real real::operator - () const +{ + real n(-_dec); + return n; +} + +long real::integer () const +{ + return (long)floorl(_dec); +} + +// Certified 91% +// @doc EXTERNAL + +// @mfunc Trasforma un reale in stringa +// +// @rdesc Ritorna la stringa nella lunghezza richiesta +const char *real::string ( + int len, // @parm Lunghezza della stringa (compreso decimali) + int dec, // @parm Numero di decimali (default UNDEFINED) + char pad) const // @parm Carattere di riempimento (default ' ') + // @parm char * | picture | Formato della stringa + + // @syntax string (int len, int dec, char pad); + // @syntax string (const char *picture); + // + // @comm Nel primo caso ritorna una stringa lunga

con

decimali e + // inserisce nella stringa stessa il carattere

nel caso la + // lunghezza richiesta sia maggiore di quella che risulterebbe per la + // completa rappresentazione del reale. + // Nel secondo caso ritorna la stringa con il formato stabilito in + //

. + +{ + TString16 fmt("%"); + if (pad != ' ') fmt << '0'; + if (len != 0) fmt << len; + if (dec != UNDEFINED) fmt << '.' << dec; + fmt << "Lf"; + + TString& tmp = get_tmp_string(); + char* __string = tmp.get_buffer(len); + + sprintf(__string, fmt, _dec); + + if (len == 0 && dec == UNDEFINED && strchr(__string, '.') != NULL) + { + int cut = strlen (__string); + for (int i = cut-1; i >= 0; i--) + { + if (__string[i] == '0') + cut--; + else + { + if(__string[i] == '.') + cut--; + break; + } + } + __string[cut] = '\0'; + } + return __string; +} + +// Childish algorithm faster and more accurate than powl(10.0, pow) +HIDDEN void ipow10(int pow, double& m, double& d) +{ + m = d = 1.0; + if (pow > 0) + { + for (int i = pow; i > 0; i--) + { + m *= 10.0; + d *= 0.1; + } + } + else + { + for (int i = pow; i < 0; i++) + { + m *= 0.1; + d *= 10.0; + } + } +} + +int real::precision() const +{ + const TFixed_string s(string()); + const int d = s.find('.'); + const int p = d < 0 ? 0 : (s.len()-d-1); + return p; +} + + +// @doc EXTERNAL + +// @mfunc real& | real | round | Arrotonda al numero di decimali passati +real& real::round ( + int prec) // @parm Numero di decimali a cui arrotondare il numero (default 0) + + // @comm Nel caso

sia: + // + // @flag 0 | Arrotonda al decimale + // @flag = 0 | Arrotonda all'intero + // @flag 0 | Arrotonda al valore passato (es. -3 arrotonda alle mille) +{ + if (abs(prec) < 20) + { + double m, d; + if (prec != 0) + { + ipow10(prec, m, d); + if (prec < 0) + _dec /= d; + else + _dec *= m; + } + + if (_dec >= 0.0) + _dec = floorl(_dec + 0.5); + else + _dec = ceill(_dec - 0.5); + + if (prec != 0) + { + if (prec < 0) + _dec *= d; + else + _dec /= m; + } + } + return *this; +} + +real& real::ceil (int prec) +{ + double m, d; + if (prec != 0) + { + ipow10(prec, m, d); + _dec *= m; + } + _dec = ceill(_dec); + if (prec != 0) +// _dec *= d; Risulta stranamente molto impreciso! + _dec /= m; + + return *this; +} + +real& real::floor (int prec) +{ + double m, d; + if (prec != 0) + { + ipow10(prec, m, d); + _dec *= m; + } + _dec = floorl(_dec); + if (prec != 0) +// _dec *= d; Risulta stranamente molto impreciso! + _dec /= m; + + return *this; +} + +real& real::trunc(int prec) +{ + double m, d; + if (prec != 0) + { + ipow10(prec, m, d); + _dec *= m; + } + _dec = floorl(_dec); + if (prec != 0) +// _dec *= d; Risulta stranamente molto impreciso! + _dec /= m; + return *this; +} + + +// @doc EXTERNAL + +// @func Scambia il numero reale

con il numero real

+void swap ( + real& a, // @parm Primo numero da scambiare + real& b) // @parm Secondo numero da scambiare + +{ + const real n = a; + a = b; + b = n; +} + +long double operator%(const real& a, const real& b) +{ + const long double times = floorl(a / b); + const long double resto = (double)a - (double)b * times; + return resto; +} + +long double sqr(long double a) +{ + return a*a; +} + +long double exp10(long double a) +{ + return powl(10.0, a); +} + +#if _MSC_VER < 1300 + +long double sqrt(long double a) +{ + return sqrtl(a); +} + +long double pow(long double a, long double b) +{ + return powl(a, b); +} + +long double exp(long double a) +{ + return expl(a); +} + +long double log10(long double a) +{ + return log10l(a); +} + +long double log(long double a) +{ + return logl(a); +} + +long double sin(long double a) +{ + return sinl(a); +} + +long double cos(long double a) +{ + return cosl(a); +} + +long double tan(long double a) +{ + return tanl(a); +} + +long double abs(long double a) +{ + return fabsl(a); +} + +#endif + + +#else + #include //#include //#include @@ -913,6 +1254,8 @@ const char* real::format(const char *picture) const return (const char *) f; } +#endif + // Funzioni comuni dei due real TObject* real::dup () const @@ -1168,15 +1511,6 @@ HIDDEN int get_picture_decimals (const TString& picture, char& decsep) return decimali; } -long double real::ld() const -{ - TString20 str = string(); - long double num; - - sscanf(str, "%Lf", &num); - return num; -} - const char* real::string(const char *picture) const { if (*picture == '\0') @@ -1534,3 +1868,12 @@ int TImporto::compare(const TSortable& s) const const int res = d.sign(); return res; } + +bool TImporto::is_zero() const +{ +#ifdef __LONGDOUBLE__ + return fabsl(_valore) < 0.00001; +#else + return _valore.is_zero(); +#endif +} diff --git a/src/include/real.h b/src/include/real.h index b0ee3dbb8..43d170063 100755 --- a/src/include/real.h +++ b/src/include/real.h @@ -12,40 +12,168 @@ class real; extern const real ZERO; -extern const real PUNTO_UNO; -extern const real PUNTO_DUE; -extern const real PUNTO_TRE; -extern const real PUNTO_QUATTRO; -extern const real MEZZO; -extern const real PUNTO_SEI; -extern const real PUNTO_SETTE; -extern const real PUNTO_OTTO; -extern const real PUNTO_NOVE; extern const real UNO; extern const real DUE; extern const real TRE; -extern const real QUATTRO; -extern const real CINQUE; -extern const real SEI; -extern const real SETTE; -extern const real OTTO; -extern const real NOVE; -extern const real DIECI; -extern const real UNDICI; -extern const real DODICI; -extern const real TREDICI; -extern const real QUATTORDICI; -extern const real QUINDICI; -extern const real SEDICI; -extern const real DICIASSETTE; -extern const real DICIOTTO; -extern const real DICIANNOVE; -extern const real VENTI; -extern const real VENTUNO; -extern const real VENTIDUE; -extern const real CINQUANTA; extern const real CENTO; +#ifdef __LONGDOUBLE__ + +// @doc EXTERNAL + +// @class real | Classe per la gestione dei numeri reali +// +// @base public | TObject +class real : public TObject + +// @comm Questa classe utilizza i long double definiti per Visual C++. Esiste un'altra classe +// real: per accedere scegliere il tasto successivo () dalla barra dei bottoni + +// @author:(INTERNAL) Guido +{ + // @access:(INTERNAL) Private Member + + // @cmember:(INTERNAL) Numero reale + long double _dec; + + // @access Protected Member +protected: + // @cmember Permette di stampare l'oggetto + virtual void print_on(ostream& out) const; + + // @cmember Duplica il numero reale (vedi classe ) + virtual TObject* dup() const; + // @cmember Traduce in lettere il numero reale + const char* literals() const; + // @cmember Inserisce i punti separatori delle migliaia e riempe i decimali + // alla lunghezza passata (es: 3.000,20) + const char* points(int decimals = 0) const; + + // @access Public Member +public: + // @cmember long double | operator long double | | Ritorna il numero reale + operator long double () const + { return _dec; } + + // @cmember Trasforma un numero dal formato inglese (decimali con punto) in + // formato italiano (decimali con virgola) + static const char* eng2ita(char* s); + // @cmember Trasforma un numero dal formato italiano (decimali con virgola) in + // formato inglese (decimali con punto) + static const char* ita2eng(const char* s); + // @cmember Controlla se si tratta di un numero reale (TRUE se vero) + static bool is_real(const char* n); + // @cmember Controlla se si tratta di un numero naturale (TRUE se vero) + static bool is_natural(const char* n); + // @cmember Controlla se si tratta di uno zero (TRUE se vero) + static bool is_null(const char* n); + // @cmember Trasforma un reale in stringa + const char* string(int len = 0, int dec = UNDEFINED, char pad = ' ') const; + // @cmember Trasforma un reale in stringa (chiama ), + // ma ritorna il formato italiano + const char* stringa(int len = 0, int dec = UNDEFINED, char pad = ' ') const; + // @cmember Trasforma un reale in stringa (chiama ), + // ma ritorna il formato atteso da Excel + const char* stringe(int len = 0, int dec = UNDEFINED, char pad = ' ') const; + // @cmember Ritorna la stringa con il formato passato + const char* string(const char* picture) const; + // @cmember Ritorna la stringa con il formato passato + const char* format(const char *picture) const; + + // @cmember Ritorna la precisione del reale (numero di decimali) + int precision() const; + // @cmember Controlla se si tratta di un reale uguale a 0 + bool is_zero() const { return _dec == ZERO; } + // @cmember Controlla se si tratta di un reale diverso da 0 + bool not_zero() const { return !is_zero();} + // @cmember Ritorna il segno del reale + int sign() const; + // @cmember Trasforma il reale in intero (operator int era troppo pericoloso) + long integer() const; + + // @cmember Arrotonda al numero di decimali passati + real& round(int prec = 0) ; + // @cmember Tronca al numero di decimali passati (default 0) + real& trunc(int prec = 0) ; + // @cmember Arrotonda al numero successivo (della precisione passata) + real& ceil(int prec = 0); + // @cmember Arrotonda al numero precedente (della precisione passata) + real& floor(int prec = 0); + // @cmember Assegna un reale + real& operator = (const real& a); + // @cmember Assegna un reale + real& operator =(long double a); + // @cmember Assegna un __int64 ad un reale + void set_int64(__int64 b); + // @cmember Aggiunge ad un reale il valore passato (passato per indirizzo) + real& operator +=(long double a); + // @cmember Sottrae ad un reale il valore passato (passato per indirizzo) + real& operator -=(long double b); + // @cmember Moltiplica un reale per il valore passato (passato per indirizzo) + real& operator *=(long double b); + // @cmember Divide un reale per il valore passato (passato per indirizzo) + real& operator /=(long double b); + // @cmember Ritorna la negazione di un reale (TRUE se 0, altrimenti FALSE) + bool operator !() const + { return _dec == ZERO; } + // @cmember Ritorna il risultato della differenza tra due reali + real operator -() const; + + // @cmember Costruttore + real(); + // @cmember Costruttore + real(const real& b); + // @cmember Costruttore + real(long double a); + // @cmember Costruttore + real(const char* s); + // @cmember Distruttore + virtual ~real() + {} +}; + +inline long double fnc_min(long double a, long double b){ return a < b ? a : b; } +inline long double fnc_max(long double a, long double b) { return a > b ? a : b; } + +inline bool operator <(const real& a, const real& b) {return (double)a < (double)b;} +inline bool operator <(double a, const real& b) {return a < (double)b;} +inline bool operator >(const real& a, const real& b) {return (double)a > (double)b;} +inline bool operator >(double a, const real& b) {return a > (double)b;} +inline bool operator <=(const real& a, const real& b) {return (double)a <= (double)b;} +inline bool operator <=(double a, const real& b) {return a <= (double)b;} +inline bool operator >=(const real& a, const real& b) {return (double)a >= (double)b;} +inline bool operator >=(double a, const real& b) {return a >= (double)b;} +inline bool operator ==(const real& a, const real& b) {return (double)a == (double)b;} +inline bool operator ==(double a, const real& b) {return a == (double)b;} +inline bool operator !=(const real& a, const real& b) {return (double)a != (double)b;} +inline bool operator !=(double a, const real& b) {return a != (double)b;} + +inline real operator +(const real& a, const real& b) {return (double)a + (double)b;} +inline real operator -(const real& a, const real& b) {return (double)a - (double)b;} +inline real operator *(const real& a, const real& b) {return (double)a * (double)b;} +inline real operator /(const real& a, const real& b) {return (double)a / (double)b;} + +long double operator%(const real& a, const real& b); +void swap(real& a, real& b) ; +long double sqr(long double) ; +long double exp10(long double) ; + +#if _MSC_VER < 1300 +long double sqrt(long double) ; +long double pow(long double, long double) ; +long double exp(long double a) ; +long double log10(long double a) ; +long double log(long double a) ; +long double sin(long double a) ; +long double cos(long double a) ; +long double tan(long double a) ; +long double abs(long double a) ; +#else +#include +#endif + +#else + #ifndef INCSTR_H #include #endif @@ -108,8 +236,6 @@ public: // @cmember Ritorna l'indirizzo del numero reale DEC* ptr() const { return (DEC*)&_dec; } - // @cmember Ritorna il numero reale convetito in long double - long double ld() const; // @cmember Trasforma un reale in stringa const char* string(int len = 0, int dec = UNDEFINED, char pad = ' ') const; // @cmember Trasforma un reale in stringa (chiama ), ma @@ -233,6 +359,8 @@ real cos(const real& a) ; real tan(const real& a) ; real abs(const real& a) ; +#endif + class TDistrib : public TObject // @author:(INTERNAL) Villa @@ -387,7 +515,7 @@ public: { return _valore; } // @cmember Controlla se l'importo e' 0 (in qualsiasi sezione, TRUE se 0) - bool is_zero() const { return _valore.is_zero(); } + bool is_zero() const; // @cmember Assegna l'importo passato const TImporto& operator=(const TImporto& i) diff --git a/src/include/recset.cpp b/src/include/recset.cpp index d356180eb..14788ee40 100755 --- a/src/include/recset.cpp +++ b/src/include/recset.cpp @@ -1558,12 +1558,8 @@ TCursor* TISAM_recordset::cursor() const TParagraph_string msg(use, 64); TPerformance_profiler prof(msg.get(0)); TISAM_recordset* my = (TISAM_recordset*)this; -#ifdef LINUX - string s(use.get_buffer()); - istringstream instr(s); -#else + istrstream instr(use.get_buffer(), use.len()+1); //"barata" x aggiungere il carattere finale -#endif TCursor_parser parser(instr, my->_column); my->_relation = parser.get_relation(); diff --git a/src/include/relapbar.h b/src/include/relapbar.h index 866fa3d37..ea5271cf7 100755 --- a/src/include/relapbar.h +++ b/src/include/relapbar.h @@ -1,4 +1,2 @@ #include -#include - -// leave a newline at the end +#include \ No newline at end of file diff --git a/src/include/relapp.cpp b/src/include/relapp.cpp index a67e99ddf..5fda52117 100755 --- a/src/include/relapp.cpp +++ b/src/include/relapp.cpp @@ -1,2210 +1,2193 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/////////////////////////////////////////////////////////// -// TRelation_application -/////////////////////////////////////////////////////////// - -TRelation_application::TRelation_application() - : _mask(NULL), _search_id(-1), _lnflag(0), - _autodelete(0), _navigating(false), - _locked(false) -{ } - -TRelation_application::~TRelation_application() -{ } - -bool TRelation_application::has_filtered_cursor() const -{ - bool yes = filtered(); - if (yes) - { - const TEdit_field& f = get_search_field(); - yes = f.browse() != NULL; - } - return yes; -} - - -TCursor * TRelation_application::get_filtered_cursor() const -{ - if (has_filtered_cursor()) - { - const TEdit_field& f = get_search_field(); - - return f.browse()->cursor(); - } - else - return NULL; -} - -void TRelation_application::setkey() -{ - if (has_filtered_cursor()) - get_filtered_cursor()->setkey(); - else - file().setkey(1); -} - -void TRelation_application::set_key_filter() -{ - TString rf = get_user_read_filter(); rf.trim(); - if (rf.not_empty()) - { - TString expr; - for (int f = _mask->fields()-1; f >= 0; f--) - { - TMask_field& fld= _mask->fld(f); - if (fld.is_edit() && fld.in_key(0)) - { - TBrowse* b = ((TEdit_field&)fld).browse(); - if (b && b->cursor()->relation()->lfile().num() == get_relation()->lfile().num()) - { - expr = b->get_filter(); - if (expr.find(rf) < 0) - { - if (expr.not_empty()) - { - expr.insert("(", 0); - expr << ")&&(" << rf << ')'; - } - else - expr = rf; - b->set_filter(expr); - } - } - } - } - } -} - - -// @doc INTERNAL - -// @mfunc Setta i limiti -void TRelation_application::set_limits( - byte what) // @parm tipo di limite da assegnare al record - -// @comm I limiti possibili sono: -// @flag 0 | Nessuna operazione -// @flag 1 | Primo record -// @flag 2 | Ultimo record -// @flag 3 | Entrambi -{ - if (has_filtered_cursor()) - { - const TEdit_field& f = get_search_field(); - if (f.browse() != NULL) - f.browse()->do_input(true); - - TCursor* cur = get_filtered_cursor(); - cur->setkey(); - if (cur->items() > 0) - { - TBaseisamfile& f = cur->file(); - if (what & 0x1) - { - *cur = 0; - _first = f.recno(); - } - if (what & 0x2) - { - *cur = cur->items() - 1; - _last = f.recno(); - } - } - else - _first = _last = -1; - } - else - { - setkey(); - TBaseisamfile& f = file(); - if (!f.empty()) - { - if (what & 0x1) - { - if (f.first() == NOERR) - _first = f.recno(); - } - if (what & 0x2) - { - if (f.last() == NOERR) - _last = f.recno(); - } - } - else - _first = _last = -1; - } -} - -void TRelation_application::set_find_button() -{ - // Ricalcola posizioni bootoni di navigazione con la vecchia toolbar - WINDOW bar = _mask->toolbar(); - if (bar != NULL_WIN) - xvt_toolbar_realize(_mask->toolbar()); - else // Non c'e' la nuova relapbar - { - int pos = _mask->id2pos(DLG_FINDREC); - if (pos >= 0 && _mask->id2pos(DLG_FIRSTREC) >= 0) //se e' un bottone pentapartito... - { - TButton_field& f_find = (TButton_field &)_mask->fld(pos); - RCT rct_base; f_find.get_rect(rct_base); - const int bwidth = (rct_base.right - rct_base.left); - const int bheight = (rct_base.bottom - rct_base.top); - if (bwidth > 3*bheight/2) // Controllo se ho gia' ridimensionato i bottoni in precedenza - { - int bx = bwidth / 3; - int by = bheight / 2; - - RCT r = rct_base; - r.left += bx; r.right -= bx; - if (!NATIVE_CONTROLS) - { - r.left -= 2; r.right += 2; - } - f_find.set_rect(r); // Ridimensiona il bottone centrale di ricerca - - if (!NATIVE_CONTROLS) - { - bx += 5; by += 3; // Aggiusta dimensioni bottoni sussidiari - } - - pos = _mask->id2pos(DLG_FIRSTREC); - if (pos >= 0) - { - r = rct_base; r.top = r.bottom - by; r.right = r.left + bx; - _mask->fld(pos).set_rect(r); - } - pos = _mask->id2pos(DLG_PREVREC); - if (pos >= 0) - { - r = rct_base; r.bottom = r.top + by; r.right = r.left + bx; - _mask->fld(pos).set_rect(r); - } - pos = _mask->id2pos(DLG_NEXTREC); - if (pos >= 0) - { - r = rct_base; r.bottom = r.top + by; r.left = r.right - bx; - _mask->fld(pos).set_rect(r); - } - pos = _mask->id2pos(DLG_LASTREC); - if (pos >= 0) - { - r = rct_base; r.top = r.bottom - by; r.left = r.right - bx; - _mask->fld(pos).set_rect(r); - } - } - } - } -} - -bool TRelation_application::create() -{ - bool ok = user_create(); - if (ok) - { - write_enable(); - _mask = get_mask(MODE_QUERY); - - filter(); - set_key_filter(); - set_limits(); - } - return ok ? TSkeleton_application::create() : ok; -} - - -bool TRelation_application::destroy() -{ - user_destroy(); - return TSkeleton_application::destroy(); -} - - -void TRelation_application::set_fixed() -{ - TToken_string s(256, '='); - FOR_EACH_TOKEN(_fixed, f) - { - s = f; - const short id = s.get_int(0); - if (id > 0 && _mask->id2pos(id) >= 0) - { - s = s.get(); - if (s.not_empty()) - _mask->set(id, s); - - if (_lnflag < 2) - _mask->disable(id); - } - } -} - -void TRelation_application::enable_query() -{ - const bool query = _mask->query_mode(); - const bool keyon = query || get_relation()->status() == _isreinsert; - - for (int i = _mask->fields() - 1; i >= 0; i--) - { - TMask_field& c = _mask->fld(i); - - if (c.in_key(0) && c.enabled_default()) - { - if (c.in_key(1)) - c.enable(keyon); - if (c.is_edit()) - { - TEdit_field& e = (TEdit_field&)c; - if (e.browse() != NULL) - e.enable_check(query); - } - } - } - - set_fixed(); -} - -bool TRelation_application::can_I_write(const TRelation* rel) const -{ return !_locked && user_can_write(rel); } - -bool TRelation_application::can_I_read(const TRelation* rel) const -{ return user_can_read(rel); } - -void TRelation_application::set_toolbar() -{ - const int mode = _mask->mode(); - const bool can_edit_some = can_I_write(NULL); - const bool can_nav = _lnflag == 0 && _curr_transaction != TRANSACTION_LINK; - - bool enabsave = can_edit_some; - int pos = _mask->id2pos(DLG_SAVEREC); - if (pos >= 0) - { - enabsave = can_edit_some && (mode != MODE_QUERY) && can_I_write(get_relation()); - _mask->fld(pos).enable(enabsave); - } - pos = _mask->id2pos(DLG_DELREC); - if (pos >= 0) - { - bool enabdel = can_edit_some && (mode == MODE_QUERY || mode == MODE_MOD); - if (enabdel && mode == MODE_MOD) - { - TRelation& r = *get_relation(); - const TRecnotype oldpos = r.lfile().recno(); - enabdel = enabsave && !protected_record(r) && user_can_delete(&r); - if (r.lfile().recno() != oldpos) - r.lfile().readat(oldpos); - } - _mask->fld(pos).enable(enabdel); - } - - pos = _mask->id2pos(DLG_FINDREC); - if (pos >= 0) - { - _mask->fld(pos).enable(_lnflag == 0); - - const long recno = get_relation()->lfile().recno(); - const bool enable_next_prev = _mask->edit_mode(); - - pos = _mask->id2pos(DLG_FIRSTREC); - if (pos >= 0) - _mask->fld(pos).enable(can_nav && (enable_next_prev ? _first != recno : _first > 0)); - pos = _mask->id2pos(DLG_PREVREC); - if (pos >= 0) - _mask->fld(pos).enable(can_nav && enable_next_prev && _first > 0 && _first != recno); - pos = _mask->id2pos(DLG_NEXTREC); - if (pos >= 0) - _mask->fld(pos).enable(can_nav && enable_next_prev && _last > 0 && _last != recno); - pos = _mask->id2pos(DLG_LASTREC); - if (pos >= 0) - _mask->fld(pos).enable(can_nav && (enable_next_prev ? _last != recno : _last > 0)); - } - - pos = _mask->id2pos(DLG_NEWREC); - if (pos >= 0) - { - bool enabins = (mode == MODE_QUERY || _lnflag == 0) && can_edit_some; - _mask->fld(pos).enable(enabins); - } - - set_find_button(); - enable_query(); -} - -void TRelation_application::update_navigation_bar() -{ - if (_mask->query_mode()) - { - set_limits(); - set_toolbar(); - } -} - -bool TRelation_application::save_and_new() const -{ return false; } - -bool TRelation_application::save_and_quit() const -{ - return (_autoins_caller.full() || _curr_transaction.not_empty()) && _curr_trans_mode != TM_REMAIN; -} - -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); - - set_toolbar(); - _mode = mode; - - const char* t = ""; - switch(mode) - { - case MODE_QUERY: - t = TR("Ricerca"); break; - case MODE_MOD: - t = TR("Modifica"); break; - case NO_MODE: - t = TR("Ricerca/Inserimento"); break; - case MODE_INS: - t = TR("Inserimento"); break; - default: - break; - } - - xvtil_statbar_set(t, TRUE); - - return _mode; -} - -// @doc INTERNAL - -// @mfunc Permette di autonumerare un record -// -// @rdesc Ritorna se e' riuscito a creare una nuova autonumerazione: -// -// @flag TRUE | La chiave non e' vuota -// @flag FALSE | Non e' riuscito ad autonumerare il documento -bool TRelation_application::autonum( - TMask* m, // @parm Maschera a cui applicare l'autonumerazione - bool rec) // @parm Indica se registrare la chiave anche sul record corrente -{ - TToken_string k; - if (!get_next_key(k)) - { - k = get_next_key(); -#ifdef DBG - if (k.full()) - xvt_dm_popup_warning("'const char* get_next_key()' is deprecated: implement 'bool get_next_key(TToken_string&)'"); -#endif - } - - if (!rec && !m->query_mode()) - m->reset(); - _renum_message = ""; - - for (const char* n = k.get(0); n && *n; n = k.get()) - { - TMask_field* fld = NULL; - if (isdigit(*n)) - fld = m->find_by_id(atoi(n)); - else - fld = m->find_by_fieldname(n); - if (fld == NULL) - { - NFCHECK("Identificatore di autonumerazione errato"); - return false; - } - const char* val = k.get(); - TMask_field& f = *fld; - if (rec || f.empty()) - f.set(val); - if (rec) - ((TEditable_field&)f).autosave(*get_relation()); - if (_renum_message.empty() || f.in_key(1)) - _renum_message.format(FR("L'elemento è stato registrato con:\n %s = %s"), - (const char*)f.prompt(), (const char*)f.get()); - } - return k.full(); -} - -// @doc EXTERNAL - -// @mfunc Entra in modo di ricerca -void TRelation_application::query_mode( - bool pre_ins) // @parm Indica in quale modo andare: - // - // @flag TRUE | Entra in modo MODE_QUERY_INSERT - // @flag FALSE | Entra in modo MODE_QUERY (default) -{ - 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(); - set_limits(); - } - - _mask->set_mode(pre_ins ? MODE_QUERYINS : MODE_QUERY); - _mask->reset(); - _mask->disable_page(1); // Nasconde pagine inutili - - if (pre_ins) - { - set_mode(NO_MODE); - init_query_insert_mode(*_mask); - enable_query(); - } - else - { - set_mode(MODE_QUERY); - init_query_mode(*_mask); - enable_query(); - - // Aggiorna bottoni di ricerca: utile soprattutto per ve0 che imposta CODNUM - if (has_filtered_cursor()) - { - set_limits(); - set_toolbar(); - } - } -} - - -void TRelation_application::insert_mode() -{ - bool try_auto = true; - - if (_mask->query_mode()) - try_auto = !test_key(1, FALSE); - - if (try_auto && !autonum(_mask, FALSE)) - { - query_insert_mode(); - return; - } - - TRelation* r = get_relation(); - r->zero(); - _mask->autosave(*r); - - if (!can_I_write(r)) - { - warning_box(FR("L'utente %s non puo' inserire %s"), (const char*)user(), r->file().description()); - 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(); - xvt_fsys_remove_file(workname); - _mask->open_modal(); - } - else - _mask->enable_page(1); - - set_mode(MODE_INS); - r->zero(); // Azzera tutta la relazione! - - _mask->load_defaults(); - init_insert_mode(*_mask); - - // ....possibilmente spostare questa chiamata ..... - if (is_transaction() && _curr_transaction == TRANSACTION_INSERT) - ini2insert_mask(); -} - -bool TRelation_application::modify_mode() -{ - TRelation* rel = get_relation(); - const TReclock block = can_I_write(rel) ? _testandlock : _nolock; - int err = rel->read(_isequal, block); - - if (!can_I_read(rel)) - { - warning_box(TR("I dati non sono accessibili per l'utente %s"), (const char*)user()); - query_mode(); - return FALSE; - } - _locked = false; - if (err != NOERR) - { - if (err == _islocked) - { - _locked = true; - message_box(TR("I dati sono già usati da un altro programma, scrittura disabilitata")); - } - else - { - error_box(FR("Impossibile leggere i dati: errore %d"), err); - if (!is_transaction()) - 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(); - else - _mask->enable_page(1); - - set_mode(MODE_MOD); - - err = read(*_mask); - if (err != NOERR) - { - query_mode(); - return FALSE; - } - - rel->save_status(); - init_modify_mode(*_mask); - - // ....possibilmente spostare questa chiamata ..... - // Forse deve essere fatta prima della init_modify_mode()! - if (_curr_transaction == TRANSACTION_MODIFY) - ini2insert_mask(); - return TRUE; -} - - -TEdit_field& TRelation_application::get_search_field() const -{ - short id = _search_id; - - if (id <= 0 || !_mask->field(id).shown()) - { - for (int i = _mask->fields()-1; i >= 0; i--) - { - const TMask_field& f = _mask->fld(i); - if (f.is_edit() && f.in_key(1) && f.shown()) - { - id = f.dlg(); - break; - } - } - } - - return _mask->efield(id); -} - -bool TRelation_application::search_mode() -{ - if (_mask->mode() != MODE_QUERY) - query_mode(); - - TEdit_field* prima = &get_search_field(); - while (prima) - { - if (prima->on_key(K_F9)) - { - if (find(1)) - return modify_mode(); - else - break; - } - - TMask_field* dopo = &_mask->focus_field(); - if (dopo != prima && dopo->is_edit() && dopo->in_key(0)) - prima = (TEdit_field*)dopo; - else - break; - } - return false; -} - -HIDDEN bool delete_handler(TMask_field& f, KEY k) -{ - if (k == K_TAB && f.focusdirty() && !f.empty()) - { - TMask& m = f.mask(); - const bool finale = *f.prompt() == 'A'; - const int pos = m.id2pos(f.dlg()); - if (pos >= 3) - { - const TMask_field& e = m.fld(pos - 3); - if (e.is_edit() && e.get().blank()) - { - const short id = e.dlg() - (finale ? 200 : 100); - const TRelation_application& app = (TRelation_application&)main_app(); - const TMask_field& orig = app.curr_mask().field(id); - bool req = orig.required(); - if (!req && orig.is_edit()) - { - const TEdit_field& e = (TEdit_field&)orig; - req = e.validate_func() == 12; - } - if (req) - { - TString str; str << (finale ? TR("A ") : TR("Da ")) << orig.prompt(); - return f.error_box(FR("Specificare anche il valore %s"), (const char*)str); - } - } - } - if (finale && !f.get().blank()) - { - const TMask_field& p = m.fld(pos - 1); - TString80 prec = p.get(); - TString80 curr = f.get(); - bool ok; - switch (p.class_id()) - { - case CLASS_REAL_FIELD: ok = real(prec) <= real(curr); break; - case CLASS_DATE_FIELD: ok = TDate(prec) <= TDate(curr); break; - default : ok = prec <= curr; break; - } - if (!ok) - return f.error_box(FR("Inserire un valore non inferiore a '%s'"), (const char*)prec); - } - } - return TRUE; -} - -int TRelation_application::delete_mode() -{ - TEdit_field& fld = get_search_field(); - TBrowse* brw = fld.browse(); - if (brw) - { - brw->do_input(TRUE); - TCursor& cur = *brw->cursor(); - - TToken_string head(brw->head()); - head.insert("@1|", 0); - TToken_string items(brw->items()); - items.insert(" |", 0); - - int tab1 = 0, tab2 = 0, y = 0; - // Nuovo modo basato sugli input - TToken_string inplist = brw->get_input_fields(); - if (inplist.not_empty()) - { - FOR_EACH_TOKEN(inplist, tok) - { - if (*tok != '"' && strchr(tok, '@') == NULL) - { - TMask_field& e = _mask->field(short(atoi(tok))); - if (e.active()) - { - const int len = strlen(e.prompt()); - if (len > tab1) tab1 = len; - const int size = e.size(); - if (size > tab2) tab2 = size; - y++; - } - } - } - } - tab1 += 5; - tab2 += tab1+2; - - cur = 0L; - TCursor_sheet sht(&cur, items, TR("Eliminazione"), head, 0x4, y); - - y = -1; // Posizione del campo precedente - TString prompt; // Prompt del campo corrente - const short delta = 100; - - FOR_EACH_TOKEN(inplist, tok) - { - if (*tok != '"' && strchr(tok, '@') == NULL) - { - TMask_field& e = _mask->field(short(atoi(tok))); - if (!e.active()) - continue; - - const short id = e.dlg()+delta; - prompt = "Da "; prompt << e.prompt(); - sht.add_static(DLG_NULL, 0, prompt, 1, ++y); - TString16 flags; - if (e.automagic()) flags << 'A'; - if (e.roman()) flags << 'M'; - if (e.right_justified()) flags << 'R'; - if (e.uppercase()) flags << 'U'; - if (e.zerofilled()) flags << 'Z'; - switch (e.class_id()) - { - case CLASS_DATE_FIELD: - { - TDate_field& d1 = sht.add_date(id, 0, "", tab1, y, flags); - TDate_field& d2 = sht.add_date(id+delta, 0, "A ", tab2, y, flags); - d1.set_handler(delete_handler); - d2.set_handler(delete_handler); - } - break; - case CLASS_REAL_FIELD: - { - TReal_field& r1 = sht.add_number(id, 0, "", tab1, y, e.size(), flags); - TReal_field& r2 = sht.add_number(id+delta, 0, "A ", tab2, y, e.size(), flags); - r1.set_handler(delete_handler); - r2.set_handler(delete_handler); - } - break; - default: - { - TEdit_field& e1 = sht.add_string(id, 0, "", tab1, y, e.size(), flags); - TEdit_field& e2 = sht.add_string(id+delta, 0, "A ", tab2, y, e.size(), flags); - e1.set_handler(delete_handler); - e2.set_handler(delete_handler); - } - break; - } - if (y == 0) - sht.first_focus(id); - } - } - - sht.open_modal(); - - KEY tasto; - bool keep_running = TRUE; - while (keep_running) - { - tasto = sht.run(); - if (tasto == K_ENTER) - { - TRectype rec_from(cur.curr()), rec_to(cur.curr()); - rec_from.zero(); rec_to.zero(); - TToken_string fldlist = brw->get_input_field_names(); - TString80 str; - int fi = 0; - for (TString80 tok = inplist.get(fi); tok.not_empty(); tok = inplist.get(), fi++) - { - const TString16 fn = fldlist.get(fi); - const TFieldref fr(fn, 0); - if (*tok == '"') - { - str = tok; - str.ltrim(1); str.rtrim(1); - fr.write(str, rec_from); - fr.write(str, rec_to); - } - else - { - const short id = short(atoi(tok)); - if (sht.id2pos(id+delta) >= 0) - { - str = sht.get(id+delta); - if (str.not_empty()) - fr.write(str, rec_from); - str = sht.get(id+2*delta); - if (str.not_empty()) - fr.write(str, rec_to); - } - else - { - str = _mask->get(id); - fr.write(str, rec_from); - fr.write(str, rec_to); - } - } - } - - if (rec_from.empty() && rec_to.empty()) - { - sht.check(-1); - } - else - { - const long totit = cur.items(); - cur.freeze(TRUE); - cur.curr() = rec_from; - cur.read(); - while (cur.pos() < totit && cur.curr() <= rec_to) - { - sht.check(cur.pos()); - ++cur; - } - cur.freeze(FALSE); - } - } - else - { - keep_running = FALSE; - if (tasto == K_DEL && sht.checked() == 0) - { - error_box(TR("Non è stato selezionato nessun elemento")); - sht.select(0); - keep_running = TRUE; - } - } - } - sht.close_modal(); - - if (tasto == K_DEL) - { - long deleting = sht.checked(); - TString msg; - msg.format(FR("Confermare l'eliminazione di %d elementi"), deleting); - bool can_delete = delete_box(msg); - if (can_delete && deleting > 100) - { - msg.insert(TR("ATTENZIONE: "), 0); - can_delete = delete_box(msg); - } - if (can_delete) - { - TWait_cursor hourglass; - long skipped = 0; // Record non cancellati perche' protetti - cur.freeze(TRUE); // Congelo il cursore altrimenti si riaggiorna troppo - for (long pos = sht.items()-1; deleting > 0; pos--) - { - if (sht.checked(pos)) - { - cur = pos; - brw->do_output(); - bool can_delete = FALSE; - if (find(1)) - { - TRelation& r = *get_relation(); - _autodelete = 0x3; - if (!protected_record(r)) - { - if (modify_mode()) - { - r.restore_status(); - can_delete = remove(); - } - cur.freeze(false); - query_mode(); - cur.freeze(true); - } - _autodelete = FALSE; - } - if (!can_delete) - skipped++; - deleting--; - } - } - cur.freeze(FALSE); - set_limits(); // Riaggiorno il numero del primo/ultimo record - - if (skipped > 0) - { - warning_box(FR("%ld elementi non sono stati cancellati in quanto protetti."), skipped); - query_mode(); - } - } - } - } - else - { - if (search_mode()) - _autodelete = TRUE; - } - return TRUE; -} - -// @doc INTERNAL - -// @mfunc Controlla se una chiave e' completa ed esiste su file -// -// @rdesc Ritorna se la chave esiste sul file -bool TRelation_application::test_key( - word k, // @parm Chiave da ricercare - bool err) // @parm Indica se visualizzare eventuali errori occorsi -{ - bool onereq = false, onefill = false; - - for (TEditable_field* e = _mask->get_key_field(k, true); - e != NULL; - e = _mask->get_key_field(k, false)) - { - if (e->required() && e->shown()) - { - onereq = TRUE; - if (e->empty()) - { - if (err) - { - TString msg(80); - msg = TR("Manca un valore indispensabile per la ricerca."); -#ifdef DBG - msg << "\nChiave " << int(k) << " - Campo " << e->dlg(); - const TFieldref* fr = e->field(); - if (fr != NULL) - { - msg << " - " << fr->name(); - if (fr->to() > 0) - msg << '[' << fr->from() << ',' << fr->to() << ']'; - } -#endif - error_box(msg); - _mask->first_focus(-e->dlg()); - } - return FALSE; - } - } - else - /* if (k == 1 && !onereq && !onefill && c.get().not_empty()) */ - if (!onereq && !onefill && e->is_edit() && !e->empty()) - onefill = TRUE; - } - if (k == 1 && !onereq && !onefill) - { - if (err) - error_box(TR("Manca un valore indispensabile per la ricerca")); - return false; - } - return onefill || onereq; -} - -bool TRelation_application::find(word k) -{ - if (k == 0) - { - for (k = 1; k <= MAX_KEYS && !test_key(k, FALSE); k++); - if (k > MAX_KEYS) - return test_key(1, TRUE); - } - - TRelation& rel = *get_relation(); - TLocalisamfile& fil = rel.file(); - fil.setkey(k); - fil.zero(); - for (TEditable_field* e = _mask->get_key_field(k, true); e; e = _mask->get_key_field(k, false)) - { - if (e->shown()) // Ignora campi invisibili - e->autosave(rel); - } - - const int err = fil.read(_isequal); - return err == NOERR; -} - -void TRelation_application::edit_cancel() -{ - if (_mask->mode() == MODE_MOD) - { - TRelation* rel = get_relation(); - rel->restore_status(); - rel->lfile().reread(_unlock); // Unlock main file - } -} - -short TRelation_application::mask_field_dirty() const -{ - short id = 0; - if (_mask) - { - const int mode = _mask->mode(); - if (mode == MODE_QUERY) - { - FOR_EACH_MASK_FIELD(*_mask, i, f) - { - if (f->dirty() && f->active()) - { - id = f->dlg(); - break; - } - } - } - else - { - FOR_EACH_MASK_FIELD(*_mask, i, f) - { - if (f->dirty() && f->active() && f->field()) - { - if (id == 0) - id = f->dlg(); - if (f->dirty() > 1) // error on field content - { - id = f->dlg(); - break; - } - } - } - } - } - return id; -} - -bool TRelation_application::save(bool check_dirty) -{ - static bool was_dirty = false; - - int pos = _mask->id2pos(DLG_SAVEREC); - if (pos < 0 || !_mask->fld(pos).active()) - { - edit_cancel(); - return true; - } - - int err = NOERR; - const int mode = _mask->mode(); - if (check_dirty) - { - const short dirty = mask_field_dirty(); - - if (mode == MODE_QUERY) - { - const bool cont = !dirty || yesno_box(TR("Annullare i dati inseriti?")); - return cont; - } - - if (!dirty && !was_dirty) - { - edit_cancel(); - 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() > 1; - - KEY k; - if (errore) - { - if (annulla) - { - TString w; - TMask_field& df = _mask->field(dirty); - if (df.is_edit()) - w = ((TEdit_field&)df).get_warning(); - if (w.blank()) - { - w = df.prompt(); - if (!w.blank()) - { - w.trim(); - w << ' ' << TR("inconsistente."); - } - } - if (w.blank()) - w = TR("Campo inconsistente."); - w << '\n'; - switch (last) - { - case K_ESC: - w << TR("Si desidera annullare?"); break; - case K_QUIT: - w << TR("Si desidera uscire?"); break; - default: - w << TR("Si desidera 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(TR("Si desidera registrare?")); - - if (k == K_ESC || k == K_NO) - { - edit_cancel(); - was_dirty = false; - return k == K_NO; - } - - if (annulla) - { - TMask_field& ff = _mask->focus_field(); - if (ff.focusdirty() && ff.is_edit()) // I need simulate tab on the current field! - { - if (!ff.on_key(K_TAB)) - { - _mask->first_focus(-ff.dlg()); - was_dirty = true; - return false; - } - } - if (!_mask->check_fields()) // Exit with ESC didn't check values - { - // check_fields sets the focus on the blocking field - _mask->first_focus(-_mask->focus_field().dlg()); - was_dirty = true; - return false; - } - } - } - was_dirty = false; - - TWait_cursor hourglass; - 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); - } - - switch(err) - { - case NOERR: - _recins = get_relation()->lfile().recno(); - mask2mail(*_mask); - break; - case _isreinsert: - warning_box(TR("Esiste già un elemento con la stessa chiave")); - break; - case _isnowarning: - break; - default: - error_box(FR("Impossibile registrare i dati: errore %d"), err); - break; - } - return err == NOERR; -} - - -int TRelation_application::read(TMask& m) -{ - const TRelation &r = *get_relation(); - -/* Metodo VECCHIO! - const int max = m.fields(); - for (int i = 0; i < max; i++) - { - if (m.fld(i).is_sheet()) - { - TSheet_field& f = (TSheet_field&)m.fld(i); - if (f.record() && !f.external_record()) - f.record()->read(*f.putkey(r)); - } - } -*/ - if (m.sheets() > 0) // Metodo Salvatempo - { - FOR_EACH_MASK_SHEET(m, i, s) - { - if (s->record() && !s->external_record()) - s->record()->read(*s->putkey(r)); - } - } - - m.autoload(r); - return NOERR; -} - -int TRelation_application::write(const TMask& m) -{ - TRelation &r = *get_relation(); - m.autosave(r); - r.curr().set_creation_info(); - - // write relation and all independent sheets - int err = r.write(); - FOR_EACH_MASK_SHEET(m, i, s) - { - if (s->record() && !s->external_record()) - err |= s->record()->write(false); - } - - return err; -} - - -int TRelation_application::rewrite(const TMask& m) -{ - TRelation& r = *get_relation(); - m.autosave(r); - r.curr().set_modify_info(); - // rewrite relation and all independent sheets - r.rewrite(); - int err=r.status(); - - FOR_EACH_MASK_SHEET(m, i, s) - { - if (s->record() && !s->external_record()) - err |= s->record()->write(true); - } - - return err; -} - -const char* TRelation_application::record_description(const TRelation& r) const -{ return r.file().description(); } - -// @doc INTERNAL - -// @mfunc Cancella il record corrente -// -// @rdesc Ritorna se il record e' stato eliminato -bool TRelation_application::relation_remove() -// @comm Se la maschera e' in MODE_MOD non e' possibile cancellare il record e viene -// emesso un di errore. -{ - CHECK(_mask->edit_mode(), "You can call remove in edit mode only"); - - TRelation& r = *get_relation(); - r.restore_status(); - if (protected_record(r)) - return warning_box(FR("%s non eliminabile"), record_description(r)); - - if (_curr_transaction == TRANSACTION_DELETE || - delete_box(FR("Confermare eliminazione %s"), record_description(r))) - { - r.restore_status(); - const bool ok = remove(); - if (ok || is_transaction()) - set_limits(); - else - { - const int err = r.status(); - if (err != NOERR) // Succede nei remove con richiesta di conferma all'utente - return error_box(FR("Errore di cancellazione %d"), err); - } - } - return TRUE; -} - - -bool TRelation_application::protected_record(TRelation &r) -{ - if (user_can_delete(&r)) - return protected_record(r.curr()); - return true; -} - -bool TRelation_application::remove() -{ - int err = get_relation()->remove(); - if (err == NOERR) - { - const int maxf = _mask->fields(); - for (int i = 0; i < maxf; i++) - { - const TMask_field& mf = _mask->fld(i); - if (mf.is_sheet()) - { - TSheet_field& f = (TSheet_field&)mf; - if (f.record()&& !f.external_record()) - err |= f.record()->remove(); - } - } - } - if (err == NOERR) - { - _mask->set_mode(NO_MODE); - mask2mail(*_mask); - } - return err == NOERR; -} - -bool TRelation_application::firm_change_enabled() const -{ - bool ok = TApplication::firm_change_enabled(); - ok &= (_mask == NULL || _mask->query_mode()) && _lnflag == 0; - return ok; -} - -void TRelation_application::main_loop() -{ - KEY k; - do { - // ciclo delle transazioni - _recins = -1; - - // imposta la maschera in query mode - query_mode(); - _mask->open_modal(); - - // Provoca l'autopremimento per il messaggio di LINK - if (_lnflag) - { - if (_trans_counter < _ntransactions) - { - // la transazione è sul .ini : la imposta nelle variabili _curr_transaction... - if (load_transaction()) - { - // la transazione necessita di autopremimento - _autodelete = _curr_transaction == TRANSACTION_DELETE; - if (_curr_transaction == TRANSACTION_INSERT ) - _mask->send_key(K_CTRL+'N', 0); - else - _mask->send_key(K_AUTO_ENTER, 0); - } - } - else // la transazione non è sul .ini - { - _mask->send_key(K_AUTO_ENTER, 0); - } - } - - if (is_transaction()) - ini2query_mask(); - - do - { - const bool change = firm_change_enabled(); - // Dis/abilita cambio ditta - enable_menu_item(M_FILE_NEW, change); - - if (_mask->edit_mode()) - { - if (_autodelete) - { - const int pos = _mask->id2pos(DLG_DELREC); - if (pos >= 0 && _mask->fld(pos).active()) - _mask->send_key(K_CTRL+'E', 0); - else - error_box(TR("Elemento non eliminabile.")); - _autodelete = FALSE; - } - } - - if (_curr_trans_mode == TM_BATCH) -// { - batch(); -/* if (_mask->check_fields()) - { - if (_curr_transaction == TRANSACTION_INSERT) - k = K_INS; - else - if (_curr_transaction == TRANSACTION_MODIFY) - k = K_ENTER; - else - if (_curr_transaction == TRANSACTION_DELETE) - k = K_DEL; - else - k = K_ESC; - } - else - k = K_ESC; - } - else */ - k = _mask->run(); - - switch (k) - { - case K_ESC: - if (save(TRUE)) - { - if (save_and_quit()) - k = K_QUIT; - else - { - edit_cancel(); // Novità 19-06-2012 - query_mode(); - } - } - break; - case K_QUIT: - if (!save(TRUE)) - k = K_ENTER; - break; - case K_F1: - dispatch_e_menu(M_HELP_CONTENTS); - break; - case K_F2: - dispatch_e_menu(M_FILE_ABOUT); - break; - case K_ENTER: - if (_lnflag && _curr_transaction != TRANSACTION_RUN) - { - if (find(1)) - { - if (_curr_transaction == TRANSACTION_INSERT) - _curr_transaction = TRANSACTION_MODIFY; - if (!modify_mode()) - k = K_QUIT; - } - else - { - if (_curr_transaction == TRANSACTION_MODIFY) - _curr_transaction = TRANSACTION_INSERT; - insert_mode(); - } - } - else - { - if (find(0)) - modify_mode(); - else - insert_mode(); - } - if (_curr_trans_mode == TM_AUTOMATIC || _curr_trans_mode == TM_BATCH) - _mask->send_key(K_CTRL+'R', 0); - break; - case K_SAVE: - if (save(FALSE)) - { - if (save_and_quit()) - { - k = K_QUIT; - } - else - { - if (save_and_new() && can_I_write(NULL)) - { - if (_mask->insert_mode()) - insert_mode(); - else - query_mode(); - } - else - { - const TMask_field & f = _mask->focus_field(); - - _mask->first_focus(-f.dlg(), false); - modify_mode(); - } - } - } - break; - case K_INS: - if (_mask->query_mode() || save(TRUE)) - { - const bool trovato = _mask->query_mode() && test_key(1, FALSE) && find(1); - if (trovato) - { - if (is_transaction()) - _curr_transaction=TRANSACTION_MODIFY; - else - warning_box(TR("Elemento gia' presente")); - modify_mode(); - } - else - insert_mode(); - } - if (_curr_trans_mode == TM_AUTOMATIC || _curr_trans_mode == TM_BATCH) - _mask->send_key(K_CTRL+'R', 0); - break; - case K_DEL: - if (_mask->query_mode()) - { - delete_mode(); - } - else - { - if (relation_remove()) - { - query_mode(); - if (_autoins_caller.not_empty() || is_transaction()) - { - if (_lnflag) _recins = 0; - k = K_QUIT; - } - } - } - break; - case K_F9: - if (_mask->query_mode() || 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: - { - TCursor* c = get_filtered_cursor(); - - if (!has_filtered_cursor() || c->curr().num() != file().curr().num()) - { - for (TEdit_field* e = (TEdit_field *) _mask->get_key_field(1, TRUE); e; e = (TEdit_field *) _mask->get_key_field(1, FALSE)) - { - if (e->is_kind_of(CLASS_EDIT_FIELD) && e->shown() && e->browse() != NULL) // Ignora campi invisibili o senza check - { - TCursor* b = e->browse()->cursor(); - - if (b && b->curr().num() == file().curr().num()) - { - c = b; - break; - } - } - } - } - - TCursor* cur = c ; - - if (c == NULL) - cur = new TCursor(get_relation()); - - err = file().reread(); - cur->curr() = file().curr(); - cur->read(); - ++(*cur); - while (cur->pos() < cur->items() && !can_I_read(cur->relation())) - ++(*cur); - file().curr() = cur->curr(); - if (can_I_read(cur->relation())) - err = get_relation()->read(_isequal, _testandlock); - if (c == NULL) - delete cur; - } - break; - case K_PREV: - { - TCursor* c = get_filtered_cursor(); - - if (!has_filtered_cursor() || c->curr().num() != file().curr().num()) - { - for (TEdit_field* e = (TEdit_field *) _mask->get_key_field(1, TRUE); e; e = (TEdit_field *) _mask->get_key_field(1, FALSE)) - { - if (e->is_kind_of(CLASS_EDIT_FIELD) && e->shown() && e->browse() != NULL) // Ignora campi invisibili o senza check - { - TCursor* b = e->browse()->cursor(); - - if (b && b->curr().num() == file().curr().num()) - { - c = b; - break; - } - } - } - } - - TCursor* cur = c ; - - if (c == NULL) - cur = new TCursor(get_relation()); - - file().reread(); - cur->curr() = file().curr(); - cur->read(); - --(*cur); - while (cur->pos() > 0 && !can_I_read(cur->relation())) - --(*cur); - file().curr() = cur->curr(); - if (can_I_read(cur->relation())) - err = get_relation()->read(_isequal, _testandlock); - if (c == NULL) - delete cur; - } - break; - case K_END: - err = file().readat(_last, _testandlock); - break; - default: - break; - } - if (err == NOERR || err == _islocked) - { - _navigating = true; - modify_mode(); - _navigating = false; - } - 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) - { - NFCHECK("Obsolete LINK message calling convention"); - TString16 num; - num.format("%ld", _recins); - TMessage msg(autoins_caller(), _lnflag ? MSG_LN : MSG_AI, num); - msg.send(); - } - - if (is_transaction()) - { - TConfig ini(_trans_ini.row(_trans_counter), "Transaction"); - ini.set("Record", _recins); - if (_recins >= 0) - { - ini.set("Result", "OK"); - ini.set("Error", "0"); - edit_mask2ini(); - } - else - { - const int err = get_relation()->status(); - ini.set("Result", err == NOERR ? "CANCEL" : "ERROR"); - ini.set("Error", err); - } - if (_curr_trans_mode == TM_BATCH) - { - batch(false); - - TString_array & errs = errors(); - - FOR_EACH_ARRAY_ROW(errs, r, s) - ini.set("ErrMsg", *s, "Main", false, r); - - TString_array & warns = warnings(); - - FOR_EACH_ARRAY_ROW(warns, r1, s1) - ini.set("WarningMsg", *s1, "Main", false, r1); - } - - } - _trans_counter++; - } while ( _trans_counter < _ntransactions); - if (_curr_trans_mode == TM_BATCH) - force_stop(); -} - -bool TRelation_application::filter() -{ - if (parse_command_line()) - return true; - - 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 = _mask->efield(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, 0x2); - 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; - - TString str, tmp; - const char* v = body.get(); - 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)) - { - str = v; - tmp.format("%d=", f.dlg()); - str.insert(tmp, 0); - _fixed.add(str); - v = body.get(); - } - } - } - - mail.restart(); - msg = mail.next_s(MSG_ED); - if (msg) - { - TToken_string body(msg->body()); - const int key = body.get_int(); - - _autoins_caller = msg->from(); - _lnflag = 2; - - TAssoc_array field_values; - const char * s; - TString t, v; - - while((s = body.get()) != NULL) - { - t = s; - const int u = t.find('='); - - CHECKS(u > 0, "Invalid edit message ", (const char *) body); - if (u > 0) - { - v = t.mid(u + 1); - - t.cut(u); - field_values.add(t, v); - } - } - - for (int i = 0; i < _mask->fields(); i++) - { - TMask_field& f = _mask->fld(i); - const TFieldref * field = f.field(); - - if (field && f.in_key(key)) - { - TString16 field_name(field->name()); - const int from = field->from(); - const int to = field->to(); - - if (to >= 0) - field_name << "[" << (from + 1); - const TString * v = (const TString *) field_values.objptr(field_name); - - TString val; - if (v == NULL && to >= 0) - { - v = (const TString *)field_values.objptr(field->name()); - if (v) - val = v->sub(from, to); - } - else - if (v) val = *v; - - if (v && f.dlg() > 0) - { - t.format("%d=", f.dlg()); - val.insert(t, 0); - _fixed.add(val); - } - } - } - } - - 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(); - - TString16 tmp; - 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)) - { - TString s(v); - tmp.format("%d=", f.dlg()); - s.insert(tmp, 0); - _fixed.add(s); - v = body.get(); - } - } -} - - -bool TRelation_application::parse_command_line() -{ - _trans_ini.destroy(); - _trans_counter=0; - _curr_transaction = ""; - _curr_trans_mode = 'I'; - - TFilename ini; - for (int i = argc()-1; i > 0; i--) - { - ini = argv(i); - if ((ini[0] == '-' || ini[0] == '/') && (ini[1] == 'I' || ini[1] == 'i')) - { - ini.ltrim(2); - if (ini.starts_with("=")) - ini.ltrim(1); - CHECK(!ini.blank(),"Manca l'indicazione della transazione. Il nome va indicato di seguito al -i, senza interporre spaziatura."); - if (ini.find('*')>=0) - { - // metachars: - list_files(ini, _trans_ini); - } - else - { - if (ini.exist()) - _trans_ini.add(ini); - else - cantread_box(ini); - } - break; - } - } - - _ntransactions= _trans_ini.items(); - - _lnflag = _ntransactions>0; - return _lnflag != 0; -} - -// il valore di ritorno indica se attivare l'"automagia": -// spedizione dei tasti e precaricamento della maschera -bool TRelation_application::load_transaction() -{ - bool retv = FALSE; - if (_trans_counter < _ntransactions) - { - TConfig cnf(_trans_ini.row(_trans_counter), "Transaction"); - _curr_transaction = cnf.get("Action"); - _curr_transaction.upper(); - _curr_trans_mode = toupper(cnf.get("Mode")[0]); - _curr_trans_from = cnf.get("From"); - const long firm = cnf.get_long("Firm"); - if (firm > 0) - { - bool ok = set_firm(firm); - if (ok) - _mask->on_firm_change(); - else - error_box(FR("La ditta %ld non esiste"), firm); - } - if (_curr_transaction == TRANSACTION_RUN) - retv = false; // Ho gia' finito qui: basta il cambio ditta - else - retv = true; // Attiva automagia - } - return retv; -} - -void TRelation_application::on_firm_change() -{ - TApplication::on_firm_change(); - if (_mask != NULL) - { - set_limits(0x3); - } -} - -void TRelation_application::ini2query_mask() -{ - if (is_transaction()) - { - TString8 n; n.format("%d", get_relation()->lfile().num()); - TConfig ini(_trans_ini.row(_trans_counter), n); - ini2mask(ini, *_mask, TRUE); - } -} - -void TRelation_application::ini2insert_mask() -{ - if (is_transaction()) - { - TString8 n; n.format("%d", get_relation()->lfile().num()); - TConfig ini(_trans_ini.row(_trans_counter), n); - ini2mask(ini, *_mask, FALSE); - } -} - -void TRelation_application::ini2mask(TConfig& ini, TMask& m, bool query) -{ - const TString16 defpar = ini.get_paragraph(); - TString tmp; - - _fixed.cut(0); - for (int f = m.fields()-1; f >= 0; f--) - { - TMask_field& campo = m.fld(f); - const TFieldref* fref = campo.field(); - if (fref) - { - if (!query || campo.in_key(0)) - { - const TString& str = fref->read(ini, defpar); - if (str.not_empty()) - { - campo.set(str); - if (query) - { - tmp.format("%d=%s", campo.dlg(), (const char *) str); - _fixed.add(tmp); - } - } - } - } - else - { - if (!query && campo.is_sheet()) - { - TSheet_field &sheet=(TSheet_field &)campo; - ini2sheet(ini, sheet); - } - } - } - ini.set_paragraph(defpar); - if (query) - set_fixed(); -} - -void TRelation_application::edit_mask2ini() -{ - const TString& str = _trans_ini.row(_trans_counter); - if (str.full()) - { - TString8 head; head.format("%d", get_relation()->lfile().num()); - TConfig ini(str, head); - mask2ini(*_mask, ini); - } -} - - -void TRelation_application::ini2sheet(TConfig& ini,TSheet_field &sheet) -{ - if (sheet.record() != NULL) - { - const int lognum = sheet.record()->logic_num(); - const TMask& sm = sheet.sheet_mask(); - - // scrive le righe nello sheet associato - TString16 defpar; - - for (int r = 1; ;r++) - { - defpar.format("%d,%d", lognum, r); - if (ini.set_paragraph(defpar)) - { - TToken_string& row = sheet.row(r-1); - for (int sf = sm.fields()-1; sf >= 0; sf--) - { - TMask_field& campo = sm.fld(sf); - const TFieldref* fref = campo.field(); - if (fref) - { - const TString& str = fref->read(ini, defpar); - row.add(str, sheet.cid2index(campo.dlg())); - } - } - sheet.check_row(r-1); - } - else - break; - } - } -} - -void TRelation_application::sheet2ini(TSheet_field &sheet,TConfig& ini) -{ - if (sheet.record() != NULL) - { - const int lognum = sheet.record()->logic_num(); - const TMask& sm = sheet.sheet_mask(); - - // scrive le righe degli sheet associati - TString16 defpar; - TString str; - int r; - - for (r = 1 ; r <= sheet.items(); r++) - { - defpar.format("%d,%d", lognum, r); - - TMask_field* fkey; - sheet.restart_key(); - while ((fkey = sheet.get_key(str))) - { - ini.set(str, fkey->get(), defpar); - } - - TToken_string& row = sheet.row(r-1); - const char* value; - int i; - for (i = 0, value = row.get(0); value; i++, value = row.get()) - { - const TMask_field& campo = sm.field(FIRST_FIELD+i); - const TFieldref* fr = campo.field(); - if (fr) - { - if (value == NULL || *value == '\0') - value = " "; - // ini.set(fr->name(), value, defpar); - fr->write(ini, defpar, value); - } - } - } - for (r = sheet.items()+1; ; r++) - { - defpar.format("%d,%d", lognum, r); - if (ini.set_paragraph(defpar)) - ini.remove_all(); - else - break; - } - } -} - -void TRelation_application::mask2ini(const TMask& m, TConfig& ini) -{ - ini.set("Firm", get_firm(), "Transaction"); - ini.set("User", user()); - ini.set("HostName", get_hostname()); - - int year, release, tag, patch; - if (get_version_info(year, release, tag, patch)) - { - TString80 ver; - ver.format("%d %d.%d-%d", year, release, tag, patch); - ini.set("Version", ver); - } - - const TLocalisamfile& lfile = get_relation()->lfile(); - - TString16 defpar; - defpar.format("%d", lfile.num()); - ini.set_paragraph(defpar); - switch (lfile.num()) - { - case LF_TAB: - case LF_TABCOM: - case LF_TABGEN: - { - const TString& tabname = lfile.curr().get("COD"); - ini.set("COD", tabname, defpar); - } - break; - } - for (int f = 0; f < m.fields(); f++) - { - TMask_field& campo = m.fld(f); - if (campo.shown()) - { - const TFieldref* fr = campo.field(); - if (fr) - { - if (campo.empty()) - fr->write(ini, defpar, " "); - else - { - if (campo.class_id() == CLASS_DATE_FIELD && campo.right_justified()) - { - const TDate d(campo.get()); - fr->write(ini, defpar, d.string(ANSI)); - } - else - fr->write(ini, defpar, campo.get()); - } - } - else - if (campo.is_sheet()) - { - TSheet_field &sheet=(TSheet_field &)campo; - sheet2ini(sheet,ini); // It's virtual - } - } - } - ini.set_paragraph(defpar); // Reimposta paragrafo standard -} - -bool TRelation_application::mask2mail(const TMask& m) -{ - TWait_cursor hourglass; - bool ok = _curr_trans_from.empty() && ::can_dispatch_transaction(get_relation()->curr()); - if (ok) - { - TFilename ininame; ininame.temp("msg", "ini"); - if (ok) // Test qualunque per usare {} - { - TConfig ini(ininame, "Transaction"); - const char* action = ""; - char mode[2] = { TM_AUTOMATIC, '\0' }; - switch (m.mode()) - { - case NO_MODE: - action = TRANSACTION_DELETE; - break; - case MODE_MOD: - action = TRANSACTION_MODIFY; - break; - default: - action = TRANSACTION_INSERT; - break; - } - ini.set("Action", action); - ini.set("Mode", mode); - mask2ini(m, ini); - } - ok = ::dispatch_transaction(get_relation()->curr(), ininame); - xvt_fsys_remove_file(ininame); - } - return ok; -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////// +// TRelation_application +/////////////////////////////////////////////////////////// + +TRelation_application::TRelation_application() + : _mask(NULL), _search_id(-1), _lnflag(0), + _autodelete(0), _navigating(false), + _locked(false) +{ } + +TRelation_application::~TRelation_application() +{ } + +bool TRelation_application::has_filtered_cursor() const +{ + bool yes = filtered(); + if (yes) + { + const TEdit_field& f = get_search_field(); + yes = f.browse() != NULL; + } + return yes; +} + + +TCursor * TRelation_application::get_filtered_cursor() const +{ + if (has_filtered_cursor()) + { + const TEdit_field& f = get_search_field(); + + return f.browse()->cursor(); + } + else + return NULL; +} + +void TRelation_application::setkey() +{ + if (has_filtered_cursor()) + get_filtered_cursor()->setkey(); + else + file().setkey(1); +} + +void TRelation_application::set_key_filter() +{ + TString rf = get_user_read_filter(); rf.trim(); + if (rf.not_empty()) + { + TString expr; + for (int f = _mask->fields()-1; f >= 0; f--) + { + TMask_field& fld= _mask->fld(f); + if (fld.is_edit() && fld.in_key(0)) + { + TBrowse* b = ((TEdit_field&)fld).browse(); + if (b && b->cursor()->relation()->lfile().num() == get_relation()->lfile().num()) + { + expr = b->get_filter(); + if (expr.find(rf) < 0) + { + if (expr.not_empty()) + { + expr.insert("(", 0); + expr << ")&&(" << rf << ')'; + } + else + expr = rf; + b->set_filter(expr); + } + } + } + } + } +} + + +// @doc INTERNAL + +// @mfunc Setta i limiti +void TRelation_application::set_limits( + byte what) // @parm tipo di limite da assegnare al record + +// @comm I limiti possibili sono: +// @flag 0 | Nessuna operazione +// @flag 1 | Primo record +// @flag 2 | Ultimo record +// @flag 3 | Entrambi +{ + if (has_filtered_cursor()) + { + const TEdit_field& f = get_search_field(); + if (f.browse() != NULL) + f.browse()->do_input(true); + + TCursor* cur = get_filtered_cursor(); + cur->setkey(); + if (cur->items() > 0) + { + TBaseisamfile& f = cur->file(); + if (what & 0x1) + { + *cur = 0; + _first = f.recno(); + } + if (what & 0x2) + { + *cur = cur->items() - 1; + _last = f.recno(); + } + } + else + _first = _last = -1; + } + else + { + setkey(); + TBaseisamfile& f = file(); + if (!f.empty()) + { + if (what & 0x1) + { + if (f.first() == NOERR) + _first = f.recno(); + } + if (what & 0x2) + { + if (f.last() == NOERR) + _last = f.recno(); + } + } + else + _first = _last = -1; + } +} + +void TRelation_application::set_find_button() +{ + // Ricalcola posizioni bootoni di navigazione con la vecchia toolbar + WINDOW bar = _mask->toolbar(); + if (bar != NULL_WIN) + xvt_toolbar_realize(_mask->toolbar()); + else // Non c'e' la nuova relapbar + { + int pos = _mask->id2pos(DLG_FINDREC); + if (pos >= 0 && _mask->id2pos(DLG_FIRSTREC) >= 0) //se e' un bottone pentapartito... + { + TButton_field& f_find = (TButton_field &)_mask->fld(pos); + RCT rct_base; f_find.get_rect(rct_base); + const int bwidth = (rct_base.right - rct_base.left); + const int bheight = (rct_base.bottom - rct_base.top); + if (bwidth > 3*bheight/2) // Controllo se ho gia' ridimensionato i bottoni in precedenza + { + int bx = bwidth / 3; + int by = bheight / 2; + + RCT r = rct_base; + r.left += bx; r.right -= bx; + if (!NATIVE_CONTROLS) + { + r.left -= 2; r.right += 2; + } + f_find.set_rect(r); // Ridimensiona il bottone centrale di ricerca + + if (!NATIVE_CONTROLS) + { + bx += 5; by += 3; // Aggiusta dimensioni bottoni sussidiari + } + + pos = _mask->id2pos(DLG_FIRSTREC); + if (pos >= 0) + { + r = rct_base; r.top = r.bottom - by; r.right = r.left + bx; + _mask->fld(pos).set_rect(r); + } + pos = _mask->id2pos(DLG_PREVREC); + if (pos >= 0) + { + r = rct_base; r.bottom = r.top + by; r.right = r.left + bx; + _mask->fld(pos).set_rect(r); + } + pos = _mask->id2pos(DLG_NEXTREC); + if (pos >= 0) + { + r = rct_base; r.bottom = r.top + by; r.left = r.right - bx; + _mask->fld(pos).set_rect(r); + } + pos = _mask->id2pos(DLG_LASTREC); + if (pos >= 0) + { + r = rct_base; r.top = r.bottom - by; r.left = r.right - bx; + _mask->fld(pos).set_rect(r); + } + } + } + } +} + +bool TRelation_application::create() +{ + bool ok = user_create(); + if (ok) + { + write_enable(); + _mask = get_mask(MODE_QUERY); + + filter(); + set_key_filter(); + set_limits(); + } + return ok ? TSkeleton_application::create() : ok; +} + + +bool TRelation_application::destroy() +{ + user_destroy(); + return TSkeleton_application::destroy(); +} + + +void TRelation_application::set_fixed() +{ + TToken_string s(256, '='); + FOR_EACH_TOKEN(_fixed, f) + { + s = f; + const short id = s.get_int(0); + if (id > 0 && _mask->id2pos(id) >= 0) + { + s = s.get(); + if (s.not_empty()) + _mask->set(id, s); + + if (_lnflag < 2) + _mask->disable(id); + } + } +} + +void TRelation_application::enable_query() +{ + const bool query = _mask->query_mode(); + const bool keyon = query || get_relation()->status() == _isreinsert; + + for (int i = _mask->fields() - 1; i >= 0; i--) + { + TMask_field& c = _mask->fld(i); + + if (c.in_key(0) && c.enabled_default()) + { + if (c.in_key(1)) + c.enable(keyon); + if (c.is_edit()) + { + TEdit_field& e = (TEdit_field&)c; + if (e.browse() != NULL) + e.enable_check(query); + } + } + } + + set_fixed(); +} + +bool TRelation_application::can_I_write(const TRelation* rel) const +{ return !_locked && user_can_write(rel); } + +bool TRelation_application::can_I_read(const TRelation* rel) const +{ return user_can_read(rel); } + +void TRelation_application::set_toolbar() +{ + const int mode = _mask->mode(); + const bool can_edit_some = can_I_write(NULL); + const bool can_nav = _lnflag == 0 && _curr_transaction != TRANSACTION_LINK; + + bool enabsave = can_edit_some; + int pos = _mask->id2pos(DLG_SAVEREC); + if (pos >= 0) + { + enabsave = can_edit_some && (mode != MODE_QUERY) && can_I_write(get_relation()); + _mask->fld(pos).enable(enabsave); + } + pos = _mask->id2pos(DLG_DELREC); + if (pos >= 0) + { + bool enabdel = can_edit_some && (mode == MODE_QUERY || mode == MODE_MOD); + if (enabdel && mode == MODE_MOD) + { + TRelation& r = *get_relation(); + const TRecnotype oldpos = r.lfile().recno(); + enabdel = enabsave && !protected_record(r) && user_can_delete(&r); + if (r.lfile().recno() != oldpos) + r.lfile().readat(oldpos); + } + _mask->fld(pos).enable(enabdel); + } + + pos = _mask->id2pos(DLG_FINDREC); + if (pos >= 0) + { + _mask->fld(pos).enable(_lnflag == 0); + + const long recno = get_relation()->lfile().recno(); + const bool enable_next_prev = _mask->edit_mode(); + + pos = _mask->id2pos(DLG_FIRSTREC); + if (pos >= 0) + _mask->fld(pos).enable(can_nav && (enable_next_prev ? _first != recno : _first > 0)); + pos = _mask->id2pos(DLG_PREVREC); + if (pos >= 0) + _mask->fld(pos).enable(can_nav && enable_next_prev && _first > 0 && _first != recno); + pos = _mask->id2pos(DLG_NEXTREC); + if (pos >= 0) + _mask->fld(pos).enable(can_nav && enable_next_prev && _last > 0 && _last != recno); + pos = _mask->id2pos(DLG_LASTREC); + if (pos >= 0) + _mask->fld(pos).enable(can_nav && (enable_next_prev ? _last != recno : _last > 0)); + } + + pos = _mask->id2pos(DLG_NEWREC); + if (pos >= 0) + { + bool enabins = (mode == MODE_QUERY || _lnflag == 0) && can_edit_some; + _mask->fld(pos).enable(enabins); + } + + set_find_button(); + enable_query(); +} + +void TRelation_application::update_navigation_bar() +{ + if (_mask->query_mode()) + { + set_limits(); + set_toolbar(); + } +} + +bool TRelation_application::save_and_new() const +{ return false; } + +bool TRelation_application::save_and_quit() const +{ + return (_autoins_caller.full() || _curr_transaction.not_empty()) && _curr_trans_mode != TM_REMAIN; +} + +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); + + set_toolbar(); + _mode = mode; + + const char* t = ""; + switch(mode) + { + case MODE_QUERY: + t = TR("Ricerca"); break; + case MODE_MOD: + t = TR("Modifica"); break; + case NO_MODE: + t = TR("Ricerca/Inserimento"); break; + case MODE_INS: + t = TR("Inserimento"); break; + default: + break; + } + + xvtil_statbar_set(t, TRUE); + + return _mode; +} + +// @doc INTERNAL + +// @mfunc Permette di autonumerare un record +// +// @rdesc Ritorna se e' riuscito a creare una nuova autonumerazione: +// +// @flag TRUE | La chiave non e' vuota +// @flag FALSE | Non e' riuscito ad autonumerare il documento +bool TRelation_application::autonum( + TMask* m, // @parm Maschera a cui applicare l'autonumerazione + bool rec) // @parm Indica se registrare la chiave anche sul record corrente +{ + TToken_string k; + if (!get_next_key(k)) + { + k = get_next_key(); +#ifdef DBG + if (k.full()) + xvt_dm_popup_warning("'const char* get_next_key()' is deprecated: implement 'bool get_next_key(TToken_string&)'"); +#endif + } + + if (!rec && !m->query_mode()) + m->reset(); + _renum_message = ""; + + for (const char* n = k.get(0); n && *n; n = k.get()) + { + TMask_field* fld = NULL; + if (isdigit(*n)) + fld = m->find_by_id(atoi(n)); + else + fld = m->find_by_fieldname(n); + if (fld == NULL) + { + NFCHECK("Identificatore di autonumerazione errato"); + return false; + } + const char* val = k.get(); + TMask_field& f = *fld; + if (rec || f.empty()) + f.set(val); + if (rec) + ((TEditable_field&)f).autosave(*get_relation()); + if (_renum_message.empty() || f.in_key(1)) + _renum_message.format(FR("L'elemento è stato registrato con:\n %s = %s"), + (const char*)f.prompt(), (const char*)f.get()); + } + return k.full(); +} + +// @doc EXTERNAL + +// @mfunc Entra in modo di ricerca +void TRelation_application::query_mode( + bool pre_ins) // @parm Indica in quale modo andare: + // + // @flag TRUE | Entra in modo MODE_QUERY_INSERT + // @flag FALSE | Entra in modo MODE_QUERY (default) +{ + 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(); + set_limits(); + } + + _mask->set_mode(pre_ins ? MODE_QUERYINS : MODE_QUERY); + _mask->reset(); + _mask->disable_page(1); // Nasconde pagine inutili + + if (pre_ins) + { + set_mode(NO_MODE); + init_query_insert_mode(*_mask); + enable_query(); + } + else + { + set_mode(MODE_QUERY); + init_query_mode(*_mask); + enable_query(); + + // Aggiorna bottoni di ricerca: utile soprattutto per ve0 che imposta CODNUM + if (has_filtered_cursor()) + { + set_limits(); + set_toolbar(); + } + } +} + + +void TRelation_application::insert_mode() +{ + bool try_auto = true; + + if (_mask->query_mode()) + try_auto = !test_key(1, FALSE); + + if (try_auto && !autonum(_mask, FALSE)) + { + query_insert_mode(); + return; + } + + TRelation* r = get_relation(); + r->zero(); + _mask->autosave(*r); + + if (!can_I_write(r)) + { + warning_box(FR("L'utente %s non puo' inserire %s"), (const char*)user(), r->file().description()); + 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(); + xvt_fsys_remove_file(workname); + _mask->open_modal(); + } + else + _mask->enable_page(1); + + set_mode(MODE_INS); + r->zero(); // Azzera tutta la relazione! + + _mask->load_defaults(); + init_insert_mode(*_mask); + + // ....possibilmente spostare questa chiamata ..... + if (is_transaction() && _curr_transaction == TRANSACTION_INSERT) + ini2insert_mask(); +} + +bool TRelation_application::modify_mode() +{ + TRelation* rel = get_relation(); + const TReclock block = can_I_write(rel) ? _testandlock : _nolock; + int err = rel->read(_isequal, block); + + if (!can_I_read(rel)) + { + warning_box(TR("I dati non sono accessibili per l'utente %s"), (const char*)user()); + query_mode(); + return FALSE; + } + _locked = false; + if (err != NOERR) + { + if (err == _islocked) + { + _locked = true; + message_box(TR("I dati sono già usati da un altro programma, scrittura disabilitata")); + } + else + { + error_box(FR("Impossibile leggere i dati: errore %d"), err); + if (!is_transaction()) + 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(); + else + _mask->enable_page(1); + + set_mode(MODE_MOD); + + err = read(*_mask); + if (err != NOERR) + { + query_mode(); + return FALSE; + } + + rel->save_status(); + init_modify_mode(*_mask); + + // ....possibilmente spostare questa chiamata ..... + // Forse deve essere fatta prima della init_modify_mode()! + if (_curr_transaction == TRANSACTION_MODIFY) + ini2insert_mask(); + return TRUE; +} + + +TEdit_field& TRelation_application::get_search_field() const +{ + short id = _search_id; + + if (id <= 0 || !_mask->field(id).shown()) + { + for (int i = _mask->fields()-1; i >= 0; i--) + { + const TMask_field& f = _mask->fld(i); + if (f.is_edit() && f.in_key(1) && f.shown()) + { + id = f.dlg(); + break; + } + } + } + + return _mask->efield(id); +} + +bool TRelation_application::search_mode() +{ + if (_mask->mode() != MODE_QUERY) + query_mode(); + + TEdit_field* prima = &get_search_field(); + while (prima) + { + if (prima->on_key(K_F9)) + { + if (find(1)) + return modify_mode(); + else + break; + } + + TMask_field* dopo = &_mask->focus_field(); + if (dopo != prima && dopo->is_edit() && dopo->in_key(0)) + prima = (TEdit_field*)dopo; + else + break; + } + return false; +} + +HIDDEN bool delete_handler(TMask_field& f, KEY k) +{ + if (k == K_TAB && f.focusdirty() && !f.empty()) + { + TMask& m = f.mask(); + const bool finale = *f.prompt() == 'A'; + const int pos = m.id2pos(f.dlg()); + if (pos >= 3) + { + const TMask_field& e = m.fld(pos - 3); + if (e.is_edit() && e.get().blank()) + { + const short id = e.dlg() - (finale ? 200 : 100); + const TRelation_application& app = (TRelation_application&)main_app(); + const TMask_field& orig = app.curr_mask().field(id); + bool req = orig.required(); + if (!req && orig.is_edit()) + { + const TEdit_field& e = (TEdit_field&)orig; + req = e.validate_func() == 12; + } + if (req) + { + TString str; str << (finale ? TR("A ") : TR("Da ")) << orig.prompt(); + return f.error_box(FR("Specificare anche il valore %s"), (const char*)str); + } + } + } + if (finale && !f.get().blank()) + { + const TMask_field& p = m.fld(pos - 1); + TString80 prec = p.get(); + TString80 curr = f.get(); + bool ok; + switch (p.class_id()) + { + case CLASS_REAL_FIELD: ok = real(prec) <= real(curr); break; + case CLASS_DATE_FIELD: ok = TDate(prec) <= TDate(curr); break; + default : ok = prec <= curr; break; + } + if (!ok) + return f.error_box(FR("Inserire un valore non inferiore a '%s'"), (const char*)prec); + } + } + return TRUE; +} + +int TRelation_application::delete_mode() +{ + TEdit_field& fld = get_search_field(); + TBrowse* brw = fld.browse(); + if (brw) + { + brw->do_input(TRUE); + TCursor& cur = *brw->cursor(); + + TToken_string head(brw->head()); + head.insert("@1|", 0); + TToken_string items(brw->items()); + items.insert(" |", 0); + + int tab1 = 0, tab2 = 0, y = 0; + // Nuovo modo basato sugli input + TToken_string inplist = brw->get_input_fields(); + if (inplist.not_empty()) + { + FOR_EACH_TOKEN(inplist, tok) + { + if (*tok != '"' && strchr(tok, '@') == NULL) + { + TMask_field& e = _mask->field(short(atoi(tok))); + if (e.active()) + { + const int len = strlen(e.prompt()); + if (len > tab1) tab1 = len; + const int size = e.size(); + if (size > tab2) tab2 = size; + y++; + } + } + } + } + tab1 += 5; + tab2 += tab1+2; + + cur = 0L; + TCursor_sheet sht(&cur, items, TR("Eliminazione"), head, 0x4, y); + + y = -1; // Posizione del campo precedente + TString prompt; // Prompt del campo corrente + const short delta = 100; + + FOR_EACH_TOKEN(inplist, tok) + { + if (*tok != '"' && strchr(tok, '@') == NULL) + { + TMask_field& e = _mask->field(short(atoi(tok))); + if (!e.active()) + continue; + + const short id = e.dlg()+delta; + prompt = "Da "; prompt << e.prompt(); + sht.add_static(DLG_NULL, 0, prompt, 1, ++y); + TString16 flags; + if (e.automagic()) flags << 'A'; + if (e.roman()) flags << 'M'; + if (e.right_justified()) flags << 'R'; + if (e.uppercase()) flags << 'U'; + if (e.zerofilled()) flags << 'Z'; + switch (e.class_id()) + { + case CLASS_DATE_FIELD: + { + TDate_field& d1 = sht.add_date(id, 0, "", tab1, y, flags); + TDate_field& d2 = sht.add_date(id+delta, 0, "A ", tab2, y, flags); + d1.set_handler(delete_handler); + d2.set_handler(delete_handler); + } + break; + case CLASS_REAL_FIELD: + { + TReal_field& r1 = sht.add_number(id, 0, "", tab1, y, e.size(), flags); + TReal_field& r2 = sht.add_number(id+delta, 0, "A ", tab2, y, e.size(), flags); + r1.set_handler(delete_handler); + r2.set_handler(delete_handler); + } + break; + default: + { + TEdit_field& e1 = sht.add_string(id, 0, "", tab1, y, e.size(), flags); + TEdit_field& e2 = sht.add_string(id+delta, 0, "A ", tab2, y, e.size(), flags); + e1.set_handler(delete_handler); + e2.set_handler(delete_handler); + } + break; + } + if (y == 0) + sht.first_focus(id); + } + } + + sht.open_modal(); + + KEY tasto; + bool keep_running = TRUE; + while (keep_running) + { + tasto = sht.run(); + if (tasto == K_ENTER) + { + TRectype rec_from(cur.curr()), rec_to(cur.curr()); + rec_from.zero(); rec_to.zero(); + TToken_string fldlist = brw->get_input_field_names(); + TString80 str; + int fi = 0; + for (TString80 tok = inplist.get(fi); tok.not_empty(); tok = inplist.get(), fi++) + { + const TString16 fn = fldlist.get(fi); + const TFieldref fr(fn, 0); + if (*tok == '"') + { + str = tok; + str.ltrim(1); str.rtrim(1); + fr.write(str, rec_from); + fr.write(str, rec_to); + } + else + { + const short id = short(atoi(tok)); + if (sht.id2pos(id+delta) >= 0) + { + str = sht.get(id+delta); + if (str.not_empty()) + fr.write(str, rec_from); + str = sht.get(id+2*delta); + if (str.not_empty()) + fr.write(str, rec_to); + } + else + { + str = _mask->get(id); + fr.write(str, rec_from); + fr.write(str, rec_to); + } + } + } + + if (rec_from.empty() && rec_to.empty()) + { + sht.check(-1); + } + else + { + const long totit = cur.items(); + cur.freeze(TRUE); + cur.curr() = rec_from; + cur.read(); + while (cur.pos() < totit && cur.curr() <= rec_to) + { + sht.check(cur.pos()); + ++cur; + } + cur.freeze(FALSE); + } + } + else + { + keep_running = FALSE; + if (tasto == K_DEL && sht.checked() == 0) + { + error_box(TR("Non è stato selezionato nessun elemento")); + sht.select(0); + keep_running = TRUE; + } + } + } + sht.close_modal(); + + if (tasto == K_DEL) + { + long deleting = sht.checked(); + TString msg; + msg.format(FR("Confermare l'eliminazione di %d elementi"), deleting); + bool can_delete = delete_box(msg); + if (can_delete && deleting > 100) + { + msg.insert(TR("ATTENZIONE: "), 0); + can_delete = delete_box(msg); + } + if (can_delete) + { + TWait_cursor hourglass; + long skipped = 0; // Record non cancellati perche' protetti + cur.freeze(TRUE); // Congelo il cursore altrimenti si riaggiorna troppo + for (long pos = sht.items()-1; deleting > 0; pos--) + { + if (sht.checked(pos)) + { + cur = pos; + brw->do_output(); + bool can_delete = FALSE; + if (find(1)) + { + TRelation& r = *get_relation(); + _autodelete = 0x3; + if (!protected_record(r)) + { + if (modify_mode()) + { + r.restore_status(); + can_delete = remove(); + } + cur.freeze(false); + query_mode(); + cur.freeze(true); + } + _autodelete = FALSE; + } + if (!can_delete) + skipped++; + deleting--; + } + } + cur.freeze(FALSE); + set_limits(); // Riaggiorno il numero del primo/ultimo record + + if (skipped > 0) + { + warning_box(FR("%ld elementi non sono stati cancellati in quanto protetti."), skipped); + query_mode(); + } + } + } + } + else + { + if (search_mode()) + _autodelete = TRUE; + } + return TRUE; +} + +// @doc INTERNAL + +// @mfunc Controlla se una chiave e' completa ed esiste su file +// +// @rdesc Ritorna se la chave esiste sul file +bool TRelation_application::test_key( + word k, // @parm Chiave da ricercare + bool err) // @parm Indica se visualizzare eventuali errori occorsi +{ + bool onereq = false, onefill = false; + + for (TEditable_field* e = _mask->get_key_field(k, true); + e != NULL; + e = _mask->get_key_field(k, false)) + { + if (e->required() && e->shown()) + { + onereq = TRUE; + if (e->empty()) + { + if (err) + { + TString msg(80); + msg = TR("Manca un valore indispensabile per la ricerca."); +#ifdef DBG + msg << "\nChiave " << int(k) << " - Campo " << e->dlg(); + const TFieldref* fr = e->field(); + if (fr != NULL) + { + msg << " - " << fr->name(); + if (fr->to() > 0) + msg << '[' << fr->from() << ',' << fr->to() << ']'; + } +#endif + error_box(msg); + _mask->first_focus(-e->dlg()); + } + return FALSE; + } + } + else + /* if (k == 1 && !onereq && !onefill && c.get().not_empty()) */ + if (!onereq && !onefill && e->is_edit() && !e->empty()) + onefill = TRUE; + } + if (k == 1 && !onereq && !onefill) + { + if (err) + error_box(TR("Manca un valore indispensabile per la ricerca")); + return false; + } + return onefill || onereq; +} + +bool TRelation_application::find(word k) +{ + if (k == 0) + { + for (k = 1; k <= MAX_KEYS && !test_key(k, FALSE); k++); + if (k > MAX_KEYS) + return test_key(1, TRUE); + } + + TRelation& rel = *get_relation(); + TLocalisamfile& fil = rel.file(); + fil.setkey(k); + fil.zero(); + for (TEditable_field* e = _mask->get_key_field(k, true); e; e = _mask->get_key_field(k, false)) + { + if (e->shown()) // Ignora campi invisibili + e->autosave(rel); + } + + const int err = fil.read(_isequal); + return err == NOERR; +} + +void TRelation_application::edit_cancel() +{ + if (_mask->mode() == MODE_MOD) + { + TRelation* rel = get_relation(); + rel->restore_status(); + rel->lfile().reread(_unlock); // Unlock main file + } +} + +short TRelation_application::mask_field_dirty() const +{ + short id = 0; + if (_mask) + { + const int mode = _mask->mode(); + if (mode == MODE_QUERY) + { + FOR_EACH_MASK_FIELD(*_mask, i, f) + { + if (f->dirty() && f->active()) + { + id = f->dlg(); + break; + } + } + } + else + { + FOR_EACH_MASK_FIELD(*_mask, i, f) + { + if (f->dirty() && f->active() && f->field()) + { + if (id == 0) + id = f->dlg(); + if (f->dirty() > 1) // error on field content + { + id = f->dlg(); + break; + } + } + } + } + } + return id; +} + +bool TRelation_application::save(bool check_dirty) +{ + static bool was_dirty = false; + + int pos = _mask->id2pos(DLG_SAVEREC); + if (pos < 0 || !_mask->fld(pos).active()) + { + edit_cancel(); + return true; + } + + int err = NOERR; + const int mode = _mask->mode(); + if (check_dirty) + { + const short dirty = mask_field_dirty(); + + if (mode == MODE_QUERY) + { + const bool cont = !dirty || yesno_box(TR("Annullare i dati inseriti?")); + return cont; + } + + if (!dirty && !was_dirty) + { + edit_cancel(); + 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() > 1; + + KEY k; + if (errore) + { + if (annulla) + { + TString w; + TMask_field& df = _mask->field(dirty); + if (df.is_edit()) + w = ((TEdit_field&)df).get_warning(); + if (w.blank()) + { + w = df.prompt(); + if (!w.blank()) + { + w.trim(); + w << ' ' << TR("inconsistente."); + } + } + if (w.blank()) + w = TR("Campo inconsistente."); + w << '\n'; + switch (last) + { + case K_ESC: + w << TR("Si desidera annullare?"); break; + case K_QUIT: + w << TR("Si desidera uscire?"); break; + default: + w << TR("Si desidera 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(TR("Si desidera registrare?")); + + if (k == K_ESC || k == K_NO) + { + edit_cancel(); + was_dirty = false; + return k == K_NO; + } + + if (annulla) + { + TMask_field& ff = _mask->focus_field(); + if (ff.focusdirty() && ff.is_edit()) // I need simulate tab on the current field! + { + if (!ff.on_key(K_TAB)) + { + _mask->first_focus(-ff.dlg()); + was_dirty = true; + return false; + } + } + if (!_mask->check_fields()) // Exit with ESC didn't check values + { + // check_fields sets the focus on the blocking field + _mask->first_focus(-_mask->focus_field().dlg()); + was_dirty = true; + return false; + } + } + } + was_dirty = false; + + TWait_cursor hourglass; + 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); + } + + switch(err) + { + case NOERR: + _recins = get_relation()->lfile().recno(); + mask2mail(*_mask); + break; + case _isreinsert: + warning_box(TR("Esiste già un elemento con la stessa chiave")); + break; + case _isnowarning: + break; + default: + error_box(FR("Impossibile registrare i dati: errore %d"), err); + break; + } + return err == NOERR; +} + + +int TRelation_application::read(TMask& m) +{ + const TRelation &r = *get_relation(); + +/* Metodo VECCHIO! + const int max = m.fields(); + for (int i = 0; i < max; i++) + { + if (m.fld(i).is_sheet()) + { + TSheet_field& f = (TSheet_field&)m.fld(i); + if (f.record() && !f.external_record()) + f.record()->read(*f.putkey(r)); + } + } +*/ + if (m.sheets() > 0) // Metodo Salvatempo + { + FOR_EACH_MASK_SHEET(m, i, s) + { + if (s->record() && !s->external_record()) + s->record()->read(*s->putkey(r)); + } + } + + m.autoload(r); + return NOERR; +} + +int TRelation_application::write(const TMask& m) +{ + TRelation &r = *get_relation(); + m.autosave(r); + r.curr().set_creation_info(); + + // write relation and all independent sheets + int err = r.write(); + FOR_EACH_MASK_SHEET(m, i, s) + { + if (s->record() && !s->external_record()) + err |= s->record()->write(false); + } + + return err; +} + + +int TRelation_application::rewrite(const TMask& m) +{ + TRelation& r = *get_relation(); + m.autosave(r); + r.curr().set_modify_info(); + // rewrite relation and all independent sheets + r.rewrite(); + int err=r.status(); + + FOR_EACH_MASK_SHEET(m, i, s) + { + if (s->record() && !s->external_record()) + err |= s->record()->write(true); + } + + return err; +} + +const char* TRelation_application::record_description(const TRelation& r) const +{ return r.file().description(); } + +// @doc INTERNAL + +// @mfunc Cancella il record corrente +// +// @rdesc Ritorna se il record e' stato eliminato +bool TRelation_application::relation_remove() +// @comm Se la maschera e' in MODE_MOD non e' possibile cancellare il record e viene +// emesso un di errore. +{ + CHECK(_mask->edit_mode(), "You can call remove in edit mode only"); + + TRelation& r = *get_relation(); + r.restore_status(); + if (protected_record(r)) + return warning_box(FR("%s non eliminabile"), record_description(r)); + + if (_curr_transaction == TRANSACTION_DELETE || + delete_box(FR("Confermare eliminazione %s"), record_description(r))) + { + r.restore_status(); + const bool ok = remove(); + if (ok || is_transaction()) + set_limits(); + else + { + const int err = r.status(); + if (err != NOERR) // Succede nei remove con richiesta di conferma all'utente + return error_box(FR("Errore di cancellazione %d"), err); + } + } + return TRUE; +} + + +bool TRelation_application::protected_record(TRelation &r) +{ + if (user_can_delete(&r)) + return protected_record(r.curr()); + return true; +} + +bool TRelation_application::remove() +{ + int err = get_relation()->remove(); + if (err == NOERR) + { + const int maxf = _mask->fields(); + for (int i = 0; i < maxf; i++) + { + const TMask_field& mf = _mask->fld(i); + if (mf.is_sheet()) + { + TSheet_field& f = (TSheet_field&)mf; + if (f.record()&& !f.external_record()) + err |= f.record()->remove(); + } + } + } + if (err == NOERR) + { + _mask->set_mode(NO_MODE); + mask2mail(*_mask); + } + return err == NOERR; +} + +bool TRelation_application::firm_change_enabled() const +{ + bool ok = TApplication::firm_change_enabled(); + ok &= (_mask == NULL || _mask->query_mode()) && _lnflag == 0; + return ok; +} + +void TRelation_application::main_loop() +{ + KEY k; + do { + // ciclo delle transazioni + _recins = -1; + + // imposta la maschera in query mode + query_mode(); + _mask->open_modal(); + + // Provoca l'autopremimento per il messaggio di LINK + if (_lnflag) + { + if (_trans_counter < _ntransactions) + { + // la transazione è sul .ini : la imposta nelle variabili _curr_transaction... + if (load_transaction()) + { + // la transazione necessita di autopremimento + _autodelete = _curr_transaction == TRANSACTION_DELETE; + if (_curr_transaction == TRANSACTION_INSERT ) + _mask->send_key(K_CTRL+'N', 0); + else + _mask->send_key(K_AUTO_ENTER, 0); + } + } + else // la transazione non è sul .ini + { + _mask->send_key(K_AUTO_ENTER, 0); + } + } + + if (is_transaction()) + ini2query_mask(); + + do + { + const bool change = firm_change_enabled(); + // Dis/abilita cambio ditta + enable_menu_item(M_FILE_NEW, change); + + if (_mask->edit_mode()) + { + if (_autodelete) + { + const int pos = _mask->id2pos(DLG_DELREC); + if (pos >= 0 && _mask->fld(pos).active()) + _mask->send_key(K_CTRL+'E', 0); + else + error_box(TR("Elemento non eliminabile.")); + _autodelete = FALSE; + } + } + + if (_curr_trans_mode == TM_BATCH) + { + batch(); + k = _mask->check_mask(); + batch(false); + } + else + k = _mask->run(); + + switch (k) + { + case K_ESC: + if (save(TRUE)) + { + if (save_and_quit()) + k = K_QUIT; + else + { + edit_cancel(); // Novità 19-06-2012 + query_mode(); + } + } + break; + case K_QUIT: + if (!save(TRUE)) + k = K_ENTER; + break; + case K_F1: + dispatch_e_menu(M_HELP_CONTENTS); + break; + case K_F2: + dispatch_e_menu(M_FILE_ABOUT); + break; + case K_ENTER: + if (_lnflag && _curr_transaction != TRANSACTION_RUN) + { + if (find(1)) + { + if (_curr_transaction == TRANSACTION_INSERT) + _curr_transaction = TRANSACTION_MODIFY; + if (!modify_mode()) + k = K_QUIT; + } + else + { + if (_curr_transaction == TRANSACTION_MODIFY) + _curr_transaction = TRANSACTION_INSERT; + insert_mode(); + } + } + else + { + if (find(0)) + modify_mode(); + else + insert_mode(); + } + if (_curr_trans_mode == TM_AUTOMATIC || _curr_trans_mode == TM_BATCH) + _mask->send_key(K_CTRL+'R', 0); + break; + case K_SAVE: + if (save(FALSE)) + { + if (save_and_quit()) + { + k = K_QUIT; + } + else + { + if (save_and_new() && can_I_write(NULL)) + { + if (_mask->insert_mode()) + insert_mode(); + else + query_mode(); + } + else + { + const TMask_field & f = _mask->focus_field(); + + _mask->first_focus(-f.dlg(), false); + modify_mode(); + } + } + } + break; + case K_INS: + if (_mask->query_mode() || save(TRUE)) + { + const bool trovato = _mask->query_mode() && test_key(1, FALSE) && find(1); + if (trovato) + { + if (is_transaction()) + _curr_transaction=TRANSACTION_MODIFY; + else + warning_box(TR("Elemento gia' presente")); + modify_mode(); + } + else + insert_mode(); + } + if (_curr_trans_mode == TM_AUTOMATIC || _curr_trans_mode == TM_BATCH) + _mask->send_key(K_CTRL+'R', 0); + break; + case K_DEL: + if (_mask->query_mode()) + { + delete_mode(); + } + else + { + if (relation_remove()) + { + query_mode(); + if (_autoins_caller.not_empty() || is_transaction()) + { + if (_lnflag) _recins = 0; + k = K_QUIT; + } + } + } + break; + case K_F9: + if (_mask->query_mode() || 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: + { + TCursor* c = get_filtered_cursor(); + + if (!has_filtered_cursor() || c->curr().num() != file().curr().num()) + { + for (TEdit_field* e = (TEdit_field *) _mask->get_key_field(1, TRUE); e; e = (TEdit_field *) _mask->get_key_field(1, FALSE)) + { + if (e->is_kind_of(CLASS_EDIT_FIELD) && e->shown() && e->browse() != NULL) // Ignora campi invisibili o senza check + { + TCursor* b = e->browse()->cursor(); + + if (b && b->curr().num() == file().curr().num()) + { + c = b; + break; + } + } + } + } + + TCursor* cur = c ; + + if (c == NULL) + cur = new TCursor(get_relation()); + + err = file().reread(); + cur->curr() = file().curr(); + cur->read(); + ++(*cur); + while (cur->pos() < cur->items() && !can_I_read(cur->relation())) + ++(*cur); + file().curr() = cur->curr(); + if (can_I_read(cur->relation())) + err = get_relation()->read(_isequal, _testandlock); + if (c == NULL) + delete cur; + } + break; + case K_PREV: + { + TCursor* c = get_filtered_cursor(); + + if (!has_filtered_cursor() || c->curr().num() != file().curr().num()) + { + for (TEdit_field* e = (TEdit_field *) _mask->get_key_field(1, TRUE); e; e = (TEdit_field *) _mask->get_key_field(1, FALSE)) + { + if (e->is_kind_of(CLASS_EDIT_FIELD) && e->shown() && e->browse() != NULL) // Ignora campi invisibili o senza check + { + TCursor* b = e->browse()->cursor(); + + if (b && b->curr().num() == file().curr().num()) + { + c = b; + break; + } + } + } + } + + TCursor* cur = c ; + + if (c == NULL) + cur = new TCursor(get_relation()); + + file().reread(); + cur->curr() = file().curr(); + cur->read(); + --(*cur); + while (cur->pos() > 0 && !can_I_read(cur->relation())) + --(*cur); + file().curr() = cur->curr(); + if (can_I_read(cur->relation())) + err = get_relation()->read(_isequal, _testandlock); + if (c == NULL) + delete cur; + } + break; + case K_END: + err = file().readat(_last, _testandlock); + break; + default: + break; + } + if (err == NOERR || err == _islocked) + { + _navigating = true; + modify_mode(); + _navigating = false; + } + 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) + { + NFCHECK("Obsolete LINK message calling convention"); + TString16 num; + num.format("%ld", _recins); + TMessage msg(autoins_caller(), _lnflag ? MSG_LN : MSG_AI, num); + msg.send(); + } + + if (is_transaction()) + { + TConfig ini(_trans_ini.row(_trans_counter), "Transaction"); + ini.set("Record", _recins); + if (_recins >= 0) + { + ini.set("Result", "OK"); + ini.set("Error", "0"); + edit_mask2ini(); + } + else + { + const int err = get_relation()->status(); + ini.set("Result", err == NOERR ? "CANCEL" : "ERROR"); + ini.set("Error", err); + } + if (_curr_trans_mode == TM_BATCH) + { + TString_array & errs = errors(); + + FOR_EACH_ARRAY_ROW(errs, r, s) + ini.set("ErrMsg", *s, "Main", false, r); + + TString_array & warns = warnings(); + + FOR_EACH_ARRAY_ROW(warns, r1, s1) + ini.set("WarningMsg", *s1, "Main", false, r1); + } + + } + _trans_counter++; + } while ( _trans_counter < _ntransactions); +} + +bool TRelation_application::filter() +{ + if (parse_command_line()) + return true; + + 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 = _mask->efield(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, 0x2); + 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; + + TString str, tmp; + const char* v = body.get(); + 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)) + { + str = v; + tmp.format("%d=", f.dlg()); + str.insert(tmp, 0); + _fixed.add(str); + v = body.get(); + } + } + } + + mail.restart(); + msg = mail.next_s(MSG_ED); + if (msg) + { + TToken_string body(msg->body()); + const int key = body.get_int(); + + _autoins_caller = msg->from(); + _lnflag = 2; + + TAssoc_array field_values; + const char * s; + TString t, v; + + while((s = body.get()) != NULL) + { + t = s; + const int u = t.find('='); + + CHECKS(u > 0, "Invalid edit message ", (const char *) body); + if (u > 0) + { + v = t.mid(u + 1); + + t.cut(u); + field_values.add(t, v); + } + } + + for (int i = 0; i < _mask->fields(); i++) + { + TMask_field& f = _mask->fld(i); + const TFieldref * field = f.field(); + + if (field && f.in_key(key)) + { + TString16 field_name(field->name()); + const int from = field->from(); + const int to = field->to(); + + if (to >= 0) + field_name << "[" << (from + 1); + const TString * v = (const TString *) field_values.objptr(field_name); + + TString val; + if (v == NULL && to >= 0) + { + v = (const TString *)field_values.objptr(field->name()); + if (v) + val = v->sub(from, to); + } + else + if (v) val = *v; + + if (v && f.dlg() > 0) + { + t.format("%d=", f.dlg()); + val.insert(t, 0); + _fixed.add(val); + } + } + } + } + + 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(); + + TString16 tmp; + 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)) + { + TString s(v); + tmp.format("%d=", f.dlg()); + s.insert(tmp, 0); + _fixed.add(s); + v = body.get(); + } + } +} + + +bool TRelation_application::parse_command_line() +{ + _trans_ini.destroy(); + _trans_counter=0; + _curr_transaction = ""; + _curr_trans_mode = 'I'; + + TFilename ini; + for (int i = argc()-1; i > 0; i--) + { + ini = argv(i); + if ((ini[0] == '-' || ini[0] == '/') && (ini[1] == 'I' || ini[1] == 'i')) + { + ini.ltrim(2); + if (ini.starts_with("=")) + ini.ltrim(1); + CHECK(!ini.blank(),"Manca l'indicazione della transazione. Il nome va indicato di seguito al -i, senza interporre spaziatura."); + if (ini.find('*')>=0) + { + // metachars: + list_files(ini, _trans_ini); + } + else + { + if (ini.exist()) + _trans_ini.add(ini); + else + cantread_box(ini); + } + break; + } + } + + _ntransactions= _trans_ini.items(); + + _lnflag = _ntransactions>0; + return _lnflag != 0; +} + +// il valore di ritorno indica se attivare l'"automagia": +// spedizione dei tasti e precaricamento della maschera +bool TRelation_application::load_transaction() +{ + bool retv = FALSE; + if (_trans_counter < _ntransactions) + { + TConfig cnf(_trans_ini.row(_trans_counter), "Transaction"); + _curr_transaction = cnf.get("Action"); + _curr_transaction.upper(); + _curr_trans_mode = toupper(cnf.get("Mode")[0]); + _curr_trans_from = cnf.get("From"); + const long firm = cnf.get_long("Firm"); + if (firm > 0) + { + bool ok = set_firm(firm); + if (ok) + _mask->on_firm_change(); + else + error_box(FR("La ditta %ld non esiste"), firm); + } + if (_curr_transaction == TRANSACTION_RUN) + retv = false; // Ho gia' finito qui: basta il cambio ditta + else + retv = true; // Attiva automagia + } + return retv; +} + +void TRelation_application::on_firm_change() +{ + TApplication::on_firm_change(); + if (_mask != NULL) + { + set_limits(0x3); + } +} + +void TRelation_application::ini2query_mask() +{ + if (is_transaction()) + { + TString8 n; n.format("%d", get_relation()->lfile().num()); + TConfig ini(_trans_ini.row(_trans_counter), n); + ini2mask(ini, *_mask, TRUE); + } +} + +void TRelation_application::ini2insert_mask() +{ + if (is_transaction()) + { + TString8 n; n.format("%d", get_relation()->lfile().num()); + TConfig ini(_trans_ini.row(_trans_counter), n); + ini2mask(ini, *_mask, FALSE); + } +} + +void TRelation_application::ini2mask(TConfig& ini, TMask& m, bool query) +{ + const TString16 defpar = ini.get_paragraph(); + TString tmp; + + _fixed.cut(0); + for (int f = m.fields()-1; f >= 0; f--) + { + TMask_field& campo = m.fld(f); + const TFieldref* fref = campo.field(); + if (fref) + { + if (!query || campo.in_key(0)) + { + const TString& str = fref->read(ini, defpar); + if (str.not_empty()) + { + campo.set(str); + if (query) + { + tmp.format("%d=%s", campo.dlg(), (const char *) str); + _fixed.add(tmp); + } + } + } + } + else + { + if (!query && campo.is_sheet()) + { + TSheet_field &sheet=(TSheet_field &)campo; + ini2sheet(ini, sheet); + } + } + } + ini.set_paragraph(defpar); + if (query) + set_fixed(); +} + +void TRelation_application::edit_mask2ini() +{ + const TString& str = _trans_ini.row(_trans_counter); + if (str.full()) + { + TString8 head; head.format("%d", get_relation()->lfile().num()); + TConfig ini(str, head); + mask2ini(*_mask, ini); + } +} + + +void TRelation_application::ini2sheet(TConfig& ini,TSheet_field &sheet) +{ + if (sheet.record() != NULL) + { + const int lognum = sheet.record()->logic_num(); + const TMask& sm = sheet.sheet_mask(); + + // scrive le righe nello sheet associato + TString16 defpar; + + for (int r = 1; ;r++) + { + defpar.format("%d,%d", lognum, r); + if (ini.set_paragraph(defpar)) + { + TToken_string& row = sheet.row(r-1); + for (int sf = sm.fields()-1; sf >= 0; sf--) + { + TMask_field& campo = sm.fld(sf); + const TFieldref* fref = campo.field(); + if (fref) + { + const TString& str = fref->read(ini, defpar); + row.add(str, sheet.cid2index(campo.dlg())); + } + } + sheet.check_row(r-1); + } + else + break; + } + } +} + +void TRelation_application::sheet2ini(TSheet_field &sheet,TConfig& ini) +{ + if (sheet.record() != NULL) + { + const int lognum = sheet.record()->logic_num(); + const TMask& sm = sheet.sheet_mask(); + + // scrive le righe degli sheet associati + TString16 defpar; + TString str; + int r; + + for (r = 1 ; r <= sheet.items(); r++) + { + defpar.format("%d,%d", lognum, r); + + TMask_field* fkey; + sheet.restart_key(); + while ((fkey = sheet.get_key(str))) + { + ini.set(str, fkey->get(), defpar); + } + + TToken_string& row = sheet.row(r-1); + const char* value; + int i; + for (i = 0, value = row.get(0); value; i++, value = row.get()) + { + const TMask_field& campo = sm.field(FIRST_FIELD+i); + const TFieldref* fr = campo.field(); + if (fr) + { + if (value == NULL || *value == '\0') + value = " "; + // ini.set(fr->name(), value, defpar); + fr->write(ini, defpar, value); + } + } + } + for (r = sheet.items()+1; ; r++) + { + defpar.format("%d,%d", lognum, r); + if (ini.set_paragraph(defpar)) + ini.remove_all(); + else + break; + } + } +} + +void TRelation_application::mask2ini(const TMask& m, TConfig& ini) +{ + ini.set("Firm", get_firm(), "Transaction"); + ini.set("User", user()); + ini.set("HostName", get_hostname()); + + int year, release, tag, patch; + if (get_version_info(year, release, tag, patch)) + { + TString80 ver; + ver.format("%d %d.%d-%d", year, release, tag, patch); + ini.set("Version", ver); + } + + const TLocalisamfile& lfile = get_relation()->lfile(); + + TString16 defpar; + defpar.format("%d", lfile.num()); + ini.set_paragraph(defpar); + switch (lfile.num()) + { + case LF_TAB: + case LF_TABCOM: + case LF_TABGEN: + { + const TString& tabname = lfile.curr().get("COD"); + ini.set("COD", tabname, defpar); + } + break; + } + for (int f = 0; f < m.fields(); f++) + { + TMask_field& campo = m.fld(f); + if (campo.shown()) + { + const TFieldref* fr = campo.field(); + if (fr) + { + if (campo.empty()) + fr->write(ini, defpar, " "); + else + { + if (campo.class_id() == CLASS_DATE_FIELD && campo.right_justified()) + { + const TDate d(campo.get()); + fr->write(ini, defpar, d.string(ANSI)); + } + else + fr->write(ini, defpar, campo.get()); + } + } + else + if (campo.is_sheet()) + { + TSheet_field &sheet=(TSheet_field &)campo; + sheet2ini(sheet,ini); // It's virtual + } + } + } + ini.set_paragraph(defpar); // Reimposta paragrafo standard +} + +bool TRelation_application::mask2mail(const TMask& m) +{ + TWait_cursor hourglass; + bool ok = _curr_trans_from.empty() && ::can_dispatch_transaction(get_relation()->curr()); + if (ok) + { + TFilename ininame; ininame.temp("msg", "ini"); + if (ok) // Test qualunque per usare {} + { + TConfig ini(ininame, "Transaction"); + const char* action = ""; + char mode[2] = { TM_AUTOMATIC, '\0' }; + switch (m.mode()) + { + case NO_MODE: + action = TRANSACTION_DELETE; + break; + case MODE_MOD: + action = TRANSACTION_MODIFY; + break; + default: + action = TRANSACTION_INSERT; + break; + } + ini.set("Action", action); + ini.set("Mode", mode); + mask2ini(m, ini); + } + ok = ::dispatch_transaction(get_relation()->curr(), ininame); + xvt_fsys_remove_file(ininame); + } + return ok; +} diff --git a/src/include/textset.h b/src/include/textset.h index 09a1d2812..00b68136f 100755 --- a/src/include/textset.h +++ b/src/include/textset.h @@ -79,9 +79,6 @@ public: virtual const TVariant& get(unsigned int column) const; virtual TRecnotype new_rec(const char* buf = NULL); virtual bool set(unsigned int fld, const TVariant& var); - virtual bool set(const char* fld, const TVariant& var) { return TText_recordset::set(fld, var); } - virtual bool set(const char* fld, const char * s) { const TVariant var(s); return TText_recordset::set(fld, var); } - virtual bool set(const char* fld, const TString & s) { const TVariant var(s); return TText_recordset::set(fld, var); } virtual void destroy_column(const int ncol = -1, bool pack = true) { _trc.destroy(ncol, pack); } virtual void create_column(const char * name, TFieldtypes type = _alfafld); virtual bool load_file(const TFilename& n); diff --git a/src/include/tokens.h b/src/include/tokens.h index a55043156..c01af24ac 100755 --- a/src/include/tokens.h +++ b/src/include/tokens.h @@ -53,6 +53,3 @@ #define VALIDATE VA #define WARNING WA #define ZOOM ZO - -// leave a newline at the end - diff --git a/src/include/uml.h b/src/include/uml.h index 9b2328641..26e949121 100755 --- a/src/include/uml.h +++ b/src/include/uml.h @@ -8,5 +8,3 @@ #undef min #undef max - -// leave a newline at the end diff --git a/src/include/urldefid.h b/src/include/urldefid.h index 80f2c5bb8..098ab4486 100755 --- a/src/include/urldefid.h +++ b/src/include/urldefid.h @@ -209,4 +209,4 @@ #endif -// leave a newline at the end +/* @END */ \ No newline at end of file diff --git a/src/include/xml.cpp b/src/include/xml.cpp index 98e7c13ef..932aa8825 100755 --- a/src/include/xml.cpp +++ b/src/include/xml.cpp @@ -518,11 +518,7 @@ void TXmlItem::AsString(TString& str) const { char* buf = str.get_buffer(nSize); memset(buf, 0, nSize); -#ifdef WIN32 ostrstream outf(buf, nSize); -#else - ostringstream outf(buf); -#endif Write(outf, 0); if (buf[nSize-1] == '\0')