diff --git a/src/include/applicat.cpp b/src/include/applicat.cpp index f420d7fbc..ed120e92b 100755 --- a/src/include/applicat.cpp +++ b/src/include/applicat.cpp @@ -136,6 +136,8 @@ long TApplication::task_eh(WINDOW win, EVENT *ep) { // Setta il vero menu principale se diverso dal default const int meno = _application->argc() > 1 ? atoi(_application->argv(1)+1) : 0; + + xvt_vobj_hide(win); ignore_xvt_errors(TRUE); MENU_ITEM* menu = xvt_res_get_menu(MENU_BAR_ID(meno)); ignore_xvt_errors(FALSE); @@ -187,6 +189,10 @@ long TApplication::handler(WINDOW win, EVENT* ep) _create_ok = create(); if (_create_ok) { + if (task_win_shown()) + xvt_vobj_show(TASK_WIN); + if (task_win_iconized()) + xvt_vobj_minimize(TASK_WIN); on_firm_change(); on_config_change(); return 1; @@ -296,12 +302,11 @@ 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); @@ -316,15 +321,13 @@ bool TApplication::remove_menu(MENU_TAG id) TApplication::TApplication() - : _god_vars(NULL),_savefirm(0), _running(FALSE), _create_ok(FALSE) + : _god_vars(nullptr),_savefirm(0), _running(false), _create_ok(false), _force(false) { } - TApplication::~TApplication() { - if (_god_vars != NULL) - delete _god_vars; + SAFE_DELETE(_god_vars); } bool TApplication::create() @@ -341,7 +344,8 @@ void TApplication::terminate() if (_create_ok) destroy(); // Distruzione files e maschere - do_events(); + if(!_force) + do_events(); if (use_files()) { @@ -371,7 +375,8 @@ const char* TApplication::get_module_name() const const TDongle& d = dongle(); const TString4 modname = _name.left(2); word aut = d.module_name2code(modname); - if (aut == 0xFFFF && modname == "ps") + + if (aut == 0xFFFF && modname == "ps") { aut = 0; module = TR("Personalizzazioni"); @@ -404,19 +409,12 @@ const char* TApplication::get_module_name() const } } } - if (!ok) - { - if(is_power_station()) - { - warning_box("Attenzione! Non sei abilitato per l'utilizzo del modulo %s", static_cast(module)); - } - else - { - cantaccess_box(module); - module.cut(0); - } - } - } + if (!ok && !is_power_station()) + { + cantaccess_box(module); + module.cut(0); + } + } } return module; } @@ -769,7 +767,7 @@ void TApplication::open_files(int logicnum, ...) va_start(marker, logicnum); while (logicnum >= LF_USER && logicnum < LF_EXTERNAL) { - if (_used_files.objptr(logicnum) == NULL) + if (_used_files.objptr(logicnum) == nullptr) _used_files.add(new TLocalisamfile(logicnum), logicnum); logicnum = va_arg(marker, int); } @@ -880,9 +878,8 @@ bool TApplication::get_next_mail(TToken_string& to, TToken_string& cc, TToken_st bool TSkeleton_application::create() { -// dispatch_e_menu(BAR_ITEM_ID(1)); -// return TApplication::create(); const bool ok = TApplication::create(); + if (ok) dispatch_e_menu(BAR_ITEM_ID(1)); return ok; } diff --git a/src/include/applicat.h b/src/include/applicat.h index f2a0695f2..8e46d4be1 100755 --- a/src/include/applicat.h +++ b/src/include/applicat.h @@ -1,4 +1,3 @@ -#pragma once #ifndef __APPLICATION_H #define __APPLICATION_H @@ -51,6 +50,9 @@ class TApplication // @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; @@ -59,7 +61,7 @@ class TApplication // @cmember:(INTERNAL) Termine dell'applicazione void terminate(); - + // @access Protected Member protected: // @cmember Ritorna il nome del modulo dell'applicazione @@ -101,7 +103,7 @@ protected: void open_files(int logicnum, ...); // @cmember Percorso documenti archiviati - bool get_spotlite_path(TFilename& path) const; + bool get_spotlite_path(TFilename& path) const; // @access Public Member public: @@ -135,6 +137,8 @@ public: // @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); @@ -188,6 +192,10 @@ public: 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 imposta la visibità della finestra principale + virtual bool task_win_shown() const { return true; } + // @cmember imposta la riduzione a icona della finestra principale + virtual bool task_win_iconized() const { return false; } // @cmember Costruttore TApplication(); diff --git a/src/include/array.h b/src/include/array.h index 8a9deb63c..0e48db804 100755 --- a/src/include/array.h +++ b/src/include/array.h @@ -230,7 +230,7 @@ TArray& objptr2array(TObject* obj); class TToken_string; #endif -#define STRING_TOKEN(obj) (obj == nullptr ? EMPTY_STRING : *(TToken_string *) obj) +#define STRING_TOKEN(obj) ((TToken_string &)(obj == nullptr ? EMPTY_STRING : *(TToken_string *) obj)) // @doc EXTERNAL diff --git a/src/include/assoc.cpp b/src/include/assoc.cpp index 03c33a441..1c46ecace 100755 --- a/src/include/assoc.cpp +++ b/src/include/assoc.cpp @@ -1,19 +1,25 @@ #include #include +#include // @ccost:(INTERNAL) HASH_SIZE | 883 | Dimensione della tabella hash const int HASH_SIZE = 883; THash_object::~THash_object() { - if (_obj != NULL) - delete _obj; + safe_delete(_obj); } +// @doc EXTERNAL + +// @class TAssoc_array | Tabella hash di oggetti generici +// +// @base public |TObject + TArray& TAssoc_array::bucket(int index) { TArray* arr = (TArray*)_bucket.objptr(index); - if (arr == NULL) + if (arr == nullptr) { arr = new TArray; _bucket.add(arr, index); @@ -41,7 +47,7 @@ THash_object* TAssoc_array::_lookup( const TFixed_string key(k); const word hv = key.hash() % HASH_SIZE; TArray& arr = bucket(hv); - THash_object* o = NULL; + THash_object* o = nullptr; isnew = false; int i; @@ -54,7 +60,7 @@ THash_object* TAssoc_array::_lookup( break; } - if (o == NULL) + if (o == nullptr) { if (insert) { @@ -85,7 +91,7 @@ TObject* TAssoc_array::last_item() { _rowitem = _bucket.last(); if( _rowitem < 0 ) - return NULL; + return nullptr; _colitem = bucket(_rowitem).items() - 1; return pred_item( ); } @@ -105,9 +111,9 @@ TObject* TAssoc_array::succ_item() } } if (_rowitem >= HASH_SIZE) - return NULL; + return nullptr; THash_object* o = (THash_object*)arr->objptr(_colitem++); - return (o == NULL || o->_obj == NULL) ? NULL : o->_obj; + return (o == nullptr || o->_obj == nullptr) ? nullptr : o->_obj; } TObject* TAssoc_array::pred_item() @@ -125,28 +131,28 @@ TObject* TAssoc_array::pred_item() } } if (_rowitem < 0 ) - return NULL; + return nullptr; THash_object* o = (THash_object*)arr->objptr(_colitem--); - return (o == NULL || o->_obj == NULL) ? NULL : o->_obj; + return (o == nullptr || o->_obj == nullptr) ? nullptr : o->_obj; } THash_object* TAssoc_array::random_hash_object() { - THash_object* o = NULL; + THash_object* o = nullptr; if (items() > 0) { int bucket = rand() % _bucket.size(); - if (_bucket.objptr(bucket) == NULL) + if (_bucket.objptr(bucket) == nullptr) bucket = _bucket.succ(bucket); - if (_bucket.objptr(bucket) == NULL) + if (_bucket.objptr(bucket) == nullptr) bucket = _bucket.pred(bucket); const TArray* arr = (const TArray*)_bucket.objptr(bucket); - if (arr != NULL) + if (arr != nullptr) { const int item = rand() % arr->size(); o = (THash_object*)arr->objptr(item); - if (o != NULL) + if (o != nullptr) { _rowitem = bucket; _colitem = item; @@ -162,7 +168,7 @@ THash_object* TAssoc_array::random_hash_object() // @rdesc Ritorna TRUE se esisteva gia' un elemento con la stessa chiave bool TAssoc_array::add( const char* key, // @parm Chiave d'ordinamento - TObject* obj, // @parm Oggetto da inserire (default=NULL) + TObject* obj, // @parm Oggetto da inserire (default=nullptr) bool force) // @parm Permette di forzare l'inserimento se esiste gia' // un oggetto con la stessa chiave @@ -185,7 +191,7 @@ bool TAssoc_array::add( { if (force) { - if (o->_obj != NULL) + if (o->_obj != nullptr) delete o->_obj; o->_obj = obj; } @@ -197,6 +203,27 @@ bool TAssoc_array::add( return false; } +bool TAssoc_array::add(const char* key, // @parm Chiave d'ordinamento + const char * str, // @parm stringa da inserire + bool force) // @parm Permette di forzare l'inserimento se esiste gia' +{ + bool isnew = false; + THash_object* o = _lookup(key, isnew, true); + + if (!isnew) + { + if (force) + { + if (o->_obj != nullptr) + delete o->_obj; + o->_obj = new TString(str); + } + return true; + } + o->_obj = new TString(str); + return false; +} + bool TAssoc_array::add(const char* key, const TObject& obj, bool force) { /* @@ -216,7 +243,7 @@ bool TAssoc_array::add(const char* key, const TObject& obj, bool force) } if (force && o->_obj != &obj) // Tolla 2017: Aggiunto controllo sugli indirizzi, perchè c'è questo problema? { - if (o->_obj != NULL) + if (o->_obj != nullptr) delete o->_obj; o->_obj = obj.dup(); } @@ -239,7 +266,7 @@ bool TAssoc_array::remove( const TFixed_string key(k); const word hv = key.hash() % HASH_SIZE; TArray& arr = bucket(hv); - THash_object* o = NULL; + THash_object* o = nullptr; int i; for (i = 0; i < arr.items(); i++) @@ -250,7 +277,7 @@ bool TAssoc_array::remove( if (ob->_key > key) break; } - if (o != NULL) + if (o != nullptr) { arr.destroy(i,TRUE); _cnt--; @@ -280,13 +307,13 @@ TObject& TAssoc_array::find( // @doc EXTERNAL // @mfunc Ritorna l'oggetto con chiave

-// @rdesc Se l'oggetto esiste ne ritorna il puntatore, altrimenti ritorna NULL +// @rdesc Se l'oggetto esiste ne ritorna il puntatore, altrimenti ritorna nullptr TObject* TAssoc_array::objptr( const char* key) const // @parm Chiave dell'oggetto da ritornare { bool isnew = false; THash_object* o = ((TAssoc_array*)this)->_lookup(key,isnew); - return o ? o->_obj : NULL; + return o ? o->_obj : nullptr; } // @doc EXTERNAL @@ -302,14 +329,14 @@ bool TAssoc_array::is_key( { bool isnew = FALSE; THash_object* o = ((TAssoc_array *)this)->_lookup(key,isnew); - return o != NULL; + return o != nullptr; } // @doc EXTERNAL // @mfunc Ritorna solo l'oggetto // -// @rdesc Ritorna il puntatore all'oggetto (se diverso da NULL), altrimenti +// @rdesc Ritorna il puntatore all'oggetto (se diverso da nullptr), altrimenti // ritorna error object TObject* TAssoc_array::get() // @xref @@ -326,17 +353,17 @@ TObject* TAssoc_array::get() if (_row >= HASH_SIZE) { _row = 0; - return NULL; + return nullptr; } THash_object* o = (THash_object*)arr->objptr(_col++); - return (o == NULL || o->_obj == NULL) ? &error_object : o->_obj; + return (o == nullptr || o->_obj == nullptr) ? &error_object : o->_obj; } // @doc EXTERNAL // @mfunc Ritorna l'oggetto e la relativa chiave // -// @rdesc Se l'oggetto esiste ne ritorna il puntatore, altrimenti ritorna NULL +// @rdesc Se l'oggetto esiste ne ritorna il puntatore, altrimenti ritorna nullptr THash_object* TAssoc_array::get_hashobj() // @comm Se l'oggetto viene trovato viene richiamata la funzione @@ -356,7 +383,7 @@ THash_object* TAssoc_array::get_hashobj() if (_row >= HASH_SIZE) { _row = 0; - return NULL; + return nullptr; } return (THash_object*)arr->objptr(_col++); } @@ -368,11 +395,13 @@ int TAssoc_array::get_keys(TString_array& kl, bool add_values) { kl.destroy(); restart(); - THash_object* o = NULL; + THash_object* o = nullptr; TString tmp(80); + while ((o = get_hashobj())) { TToken_string* tt = new TToken_string(o->key()); + if (add_values) { tmp = ""; @@ -389,7 +418,7 @@ const TString& TAssoc_array::get_str(const char* key) const { bool isnew = false; THash_object* o = ((TAssoc_array *)this)->_lookup(key,isnew); - if (o != NULL && o->obj().is_kind_of(CLASS_STRING)) + if (o != nullptr && o->obj().is_kind_of(CLASS_STRING)) return (const TString&)o->obj(); return EMPTY_STRING; } @@ -397,7 +426,7 @@ const TString& TAssoc_array::get_str(const char* key) const bool TAssoc_array::get_bool(const char* key) const { const TString& str = get_str(key); - return str.full() && strchr("1XY", str[0]) != NULL; + return str.full() && strchr("1XY", str[0]) != nullptr; } int TAssoc_array::get_int(const char* key) const @@ -442,17 +471,18 @@ TObject* TCache::objptr(const TString& key) { const int hv = key.hash() % _data.size(); THash_object* ho = (THash_object*)_data.objptr(hv); - TObject* obj = NULL; - if (ho != NULL && ho->key() == key) + TObject* obj = nullptr; + + if (ho != nullptr && ho->key() == key) { obj = &ho->obj(); } else { obj = key2obj(key); - if (obj != NULL) + if (obj != nullptr) { - if (ho != NULL) + if (ho != nullptr) { discarding(ho); _data.destroy(hv); diff --git a/src/include/assoc.h b/src/include/assoc.h index 4d2861174..5e78455c1 100755 --- a/src/include/assoc.h +++ b/src/include/assoc.h @@ -14,6 +14,7 @@ // @class THash_object | Classe per la definizione degli elementi di una tabella hash. // // @base public | TObject + class THash_object : public TObject // @author:(INTERNAL) Villa { @@ -37,10 +38,10 @@ public: TObject& obj() const { return *_obj; } - TObject* remove_obj() { TObject* o = _obj; _obj = NULL; return o; } + TObject* remove_obj() { TObject* o = _obj; _obj = nullptr; return o; } // @cmember Costruttore (inizializza la chiave ed opzionalmente l'oggetto) - THash_object(const char* k, TObject* o = NULL) : _key(k), _obj(o) + THash_object(const char* k, TObject* o = nullptr) : _key(k), _obj(o) {} // @cmember Distruttore virtual ~THash_object(); @@ -109,6 +110,9 @@ public: // @cmember Aggiunge una copia dell'oggetto bool add(const char* key, const TObject& obj, bool force = false); + // @cmember Aggiunge una stringa. Se era gia' presente guarda il parametro force + bool add(const char* key, const char * str, bool force = false); + // @cmember Elimina un oggetto bool remove(const char* key); diff --git a/src/include/bagn010.uml b/src/include/bagn010.uml index 585d5f6ae..6212fb1f5 100644 --- a/src/include/bagn010.uml +++ b/src/include/bagn010.uml @@ -41,7 +41,7 @@ END STRING F_KEYFIELD2 30 BEGIN - PROMPT 42 2 "Campo 2 " + PROMPT 44 2 "Campo 2 " FLAGS "D" END @@ -53,7 +53,7 @@ END STRING F_KEYFIELD4 30 BEGIN - PROMPT 42 3 "Campo 4 " + PROMPT 44 3 "Campo 4 " FLAGS "D" END @@ -65,7 +65,7 @@ END STRING F_KEYFIELD6 30 BEGIN - PROMPT 42 4 "Campo 6 " + PROMPT 44 4 "Campo 6 " FLAGS "D" END @@ -77,7 +77,7 @@ END STRING F_KEYFIELD8 30 BEGIN - PROMPT 42 5 "Campo 8 " + PROMPT 44 5 "Campo 8 " FLAGS "D" END @@ -89,7 +89,7 @@ END STRING F_KEYFIELD10 30 BEGIN - PROMPT 42 6 "Campo 10 " + PROMPT 44 6 "Campo 10 " FLAGS "D" END @@ -101,7 +101,7 @@ END STRING F_KEYFIELD12 30 BEGIN - PROMPT 42 7 "Campo 12 " + PROMPT 44 7 "Campo 12 " FLAGS "D" END @@ -113,7 +113,7 @@ END STRING F_KEYFIELD14 30 BEGIN - PROMPT 42 8 "Campo 14 " + PROMPT 44 8 "Campo 14 " FLAGS "D" END @@ -125,7 +125,7 @@ END STRING F_KEYFIELD16 30 BEGIN - PROMPT 42 9 "Campo 16 " + PROMPT 44 9 "Campo 16 " FLAGS "D" END @@ -137,7 +137,7 @@ END STRING F_KEYFIELD18 30 BEGIN - PROMPT 42 10 "Campo 18 " + PROMPT 44 10 "Campo 18 " FLAGS "D" END @@ -149,7 +149,7 @@ END STRING F_KEYFIELD20 30 BEGIN - PROMPT 42 11 "Campo 20 " + PROMPT 44 11 "Campo 20 " FLAGS "D" END diff --git a/src/include/checks.cpp b/src/include/checks.cpp index 1d37258a2..8a540a34c 100755 --- a/src/include/checks.cpp +++ b/src/include/checks.cpp @@ -52,7 +52,10 @@ bool fatal_box( { buildmsg(); if (__batch) - __errors.add(msg); + { + if (__errors.find(msg) < 0) + __errors.add(msg); + } else xvt_dm_post_fatal_exit(msg); return false; @@ -69,7 +72,10 @@ bool error_box( { buildmsg(); if (__batch) - __errors.add(msg); + { + if (__errors.find(msg) < 0) + __errors.add(msg); + } else xvt_dm_post_error(msg); return false; @@ -85,7 +91,10 @@ bool warning_box( { buildmsg(); if (__batch) - __warnings.add(msg); + { + if (__warnings.find(msg) < 0) + __warnings.add(msg); + } else xvt_dm_post_warning(msg); return 0; @@ -117,7 +126,10 @@ bool message_box( { buildmsg(); if (__batch) - __warnings.add(msg); + { + if (__warnings.find(msg) < 0) + __warnings.add(msg); + } else xvt_dm_post_message(msg); return false; @@ -133,7 +145,10 @@ bool sorry_box( { buildmsg(); if (__batch) - __warnings.add(msg); + { + if (__warnings.find(msg) < 0) + __warnings.add(msg); + } else xvt_dm_post_note(msg); return false; @@ -147,7 +162,8 @@ bool noyes_box( buildmsg(); if (__batch) { - __errors.add(msg); + if (__errors.find(msg) < 0) + __errors.add(msg); return true; } ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", NULL, msg); @@ -162,7 +178,8 @@ int noyesall_box( buildmsg(); if (__batch) { - __errors.add(msg); + if (__errors.find(msg) < 0) + __errors.add(msg); return K_NO; } ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", "Si Tutti", msg); @@ -180,7 +197,8 @@ int custom_box( buildmsg(); if (__batch) { - __errors.add(msg); + if (__errors.find(msg) < 0) + __errors.add(msg); return K_NO; } ASK_RESPONSE r = xvt_dm_post_ask(buttons, buttonc, buttond, msg); @@ -203,7 +221,8 @@ bool yesno_box( buildmsg(); if (__batch) { - __errors.add(msg); + if (__errors.find(msg) < 0) + __errors.add(msg); return false; } ASK_RESPONSE r = xvt_dm_post_ask("Si", "No", NULL, msg); @@ -218,7 +237,8 @@ int yesnoall_box( buildmsg(); if (__batch) { - __errors.add(msg); + if (__errors.find(msg) < 0) + __errors.add(msg); return K_NO; } ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", "No Tutti", msg); @@ -277,7 +297,8 @@ int yesnocancel_box( buildmsg(); if (__batch) { - __errors.add(msg); + if (__errors.find(msg) < 0) + __errors.add(msg); return K_NO; } ASK_RESPONSE r = xvt_dm_post_ask("Si", "No", "Annulla", msg); diff --git a/src/include/classes.h b/src/include/classes.h index d1bac02dc..027a08065 100755 --- a/src/include/classes.h +++ b/src/include/classes.h @@ -25,6 +25,7 @@ #define CLASS_CONTAINER 100 #define CLASS_ARRAY 101 #define CLASS_STACK 102 +#define CLASS_INDEXED_ARRAY 103 #define CLASS_WINDOW 200 #define CLASS_SHEET 201 diff --git a/src/include/config.cpp b/src/include/config.cpp index 82110982e..efc479018 100755 --- a/src/include/config.cpp +++ b/src/include/config.cpp @@ -255,17 +255,40 @@ bool TConfig::exist( // @flag TRUE | Se la variabile esiteva // @flag FALSE | Se la variabile non esiteva bool TConfig::remove( - const char* var, // @parm Nome della variabile - int index) // @parm Indice dell'elemento dell'array (default -1) + const char* var, // @parm Nome della variabile + int index) // @parm Indice dell'elemento dell'array (default -1) // @comm Se

e' = 0 viene costruito il nome dell'elemento // dell'array da cercare, diversamente viene cercata la variabile // normale passata in

. { - const char* key = get_varkey(var, index); - const bool ok = _data.remove(key); - if (ok) _dirty = true; - return ok; + const char* key = get_varkey(var, index); + const bool ok = _data.remove(key); + if (ok) _dirty = true; + return ok; +} + +// @mfunc Elimina una variabile dal paragrafo section +// +// @rdesc Ritorna i seguenti valori: +// +// @flag TRUE | Se la variabile esiteva +// @flag FALSE | Se la variabile non esiteva +bool TConfig::remove( + const char* var, // @parm Nome della variabile + const char* section, // @parm Sezione della variabile + int index) // @parm Indice dell'elemento dell'array (default -1) + +// @comm Se

e' = 0 viene costruito il nome dell'elemento +// dell'array da cercare, diversamente viene cercata la variabile +// normale passata in

. +{ + if (section && *section) // Cambia paragrafo se necessario + set_paragraph(section); + const char* key = get_varkey(var, index); + const bool ok = _data.remove(key); + if (ok) _dirty = true; + return ok; } // @doc EXTERNAL @@ -972,9 +995,14 @@ bool ini_set_string(const char* file, const char* paragraph, const char* name, c bool ini_remove(const char* file, const char* para, const char* name, int idx) { - TConfig c(file,para); +#ifndef DIRECT + DECLARE_VARNAME(name, idx); + return xvt_sys_remove_profile_string(file, para, varname) != 0; +#else + TConfig c(file, para); return c.remove(name, idx); +#endif } bool ini_get_bool(const char* file, const char* para, const char* name, bool defval, int idx) diff --git a/src/include/config.h b/src/include/config.h index 15a410d0f..ea98da7c6 100755 --- a/src/include/config.h +++ b/src/include/config.h @@ -128,6 +128,9 @@ public: // @cmember Elimina una variabile nel paragrafo attivo bool remove(const char* var, int index = -1); + // @cmember Elimina una variabile nel paragrafo attivo + bool remove(const char* var, const char * section, int index = -1); + // @cmember Elimina una array di variabili nel paragrafo attivo bool remove_array(const char* var); diff --git a/src/include/currency.cpp b/src/include/currency.cpp index b3675a3a2..a2b5c0c40 100755 --- a/src/include/currency.cpp +++ b/src/include/currency.cpp @@ -86,7 +86,6 @@ TObject* TDowJones::rec2obj(const TRectype& rec) const data->_chg = UNO; } } - if (codval.full()) { data->_dec = rec.get_int("I0"); diff --git a/src/include/date.cpp b/src/include/date.cpp index 0c79dfe24..d69efbd5d 100755 --- a/src/include/date.cpp +++ b/src/include/date.cpp @@ -107,10 +107,14 @@ TDate::TDate(int day, int month, int year) { if (day >= 1 && day <= 31 && month >= 1 && month <= 12 && year > 0) { - // 01/06/07 Tolla: Se passo il giorno 31 sicuramente voglio l'ultimo! Così passando 31/02/xx mi torna - if(day == 31) +/* // 01/06/07 Tolla: Se passo il giorno 31 sicuramente voglio l'ultimo! Così passando 31/02/xx mi torna che cazzata esiste last_day qui sotto + if (day == 31) +#ifdef DBG + error_box("Mattia sei un imbecille"); +#else _val = makedata(last_day(month,year), month, year); - else +#endif + else */ _val = makedata(day, month, year); } else diff --git a/src/include/execp.h b/src/include/execp.h index 12a974a5f..9c82d702b 100755 --- a/src/include/execp.h +++ b/src/include/execp.h @@ -36,7 +36,7 @@ public: // @cmember Controlla se l'utente puo' eseguire il programma bool can_run() const; // @cmember Esegue il processo - long run(bool async = FALSE, byte user = TRUE, bool iconizetask = true); + long run(bool async = false, byte user = true, bool iconizetask = true); // @cmember Ritorna l'ultimo codice di uscita int exitcode() const { return _exitcode; } diff --git a/src/include/expr.cpp b/src/include/expr.cpp index 6749f7cc8..f5ba4dd41 100755 --- a/src/include/expr.cpp +++ b/src/include/expr.cpp @@ -1230,7 +1230,7 @@ TCodesym TExpression::__factor(TCodesym startsym) _code.add(_number, real(parms_found)); val = real(index); _code.add(startsym, val); - _user_func_defined = TRUE; + _user_func_defined = true; } } } diff --git a/src/include/multirec.h b/src/include/multirec.h index 495774b0b..f17787831 100755 --- a/src/include/multirec.h +++ b/src/include/multirec.h @@ -32,8 +32,6 @@ class TMultiple_rectype : public TAuto_variable_rectype protected: const TArray & files() const { return _files;} - // @cmember Documento nuovo (non presente sul database). - bool nuovo() const { return _nuovo; } // @cmember funzione per costruire la chiave delle righe virtual void set_body_key(TRectype & rowrec); // @cmember verifica se la chiave della testata e' completa @@ -73,7 +71,9 @@ public: void set_nuovo(bool nuovo) { _nuovo = nuovo; } // @cmember restituisce il record di testata - const TAuto_variable_rectype& head() const { return *this; } // Ritorna la testata del documento + // @cmember Documento nuovo (non presente sul database). + bool nuovo() const { return _nuovo; } + const TAuto_variable_rectype& head() const { return *this; } // Ritorna la testata del documento // @cmember restituisce il record di testata TAuto_variable_rectype& head() { return *this; } // Ritorna la testata del documento diff --git a/src/include/relapp.cpp b/src/include/relapp.cpp index 6a941e6ca..479093881 100755 --- a/src/include/relapp.cpp +++ b/src/include/relapp.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -15,9 +16,10 @@ /////////////////////////////////////////////////////////// TRelation_application::TRelation_application() - : _mask(NULL), _search_id(-1), _lnflag(0), + : _mask(nullptr), _search_id(-1), _lnflag(0), _autodelete(0), _navigating(false), - _locked(false) + _locked(false), _stop_on_error(0), + _curr_transaction(transaction_mode_interactive), _transaction_batch(false) { } TRelation_application::~TRelation_application() @@ -29,7 +31,8 @@ bool TRelation_application::has_filtered_cursor() const if (yes) { const TEdit_field& f = get_search_field(); - yes = f.browse() != NULL; + + yes = f.browse() != nullptr; } return yes; } @@ -44,7 +47,7 @@ TCursor * TRelation_application::get_filtered_cursor() const return f.browse()->cursor(); } else - return NULL; + return nullptr; } void TRelation_application::setkey() @@ -103,7 +106,7 @@ void TRelation_application::set_limits( if (has_filtered_cursor()) { const TEdit_field& f = get_search_field(); - if (f.browse() != NULL) + if (f.browse() != nullptr) f.browse()->do_input(true); TCursor* cur = get_filtered_cursor(); @@ -267,7 +270,7 @@ void TRelation_application::enable_query() if (c.is_edit()) { TEdit_field& e = (TEdit_field&)c; - if (e.browse() != NULL) + if (e.browse() != nullptr) e.enable_check(query); } } @@ -285,7 +288,7 @@ bool TRelation_application::can_I_read(const TRelation* rel) const void TRelation_application::set_toolbar() { const int mode = _mask->mode(); - const bool can_edit_some = can_I_write(NULL); + const bool can_edit_some = can_I_write(nullptr); const bool can_nav = _lnflag == 0 && _curr_transaction != TRANSACTION_LINK; bool enabsave = can_edit_some; @@ -337,7 +340,7 @@ void TRelation_application::set_toolbar() { // Prima: can_edit_some = can_I_write(NULL) // Adesso: user_can_write() -> a me interessa che l'utente possa scrivere senza controllare che sia bloccato il record, si può sempre creare un record (se abilitati) nuovo anche in visualizzazione - bool enabins = (mode == MODE_QUERY || _lnflag == 0) && user_can_write(NULL); + bool enabins = (mode == MODE_QUERY || _lnflag == 0) && user_can_write(nullptr); _mask->fld(pos).enable(enabins); } @@ -359,7 +362,7 @@ bool TRelation_application::save_and_new() const bool TRelation_application::save_and_quit() const { - return (_autoins_caller.full() || _curr_transaction.not_empty()) && _curr_trans_mode != TM_REMAIN; + return (_autoins_caller.full() || _curr_transaction.not_empty()) && _curr_trans_mode != transaction_mode_remain; } int TRelation_application::set_mode(int mode) @@ -421,12 +424,12 @@ bool TRelation_application::autonum( for (const char* n = k.get(0); n && *n; n = k.get()) { - TMask_field* fld = NULL; + TMask_field* fld = nullptr; if (isdigit(*n)) fld = m->find_by_id(atoi(n)); else fld = m->find_by_fieldname(n); - if (fld == NULL) + if (fld == nullptr) { NFCHECK("Identificatore di autonumerazione errato"); return false; @@ -454,7 +457,7 @@ void TRelation_application::query_mode( // @flag FALSE | Entra in modo MODE_QUERY (default) { TMask* old = _mask; - const bool was_open = old != NULL && old->is_open(); + const bool was_open = old != nullptr && old->is_open(); const bool changing = changing_mask(MODE_QUERY); if (changing && was_open) @@ -721,7 +724,7 @@ int TRelation_application::delete_mode() { FOR_EACH_TOKEN(inplist, tok) { - if (*tok != '"' && strchr(tok, '@') == NULL) + if (*tok != '"' && strchr(tok, '@') == nullptr) { TMask_field& e = _mask->field(short(atoi(tok))); if (e.active()) @@ -747,7 +750,7 @@ int TRelation_application::delete_mode() FOR_EACH_TOKEN(inplist, tok) { - if (*tok != '"' && strchr(tok, '@') == NULL) + if (*tok != '"' && strchr(tok, '@') == nullptr) { TMask_field& e = _mask->field(short(atoi(tok))); if (!e.active()) @@ -893,7 +896,7 @@ int TRelation_application::delete_mode() { cur = pos; brw->do_output(); - bool can_delete = FALSE; + bool can_delete = false; if (find(1)) { TRelation& r = *get_relation(); @@ -909,14 +912,14 @@ int TRelation_application::delete_mode() query_mode(); cur.freeze(true); } - _autodelete = FALSE; + _autodelete = false; } if (!can_delete) skipped++; deleting--; } } - cur.freeze(FALSE); + cur.freeze(false); set_limits(); // Riaggiorno il numero del primo/ultimo record if (skipped > 0) @@ -930,9 +933,9 @@ int TRelation_application::delete_mode() else { if (search_mode()) - _autodelete = TRUE; + _autodelete = true; } - return TRUE; + return true; } // @doc INTERNAL @@ -947,7 +950,7 @@ bool TRelation_application::test_key( bool onereq = false, onefill = false; for (TEditable_field* e = _mask->get_key_field(k, true); - e != NULL; + e != nullptr; e = _mask->get_key_field(k, false)) { if (e->required() && e->shown()) @@ -962,7 +965,7 @@ bool TRelation_application::test_key( #ifdef DBG msg << "\nChiave " << int(k) << " - Campo " << e->dlg(); const TFieldref* fr = e->field(); - if (fr != NULL) + if (fr != nullptr) { msg << " - " << fr->name(); if (fr->to() > 0) @@ -1163,6 +1166,9 @@ bool TRelation_application::save(bool check_dirty) was_dirty = false; TWait_cursor hourglass; + + if (batch_transaction_in_error()) + return true; if (mode == MODE_INS) { bool changed = true; @@ -1268,6 +1274,7 @@ int TRelation_application::write(const TMask& m) int TRelation_application::rewrite(const TMask& m) { + TRelation& r = *get_relation(); m.autosave(r); r.curr().set_modify_info(); @@ -1356,19 +1363,30 @@ bool TRelation_application::remove() bool TRelation_application::firm_change_enabled() const { bool ok = TApplication::firm_change_enabled(); - ok &= (_mask == NULL || _mask->query_mode()) && _lnflag == 0; + ok &= (_mask == nullptr || _mask->query_mode()) && _lnflag == 0; return ok; } void TRelation_application::main_loop() { - KEY k; + KEY k = K_UNDEF; + TProgress_monitor * p = nullptr; + + if (_prog_message.full()) + p = new TProgress_monitor(_ntransactions, _prog_message); + if (_transaction_batch) + batch(); do { // ciclo delle transazioni _recins = -1; // imposta la maschera in query mode query_mode(); + if (_mask && _mask->find_by_id(DLG_LOG)) + { + _mask->show(DLG_LOG, db_log() && admin()); + _mask->set_handler(DLG_LOG, show_log_handler); + } _mask->open_modal(); // Provoca l'autopremimento per il messaggio di LINK @@ -1381,11 +1399,14 @@ void TRelation_application::main_loop() { // la transazione necessita di autopremimento _autodelete = _curr_transaction == TRANSACTION_DELETE; - if (_curr_transaction == TRANSACTION_INSERT ) - _mask->send_key(K_CTRL+'N', 0); + if (_curr_transaction == TRANSACTION_INSERT) + _mask->send_key(K_CTRL + 'N', 0); else _mask->send_key(K_AUTO_ENTER, 0); - } + if (_transaction_batch) + do_events(); + } + } else // la transazione non è sul .ini { @@ -1411,18 +1432,26 @@ void TRelation_application::main_loop() _mask->send_key(K_CTRL+'E', 0); else error_box(TR("Elemento non eliminabile.")); - _autodelete = FALSE; + _autodelete = false; } } - if (_curr_trans_mode == TM_BATCH) + if (is_transaction() && _transaction_batch) { - batch(); - k = _mask->check_mask(); - batch(false); + KEY k_tmp = _mask->check_mask(); + + if (k_tmp == K_ENTER) + { + if (k != K_UNDEF) + k_tmp = K_SAVE; + } + else + if (_stop_on_error > 0) + _stop_on_error++; + k = k_tmp; } else - k = _mask->run(); + k = _mask->run(); switch (k) { @@ -1439,7 +1468,7 @@ void TRelation_application::main_loop() } break; case K_QUIT: - if (!save(TRUE)) + if (!is_batch_transaction() && !save(TRUE)) k = K_ENTER; break; case K_F1: @@ -1472,8 +1501,11 @@ void TRelation_application::main_loop() else insert_mode(); } - if (_curr_trans_mode == TM_AUTOMATIC || _curr_trans_mode == TM_BATCH) - _mask->send_key(K_CTRL+'R', 0); + if (_curr_trans_mode == transaction_mode_automatic && !_transaction_batch) + { + _mask->send_key(K_CTRL + 'R', 0); + do_events(); + } break; case K_SAVE: if (save(FALSE)) @@ -1484,7 +1516,7 @@ void TRelation_application::main_loop() } else { - if (save_and_new() && can_I_write(NULL)) + if (save_and_new() && can_I_write(nullptr)) { if (_mask->insert_mode()) insert_mode(); @@ -1516,7 +1548,7 @@ void TRelation_application::main_loop() else insert_mode(); } - if (_curr_trans_mode == TM_AUTOMATIC || _curr_trans_mode == TM_BATCH) + if (_curr_trans_mode == transaction_mode_automatic || _transaction_batch) _mask->send_key(K_CTRL+'R', 0); break; case K_DEL: @@ -1526,6 +1558,8 @@ void TRelation_application::main_loop() } else { + if (batch_transaction_in_error()) + break; if (relation_remove()) { query_mode(); @@ -1559,7 +1593,7 @@ void TRelation_application::main_loop() { 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 + if (e->is_kind_of(CLASS_EDIT_FIELD) && e->shown() && e->browse() != nullptr) // Ignora campi invisibili o senza check { TCursor* b = e->browse()->cursor(); @@ -1574,7 +1608,7 @@ void TRelation_application::main_loop() TCursor* cur = c ; - if (c == NULL) + if (c == nullptr) cur = new TCursor(get_relation()); err = file().reread(); @@ -1586,8 +1620,8 @@ void TRelation_application::main_loop() file().curr() = cur->curr(); if (can_I_read(cur->relation())) err = get_relation()->read(_isequal, _testandlock); - if (c == NULL) - delete cur; + if (c == nullptr) + safe_delete(cur); } break; case K_PREV: @@ -1598,7 +1632,7 @@ void TRelation_application::main_loop() { 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 + if (e->is_kind_of(CLASS_EDIT_FIELD) && e->shown() && e->browse() != nullptr) // Ignora campi invisibili o senza check { TCursor* b = e->browse()->cursor(); @@ -1611,28 +1645,28 @@ void TRelation_application::main_loop() } } - TCursor* cur = c ; + TCursor* cur = c ; - if (c == NULL) - cur = new TCursor(get_relation()); + if (c == nullptr) + cur = new TCursor(get_relation()); - file().reread(); + file().reread(); cur->curr() = file().curr(); cur->read(); --(*cur); - while (cur->pos() > 0 && !can_I_read(cur->relation())) + 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; + err = get_relation()->read(_isequal, _testandlock); + if (c == nullptr) + safe_delete(cur); } break; - case K_END: + case K_END: err = file().readat(_last, _testandlock); break; - default: + default: break; } if (err == NOERR || err == _islocked) @@ -1649,7 +1683,7 @@ void TRelation_application::main_loop() } while (k != K_QUIT); if (_mask->is_open()) - _mask->close_modal(); + _mask->close_modal(); _mask->set_mode(NO_MODE); @@ -1675,25 +1709,40 @@ void TRelation_application::main_loop() else { const int err = get_relation()->status(); - ini.set("Result", err == NOERR ? "CANCEL" : "ERROR"); - ini.set("Error", err); + ini.set("Result", (err == NOERR && !is_batch_transaction()) ? "CANCEL" : "ERROR"); + ini.set("Error", !is_batch_transaction() ? err : -1); } - if (_curr_trans_mode == TM_BATCH) + if (_transaction_batch) { - TString_array & errs = errors(); + TString_array & errs = errors(); FOR_EACH_ARRAY_ROW(errs, r, s) - ini.set("ErrMsg", *s, "Main", false, r); + ini.set("ErrorMsg", *s, "Transaction", true, r); + for (int r = errs.items(); ini.exist("ErrorMsg", "Transaction", r); r++) + ini.remove("ErrorMsg", "Transaction", r); TString_array & warns = warnings(); FOR_EACH_ARRAY_ROW(warns, r1, s1) - ini.set("WarningMsg", *s1, "Main", false, r1); + ini.set("WarningMsg", *s1, "Transaction", true, r1); + for (int r = warns.items(); ini.exist("WarningMsg", "Transaction", r); r++) + ini.remove("WarningMsg", "Transaction", r); + errs.destroy(); + warns.destroy(); } } _trans_counter++; + if (p != nullptr) + p->addstatus(1L); + k = K_UNDEF; } while ( _trans_counter < _ntransactions); + if (_transaction_batch) + { + batch(false); + force_stop(); + } + safe_delete(p); } bool TRelation_application::filter() @@ -1720,7 +1769,7 @@ bool TRelation_application::filter() TString80 t; const char* s; - while((s = body.get()) != NULL) + while((s = body.get()) != nullptr) { t = s; const int u = t.find('='); @@ -1732,12 +1781,12 @@ bool TRelation_application::filter() _fixed.add(t); const short fid = atoi(t.left(u)); const TFieldref* campo = _mask->field(fid).field(); - if (campo != NULL) + if (campo != nullptr) campo->write(t.mid(u+1), rec); } cur->setfilter(""); cur->setregion(rec, rec, 0x2); - if (s == NULL) id = 0; + if (s == nullptr) id = 0; } } @@ -1757,7 +1806,7 @@ bool TRelation_application::filter() TString str, tmp; const char* v = body.get(); - for (int i = 0; v != NULL && i < _mask->fields(); i++) + for (int i = 0; v != nullptr && i < _mask->fields(); i++) { TMask_field& f = _mask->fld(i); if (f.active() && f.dlg() > 0 && f.in_key(key)) @@ -1785,7 +1834,7 @@ bool TRelation_application::filter() const char * s; TString t, v; - while((s = body.get()) != NULL) + while((s = body.get()) != nullptr) { t = s; const int u = t.find('='); @@ -1816,7 +1865,7 @@ bool TRelation_application::filter() const TString * v = (const TString *) field_values.objptr(field_name); TString val; - if (v == NULL && to >= 0) + if (v == nullptr && to >= 0) { v = (const TString *)field_values.objptr(field->name()); if (v) @@ -1834,23 +1883,22 @@ bool TRelation_application::filter() } } } - - return TRUE; + return true; } void TRelation_application::set_link(TMask & m, const char * keyexpr) { - CHECK(keyexpr != NULL, "Invalid expression"); + CHECK(keyexpr != nullptr, "Invalid expression"); TToken_string body(keyexpr); const int key = body.get_int(); - _lnflag = TRUE; + _lnflag = true; const char* v = body.get(); TString16 tmp; const int max = m.fields(); - for (int i = 0; i < max && v != NULL; i++) + for (int i = 0; i < max && v != nullptr; i++) { TMask_field& f = m.fld(i); @@ -1871,14 +1919,15 @@ bool TRelation_application::parse_command_line() _trans_ini.destroy(); _trans_counter=0; _curr_transaction = ""; - _curr_trans_mode = 'I'; + _curr_trans_mode = transaction_mode_interactive; TFilename ini; for (int i = argc()-1; i > 0; i--) { ini = argv(i); - if ((ini[0] == '-' || ini[0] == '/') && (ini[1] == 'I' || ini[1] == 'i')) + if ((ini[0] == '-' || ini[0] == '/') && ((toupper(ini[1]) == 'I') || (toupper(ini[1]) == 'B'))) { + _transaction_batch = (toupper(ini[1]) == 'B'); ini.ltrim(2); if (ini.starts_with("=")) ini.ltrim(1); @@ -1895,6 +1944,16 @@ bool TRelation_application::parse_command_line() else cantread_box(ini); } + + TString msg = argv(i + 1); + + if (msg.starts_with("-m") || msg.starts_with("-M")) + { + i++; + msg.ltrim(2); + msg.strip("\""); + _prog_message = msg; + } break; } } @@ -1915,7 +1974,8 @@ bool TRelation_application::load_transaction() 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_mode = (transaction_mode) toupper(cnf.get("Mode")[0]); + _stop_on_error = cnf.get_bool("StopOnError") ? 1 : 0; _curr_trans_from = cnf.get("From"); const long firm = cnf.get_long("Firm"); if (firm > 0) @@ -1937,10 +1997,8 @@ bool TRelation_application::load_transaction() void TRelation_application::on_firm_change() { TApplication::on_firm_change(); - if (_mask != NULL) - { + if (_mask != nullptr) set_limits(0x3); - } } void TRelation_application::ini2query_mask() @@ -1959,6 +2017,7 @@ void TRelation_application::ini2insert_mask() { TString8 n; n.format("%d", get_relation()->lfile().num()); TConfig ini(_trans_ini.row(_trans_counter), n); + ini2mask(ini, *_mask, FALSE); } } @@ -1994,6 +2053,7 @@ void TRelation_application::ini2mask(TConfig& ini, TMask& m, bool query) if (!query && campo.is_sheet()) { TSheet_field &sheet=(TSheet_field &)campo; + ini2sheet(ini, sheet); } } @@ -2017,7 +2077,7 @@ void TRelation_application::edit_mask2ini() void TRelation_application::ini2sheet(TConfig& ini,TSheet_field &sheet) { - if (sheet.record() != NULL) + if (sheet.record() != nullptr) { const int lognum = sheet.record()->logic_num(); const TMask& sm = sheet.sheet_mask(); @@ -2027,8 +2087,17 @@ void TRelation_application::ini2sheet(TConfig& ini,TSheet_field &sheet) for (int r = 1; ;r++) { + bool found = false; + defpar.format("%d,%d", lognum, r); - if (ini.set_paragraph(defpar)) + for (int i = 0; i < 3 && !(found = ini.set_paragraph(defpar)); i++) + { + const int pos = defpar.find(','); + + if (pos > 0) + defpar.insert("0", pos + 1); + } + if (found) { TToken_string& row = sheet.row(r-1); for (int sf = sm.fields()-1; sf >= 0; sf--) @@ -2051,7 +2120,7 @@ void TRelation_application::ini2sheet(TConfig& ini,TSheet_field &sheet) void TRelation_application::sheet2ini(TSheet_field &sheet,TConfig& ini) { - if (sheet.record() != NULL) + if (sheet.record() != nullptr) { const int lognum = sheet.record()->logic_num(); const TMask& sm = sheet.sheet_mask(); @@ -2063,25 +2132,38 @@ void TRelation_application::sheet2ini(TSheet_field &sheet,TConfig& ini) for (r = 1 ; r <= sheet.items(); r++) { + bool found = false; + defpar.format("%d,%d", lognum, r); - + for (int i = 0; i < 3 && !(found = ini.set_paragraph(defpar)); i++) + { + const int pos = defpar.find(','); + + if (pos > 0) + defpar.insert("0", pos + 1); + } + if (found) + if (ini.set_paragraph(defpar)) + ini.remove_all(); + defpar.format("%d,%04d", 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') + if (value == nullptr || *value == '\0') value = " "; // ini.set(fr->name(), value, defpar); fr->write(ini, defpar, value); @@ -2091,6 +2173,16 @@ void TRelation_application::sheet2ini(TSheet_field &sheet,TConfig& ini) for (r = sheet.items()+1; ; r++) { defpar.format("%d,%d", lognum, r); + bool found = false; + + defpar.format("%d,%d", lognum, r); + for (int i = 0; i < 3 && !(found = ini.set_paragraph(defpar)); i++) + { + const int pos = defpar.find(','); + + if (pos > 0) + defpar.insert("0", pos + 1); + } if (ini.set_paragraph(defpar)) ini.remove_all(); else @@ -2172,7 +2264,7 @@ bool TRelation_application::mask2mail(const TMask& m) { TConfig ini(ininame, "Transaction"); const char* action = ""; - char mode[2] = { TM_AUTOMATIC, '\0' }; + char mode[2] = { transaction_mode_automatic, '\0' }; switch (m.mode()) { case NO_MODE: diff --git a/src/include/relapp.h b/src/include/relapp.h index 9f3333f71..56b02778a 100755 --- a/src/include/relapp.h +++ b/src/include/relapp.h @@ -13,19 +13,14 @@ #include #endif -#ifndef __MASK_H -#include +#ifndef __AUTOMASK_H +#include +#endif + +#ifndef __TRANSACTION_H +#include #endif -#define TRANSACTION_RUN "RUN" // Run application (eventually sets firm) -#define TRANSACTION_INSERT "INSERT" // Create a new record and fill it -#define TRANSACTION_MODIFY "MODIFY" // Load and modify an existing record -#define TRANSACTION_DELETE "DELETE" // Delete an existing record -#define TRANSACTION_LINK "LINK" // Load an existing record and interactively edit it -#define TM_INTERACTIVE 'I' -#define TM_AUTOMATIC 'A' -#define TM_REMAIN 'R' -#define TM_BATCH 'B' // @doc EXTERNAL // @class TRelation_application | Classe per la gestione di una applicazione di manutenzione di uno @@ -68,14 +63,20 @@ class TRelation_application : public TSkeleton_application // @cmember:(INTERNAL) Azione della transazione corrente TString _curr_transaction; // @cmember:(INTERNAL) Modalità di esecuzione della transazione corrente (Automatica o interattiva) - char _curr_trans_mode; + transaction_mode _curr_trans_mode; + // @cmember:(INTERNAL) Modalità di esecuzione batch della transazione corrente + bool _transaction_batch; // @cmember:(INTERNAL) Transazione ricevuta da ..... TString _curr_trans_from; + // @cmember:(INTERNAL) Messaggio progress monitor transazioni + TString _prog_message; // @cmember:(INTERNAL) Flag di cancellazione automatica veloce int _autodelete; // @cmember:(INTERNAL) Flag di navigazione tramite toolbar bool _navigating; bool _locked; + // @cmember:(INTERNAL) Flag di controllo scritt ura su errore per le transizioni batch + int _stop_on_error; private: // @cmember:(INTERNAL) Carica la transazione corrente (protocollo via .ini) @@ -96,7 +97,7 @@ private: void set_key_filter(); // @cmember:(INTERNAL) Posiziona l'applicazione in modo richiesta/inserimento (chiama ) void query_insert_mode() - { query_mode(TRUE); } + { query_mode(true); } // @cmember:(INTERNAL) Entra in modo inserimento void insert_mode(); // @cmember:(INTERNAL) Cancella il record corrente @@ -283,9 +284,13 @@ public: bool lnflag() const { return _lnflag != 0;} // @cmember Ritorna TRUE se e' una transazione virtual bool is_transaction() const { return _curr_transaction.not_empty(); } + virtual bool is_batch_transaction() const { return is_transaction() && _transaction_batch; } + virtual bool batch_transaction_in_error() const { return is_batch_transaction() && _stop_on_error > 1; } virtual word class_id() const { return CLASS_RELATION_APPLICATION; } + virtual bool task_win_shown() const { return !_transaction_batch; } + // @cmember Costruttore TRelation_application(); // @cmember Distruttore diff --git a/src/include/transaction.cpp b/src/include/transaction.cpp index 89a4b565e..32e298197 100644 --- a/src/include/transaction.cpp +++ b/src/include/transaction.cpp @@ -727,8 +727,10 @@ bool file2app(TString & file ,TString& app) return app.full(); } -void execute_transactions(TArray & transactions, TLog_report & log) +void execute_transactions(TArray & transactions, TLog_report & log, bool interactive, const char * msg) { + TString prog_msg(msg); + if (transactions.items() > 0) { TBit_array processed; @@ -748,11 +750,14 @@ void execute_transactions(TArray & transactions, TLog_report & log) break; if (table.full()) { - TFilename path = t.name().path(); + TFilename pref = t.name(); + pref.ext(""); + while (isdigit(pref[pref.len() - 1])) + pref.rtrim(1); while (i >= 0) { - if (t.executer() == table && path == t.name().path()) + if (t.executer() == table && t.name().starts_with(pref)) { t.write(); processed.set(i); @@ -768,11 +773,14 @@ void execute_transactions(TArray & transactions, TLog_report & log) if (file2app(table, app)) { - TFilename filemask(path); + TFilename filemask(pref); TString_array files; filemask << "*" << "." << t.ext(); - app << " -i" << filemask << " -u" << user(); + app << (interactive ? " -i" : " -b") << filemask; + if (prog_msg.full()) + app << " -m\"" << prog_msg << "\""; + app << " -u" << user(); TExternal_app cmd(app); cmd.run(); diff --git a/src/include/transaction.h b/src/include/transaction.h index fed1977b8..867f46cf6 100644 --- a/src/include/transaction.h +++ b/src/include/transaction.h @@ -186,6 +186,6 @@ public: virtual ~TTransaction() {} }; -void execute_transactions(TArray & transactions, TLog_report & log); +void execute_transactions(TArray & transactions, TLog_report & log, bool interactive = true, const char * msg = nullptr); #endif diff --git a/src/include/validate.cpp b/src/include/validate.cpp index 9aaaf5764..da52298a4 100755 --- a/src/include/validate.cpp +++ b/src/include/validate.cpp @@ -517,8 +517,8 @@ HIDDEN bool _fixlen_val(TMask_field& f, KEY) const int length = get_int_val_param(0); const bool ok = s.len() == length; if (!ok) - f.error_box(FR("La lunghezza del campo deve essere %d %s"), - length, f.is_kind_of(CLASS_REAL_FIELD) ? TR("cifre") : TR("caratteri")); + f.error_box(FR("La lunghezza del campo %s deve essere %d %s"), + f.prompt(), length, f.is_kind_of(CLASS_REAL_FIELD) ? TR("cifre") : TR("caratteri")); return ok; } @@ -703,7 +703,7 @@ HIDDEN bool _alpha_val(TMask_field& f, KEY k) const TString& s = f.get(); for (int i = 0; s[i]; i++) if (!isalpha(s[i])) - return f.error_box(TR("Sono ammessi solo caratteri alfabetici")); + return f.error_box(FR("Sono ammessi solo caratteri alfabetici nel campo %s"), f.prompt()); } return true; } @@ -822,7 +822,7 @@ HIDDEN bool _ora_val(TMask_field& f, KEY key) if ( ok ) f.set( ora ); else - return f.error_box(TR("Ora errata o formato non valido")); + return f.error_box(FR("Ora errata o formato non valido nel campo %s"), f.prompt()); } } return true;