(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/files.h b/src/include/files.h
index 9a2743bfc..b1937098c 100755
--- a/src/include/files.h
+++ b/src/include/files.h
@@ -225,7 +225,7 @@ public:
// @cmember Ritorna una token string contenente la descrizione del campo
const char* fielddef(int fld) const;
// @cmember Ritorna una stringa contenente la chiave
- const char* keydef(int key) const;
+ const char* keydef(int key = 0) const;
// @cmember Ritorna la lunghezza del record
int len() const;
diff --git a/src/include/keys.h b/src/include/keys.h
index 2528df61d..a90a7cb75 100755
--- a/src/include/keys.h
+++ b/src/include/keys.h
@@ -6,6 +6,7 @@
#endif
/* @M */
+#define K_UNDEF 0
#define K_BACKSPACE 8
#define K_TAB 9
#define K_ENTER 13
diff --git a/src/include/mask.cpp b/src/include/mask.cpp
index b0781d46f..aa56652d1 100755
--- a/src/include/mask.cpp
+++ b/src/include/mask.cpp
@@ -797,7 +797,7 @@ bool TMask::stop_run(
}
}
}
- if (i >= last)
+ if (i >= last)
return false;
}
@@ -2802,12 +2802,12 @@ void TMask::post_error_message(const char* msg, int sev)
}
}
+// @comm Check_mask fatta per la relapp chiamate in modo batch verifica la consistenza della maschera senza visualizzare l'interfaccia.
+// @comm Se la finestra non era aperta la apre in modo modale
KEY TMask::check_mask()
-
- // @comm Se la finestra non era aperta la apre in modo modale
{
start_run();
- return stop_run(K_ENTER) ? K_ENTER : K_ESC;
+ return stop_run(K_AUTO_ENTER) ? K_ENTER : K_QUIT;
}
// @cmember ritorna la posizione del primo campo di una cella di uno sheet
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/odbcrset.cpp b/src/include/odbcrset.cpp
index 82cb28818..12cffac81 100755
--- a/src/include/odbcrset.cpp
+++ b/src/include/odbcrset.cpp
@@ -707,6 +707,20 @@ void TODBC_recordset::remove_rec(const TISAM_recordset& dbfset)
upd.exec(query);
}
+const char * TODBC_recordset::table_name()
+{
+ TString & s = get_tmp_string(255);
+ int pos = _sql.find("FROM");
+
+ if (pos >= 0)
+ {
+ s = _sql.ltrim(pos + 5);
+ pos = s.find(" ");
+ if (pos > 0)
+ s = s.left(pos);
+ }
+ return s;
+}
void TODBC_recordset::set(const char* sql)
{
if (not_frozen() || !_loaded || _sql != sql)
diff --git a/src/include/odbcrset.h b/src/include/odbcrset.h
index 548f4b1e7..675547b9d 100755
--- a/src/include/odbcrset.h
+++ b/src/include/odbcrset.h
@@ -69,6 +69,7 @@ public:
void remove_rec(const TISAM_recordset& dbfset);
const TString& dsn() const { return _dsn; }
+ const char * table_name();
TODBC_recordset(const char* sql, const bool freezed = false);
virtual ~TODBC_recordset();
diff --git a/src/include/postman.cpp b/src/include/postman.cpp
index 8d33b6960..a65f467ad 100755
--- a/src/include/postman.cpp
+++ b/src/include/postman.cpp
@@ -495,7 +495,7 @@ void TPostman::load_filters()
// Inserisce un elemento fasullo per segnalare l'avvenuta lettura
if (_expr.items() == 0)
- _expr.add("", NULL);
+ _expr.add("", new TObject);
}
TExpression* TPostman::get_filter_expr(const char* flt)
diff --git a/src/include/prefix.cpp b/src/include/prefix.cpp
index a02b96837..e794c23d1 100755
--- a/src/include/prefix.cpp
+++ b/src/include/prefix.cpp
@@ -789,6 +789,13 @@ TDirtype TFile_manager::get_dirtype(int logicnum)
return i.dir_type();
}
+const char * TFile_manager::get_keydef(int logicnum, int key) const
+{
+ TTrec r(logicnum);
+
+ return r.keydef(key - 1);
+}
+
void TFile_manager::notify_change(TIsam_handle name)
{
TFile_info& i = fileinfo(name);
@@ -1036,12 +1043,14 @@ 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);
xvt_fsys_build_pathname(prfx, NULL, __ptprf, _prefix, NULL, NULL);
}
else
{
char* prfx = (char*)CGetPref(); // Safe non const cast for StPath cprefix
+
*prfx = '\0';
}
}
diff --git a/src/include/prefix.h b/src/include/prefix.h
index 8f3e15be6..eb0bb7e45 100755
--- a/src/include/prefix.h
+++ b/src/include/prefix.h
@@ -50,7 +50,7 @@ public:
TCodeb_handle get_handle(TIsam_handle name, int key);
int get_reclen(int logicnum);
-
+ const char * get_keydef(int logicnum, int key = 1) const ;
void notify_change(TIsam_handle name);
long last_change(TIsam_handle name) const;
@@ -208,6 +208,9 @@ public:
const TFilename& get_filename(TIsam_handle name) const
{ return _manager.get_filename(name); }
+ const char * get_keyexpr(int logicnum, int key = 1) const
+ { return TToken_string(_manager.get_keydef(logicnum, key)).get(); }
+
void notify_change(TIsam_handle name)
{ _manager.notify_change(name); }
diff --git a/src/include/relapp.cpp b/src/include/relapp.cpp
index 6a941e6ca..3a33576f7 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,13 +1363,19 @@ 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;
@@ -1381,11 +1394,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 +1427,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 +1463,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 +1496,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 +1511,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 +1543,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 +1553,8 @@ void TRelation_application::main_loop()
}
else
{
+ if (batch_transaction_in_error())
+ break;
if (relation_remove())
{
query_mode();
@@ -1559,7 +1588,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 +1603,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 +1615,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 +1627,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 +1640,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 +1678,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 +1704,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 +1764,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 +1776,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 +1801,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 +1829,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 +1860,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 +1878,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 +1914,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 +1939,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 +1969,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 +1992,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 +2012,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 +2048,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 +2072,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 +2082,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 +2115,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 +2127,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 +2168,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 +2259,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;
diff --git a/src/include/xml.h b/src/include/xml.h
index 15300ac64..fbadfbb8a 100755
--- a/src/include/xml.h
+++ b/src/include/xml.h
@@ -57,6 +57,7 @@ public:
bool GetEnclosedReal(const char* strAttr, real & r) const;
TXmlItem& SetAttr(const char* strAttr, const char* strVal);
+ void ListAttrs(TString_array & attrs) const { attrs.destroy(); if (m_Attributes) m_Attributes->get_keys(attrs); }
const TString& GetAttr(const char* strAttr) const;
TXmlItem& SetAttr(const char* strAttr, int n);
TXmlItem& SetColorAttr(const char* strAttr, COLOR rgb);
diff --git a/src/ve/ve0100.cpp b/src/ve/ve0100.cpp
index b893b128f..f384af3b3 100755
--- a/src/ve/ve0100.cpp
+++ b/src/ve/ve0100.cpp
@@ -1173,10 +1173,7 @@ void TMotore_application::ini2mask(TConfig& ini, TMask& msk, bool query)
{
const TRectype& art = cache().get(LF_ANAMAG, codart);
if (art.empty())
- {
- error_box(FR("Articolo non valido sulla riga %d: %s"), f.items(), (const char*)codart);
rec.zero(RDOC_CODARTMAG);
- }
}
}
else
diff --git a/src/xvaga/xvaga.cpp b/src/xvaga/xvaga.cpp
index 6e15803ea..c826be031 100755
--- a/src/xvaga/xvaga.cpp
+++ b/src/xvaga/xvaga.cpp
@@ -3742,6 +3742,28 @@ BOOLEAN xvt_sys_set_profile_string(const char* file, const char* paragraph, cons
#endif
}
+XVTDLL BOOLEAN xvt_sys_remove_profile_string(const char* file, const char* paragraph, const char* name)
+{
+ if (file == NULL || *file == '\0')
+ file = xvt_fsys_get_campo_ini();
+
+ if (paragraph == NULL || *paragraph == '\0')
+ paragraph = "Main";
+
+#ifdef __WXMSW__
+ return ::WritePrivateProfileString(paragraph, name, nullptr, file) > 0;
+#else
+ wxFileConfig ini("", "", file, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
+ ini.SetUmask(0x0);
+
+ wxString path;
+ path << "/" << paragraph;
+ ini.SetPath(path);
+
+ return ini.DeleteEntry(name);
+#endif
+}
+
BOOLEAN xvt_sys_find_editor(const char* file, char* editor)
{
BOOLEAN ok = FALSE;
diff --git a/src/xvaga/xvt.h b/src/xvaga/xvt.h
index 288d91009..b442c9074 100755
--- a/src/xvaga/xvt.h
+++ b/src/xvaga/xvt.h
@@ -432,6 +432,7 @@ XVTDLL int xvt_sys_get_profile_string(const char* file, const char* paragra
const char* defval, char* value, int maxsize);
XVTDLL BOOLEAN xvt_sys_set_profile_int(const char* file, const char* paragraph, const char* name, long value);
XVTDLL BOOLEAN xvt_sys_set_profile_string(const char* file, const char* paragraph, const char* name, const char* value);
+XVTDLL BOOLEAN xvt_sys_remove_profile_string(const char* file, const char* paragraph, const char* name);
XVTDLL int xvt_sys_get_session_id();
XVTDLL unsigned long xvt_sys_get_free_memory();