campo-sirio/include/config.cpp
guy bf819df0be PORTING alla versione 4.56 di XVT piu' altre f...te
applicat.cpp  Aggiornata alla 4.5 la gestione dei 3d controls,
              corretto routing di certi E_COMMAND
              corretta gestione title di XVT_CONFIG
controls.cpp  Intercettati eventi XIE_COLMOVE e XIE_COLSIZE
              intrappolato bottone sinistro del mouse e ignorati gli altri
config.cpp    Migliorata gestione paragrafi con righe vuote
              probabile ottimizzazione del reperimento delle variabili
config.h      Tolto un CAZZ di Ferdinando
colors.cpp    Creato per gestire scelta colori
colors.h      Aggiunta funzione di conversione colori
mask.cpp      Gestione popup menu
sheet.cpp     Salvataggio colonne
msksheet.cpp  Salvataggio colonne e colorazione righe
printer.cpp   Migliorato riconoscimento fax e calcolo dimensioni foglio
tabapp.cpp    Ora prima creo la relazione e poi la maschera principale
xvtility.cpp  Aggiornata la gestione dei controlli 3D di Windows
mask.h        Aggiunto metodo per avere il numero della sottomaschera


git-svn-id: svn://10.65.10.50/trunk@3890 c028cbd2-c16b-5b4b-a496-9718f37d4682
1996-11-12 14:53:09 +00:00

607 lines
17 KiB
C++
Executable File

#include <applicat.h>
#include <colors.h>
#include <config.h>
#include <date.h>
#include <scanner.h>
#include <prefix.h>
#include <utility.h>
extern "C" { int rename(const char*, const char*); };
// @doc EXTERNAL
// @mfunc Legge i dati del paragrafo
//
// @rdesc Ritorna i seguenti valori:
//
// @flag TRUE | Se il paragrafo c'ere
// @flag FALSE | Se il pragarafo non e' esitente
bool TConfig::_read_paragraph()
// @comm Legge il contenuto di tutte le variabili del paragrafo attivo
{
bool itwas = FALSE;
_data.destroy();
TScanner scan(_file);
if (scan.paragraph(_paragraph))
{
itwas = TRUE;
// populate array
TString key, val;
for (;;)
{
const TString& l = scan.line();
if (l == "" || l[0] == '[') break; // Fine paragrafo
if (l[0] == '#' || l[0] == '/') continue; // Riga di commento
const int ind = l.find('=');
if (ind == -1)
{
error_box("Errore configurazione:\n file %s, vicino alla riga %u\n %s",
(const char*)_file, scan.linenum(), (const char*)l);
continue;
}
key = l.left(ind); key.trim();
val = l.mid(ind+1); val.trim();
if (val[0] == '%')
{
if (val == "%yr%") val.format("%04d", TDate(TODAY).year()); else
if (val == "%frm%") val.format("%05ld", prefix().get_codditta());
}
// sostituzione abilitata
_data.add(key,val,TRUE);
}
}
return itwas;
}
// @doc EXTERNAL
// @mfunc Scrive i dati del paragrafo
void TConfig::_write_paragraph(
ofstream& out) // @parm Indirizzo dell'utput sul quale scrivere il paragrafo
// @comm Scrive sullo stream <p>out le variabili del paragrafo attivo.
{
if (_data.items() > 0) // Inutile scrivere paragrafi vuoti!
{
out << '[' << _paragraph << ']' << endl;
_data.restart();
for (THash_object* o = _data.get_hashobj(); o; o = _data.get_hashobj())
out << o->key() << " = " << (TString&)(o->obj()) << '\n';
out << endl;
}
}
void TConfig::_write_file()
{
ifstream in(_file);
TFilename temp;
temp.temp("cnf");
ofstream out(temp);
TString l(1024);
TString cnf; cnf << '[' << _paragraph << ']';
bool skip = FALSE, done = FALSE, skip_empty = TRUE;
while (!in.eof())
{
in.getline((char*)(const char*)l, l.size());
l.trim();
if (cnf == l)
{
// write paragraph and all variables
_write_paragraph(out);
skip = skip_empty = done = TRUE;
}
else
{
if (skip)
skip = l[0] != '[';
if (!skip)
{
const bool empty = l.empty();
if (!empty || !skip_empty)
out << l << endl;
skip_empty = empty;
}
}
}
// new paragraph
if (!done) _write_paragraph(out);
out.close(); in.close();
if (fexist(_file))
{
while (access(_file, 02) != 0)
message_box("Il file %s e' gia' in uso", (const char*)_file);
}
fcopy(temp, _file); // Copia dalla tempdir al nuovo .ini
remove(temp); // Cancella file temporaneo
}
void TConfig::set_paragraph(const char* section)
{
if (section != NULL && _paragraph != section)
{
if (_dirty)
_write_file();
_paragraph = section;
_dirty = FALSE;
_read_paragraph();
}
}
// @doc EXTERNAL
// @mfunc Controlla se esite una variabile nel paragrafo attivo
//
// @rdesc Ritorna i seguenti valori:
//
// @flag TRUE | Se la variabile esite
// @flag FALSE | Se la variabile non esite
bool TConfig::exist(
const char* var, // @parm Nome della variabile
int index) // @parm Indice dell'elemento dell'array (default -1)
// @comm Se <p index> e' <gt>= 0 viene costruito il nome dell'elemento
// dell'array da cercare, diversamente viene cercata la variabile
// normale passata in <p var>.
{
if (index >= 0)
{
TString key(80);
key << var << '(' << index << ')';
return _data.is_key(key);
}
return _data.is_key(var);
}
// @doc EXTERNAL
// @mfunc Elimina una variabile dal paragrafo corrente
//
// @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
int index) // @parm Indice dell'elemento dell'array (default -1)
// @comm Se <p index> e' <gt>= 0 viene costruito il nome dell'elemento
// dell'array da cercare, diversamente viene cercata la variabile
// normale passata in <p var>.
{
TString key(var);
if (index >= 0)
key << '(' << index << ')';
const bool ok = _data.remove(key);
if (ok) _dirty = TRUE;
return ok;
}
// @doc EXTERNAL
// @mfunc Ritorna il valore della variabile nella sezione corrente o in
// quella specificata
//
// @rdesc Ritorna la stringa contenuta nella variabile, se questa esiste, altrimenti
// il valore di default che dovrebbe assumere determinato dal parametro
// <p def>
TString& TConfig::get(
const char* var, // @parm Variabile della quale ritornare il valore
const char* section, // @parm Sezione della varaibile (default NULL)
int index, // @parm Eventuale indice della varaibailie (default -1)
const char* def) // @parm Valore default della varaibile (default "")
// @comm Passando <p index> <gt>= 0 viene appeso al nome della variabile per
// implementare un array.
// <nl>Il paragrafo passato in <p section> diventa quello attivo.
//
// @xref <mf TConfig::get_long> <mf TConfig::get_int> <mf TConfig::get_bool>
// <mf TConfig::get_color>
{
if (section) // Cambia paragrafo se necessario
set_paragraph(section);
TString* val;
if (index >= 0)
{
TString v(80);
v << var << '(' << index << ')';
val = (TString*)_data.objptr(v);
}
else
val = (TString*)_data.objptr(var);
if (val == NULL) // Se non la trova inserisci il default
{
set(var, def, section, TRUE, index);
val = &get(var, NULL, index);
}
return *val;
}
// @doc EXTERNAL
// @mfunc Ritorna il valore della variabile nella sezione corrente o in
// quella specificata
//
// @rdesc Ritorna il numero contenuto nella variabile, se questa esiste, altrimenti
// il valore di default che dovrebbe assumere determinato dal parametro
// <p def>
long TConfig::get_long(
const char* var, // @parm Variabile della quale ritornare il valore
const char* section, // @parm Sezione della varaibile (default NULL)
int index, // @parm Eventuale indice della varaibailie (default -1)
long def) // @parm Valore default della varaibile (default 0L)
// @comm Passando <p index> <gt>= 0 viene appeso al nome variabile per
// implementare un array.
// <nl>Il paragrafo passato in <p section> diventa quello attivo.
//
// @xref <mf TConfig::get> <mf TConfig::get_int> <mf TConfig::get_bool>
// <mf TConfig::get_color>
{
const char* n = get(var,section,index);
if (*n)
def = atol(n);
else
{
TString16 d; d << def;
set(var, d, section, TRUE, index);
}
return def;
}
// @doc EXTERNAL
// @mfunc Ritorna il valore della variabile nella sezione corrente o in
// quella specificata
//
// @rdesc Ritorna il primo carattere della variabile, se questa esiste, altrimenti
// il valore di default che dovrebbe assumere determinato dal parametro
// <p def>
char TConfig::get_char(
const char* var, // @parm Variabile della quale ritornare il valore
const char* section, // @parm Sezione della varaibile (default NULL)
int index, // @parm Eventuale indice della varaibailie (default -1)
char def) // @parm Valore default della varaibile (default ' ')
// @comm Passando <p index> <gt>= 0 viene appeso al nome variabile per
// implementare un array.
// <nl>Il paragrafo passato in <p section> diventa quello attivo.
//
// @xref <mf TConfig::get> <mf TConfig::get_int> <mf TConfig::get_bool>
// <mf TConfig::get_color>
{
const char* n = get(var,section,index);
if (*n)
def = *n;
else
{
const char d[2] = { def, '\0' };
set(var, d, section, TRUE, index);
}
return def;
}
// @doc EXTERNAL
// @mfunc Ritorna il valore della variabile nella sezione corrente o in
// quella specificata
//
// @rdesc Ritorna l'intero contenuto nella variabile, se questa esiste, altrimenti
// il valore di default che dovrebbe assumere determinato dal parametro
// <p def>
int TConfig::get_int(
const char* var, // @parm Variabile della quale ritornare il valore
const char* section, // @parm Sezione della varaibile (default NULL)
int index, // @parm Eventuale indice della varaibailie (default -1)
int def) // @parm Valore default della varaibile (default 0)
// @comm Chiama la funzione <mf TConfig::get_long> e ne ritorna un intero.
// <nl>Passando <p index> <gt>= 0 viene appeso al nome variabile per
// implementare un array.
// <nl>Il paragrafo passato in <p section> diventa quello attivo.
//
// @xref <mf TConfig::get> <mf TConfig::get_long> <mf TConfig::get_bool>
// <mf TConfig::get_color>
{
return (int)get_long(var, section, index, def);
}
// @doc EXTERNAL
// @mfunc Ritorna il valore della variabile nella sezione corrente o in
// quella specificata
//
// @rdesc Ritorna i seguenti valori
//
// @flag TRUE | Se la varabile e' settata con X
// @flag FALSE | Se la varabile nen e' settata con X
// @flag <p def> | Se la varabile non esiste
bool TConfig::get_bool(
const char* var, // @parm Variabile della quale ritornare il valore
const char* section, // @parm Sezione della varaibile (default NULL)
int index, // @parm Eventuale indice della varaibailie (default -1)
bool def) // @parm Valore default della varaibile (default FALSE)
// @comm Viene chiamata la funzione <mf TConfig::get>.
// <nl>Passando <p index> <gt>= 0 viene appeso al nome variabile per
// implementare un array.
// <nl>Il paragrafo passato in <p section> diventa quello attivo.
//
// @xref <mf TConfig::get> <mf TConfig::get_long> <mf TConfig::get_int>
// <mf TConfig::get_color>
{
const TString16 d(def ? "X" : "");
const TString& s = get(var, section, index, d).upper();
return s != "" && (s == "X" || s == "ON" || s == "YES" || s == "OK" || s == "TRUE");
}
// @doc EXTERNAL
// @mfunc Ritorna il valore del colore settato nella variabile nella
// sezione corrente o in quella specificata
COLOR TConfig::get_color(
const char* var, // @parm Variabile della quale ritornare il valore
const char* section, // @parm Sezione della varaibile (default NULL)
int index, // @parm Eventuale indice della varaibailie (default -1)
COLOR def) // @parm Valore default della varaibile (default 0)
// @comm Passando <p index> <gt>= 0 viene appeso al nome variabile per
// implementare un array.
// <nl>Il paragrafo passato in <p section> diventa quello attivo.
//
// @xref <mf TConfig::get> <mf TConfig::get_long> <mf TConfig::get_int>
// <mf TConfig::get_bool>
{
const char* c = get(var, section, index);
if (*c)
{
TToken_string s(c, ',');
const byte r = (byte)s.get_int();
const byte g = (byte)s.get_int();
const byte b = (byte)s.get_int();
def = RGB2COLOR(r, g, b);
}
else
{
TString16 d;
d.format("%d,%d,%d",
XVT_COLOR_GET_RED(def), XVT_COLOR_GET_GREEN(def), XVT_COLOR_GET_BLUE(def));
set(var, d, section, TRUE, index);
}
return def;
}
// @doc EXTERNAL
// @mfunc Setta la variabile nella sezione corrente o specificata
//
// @rdesc Ritorna i seguenti valori:
//
// @flag TRUE | Se la variabile era gia' esistente
// @flag FALSE | Se la variabile non era gia' esistente
bool TConfig::set(
const char* var, // @parm Nome della variabile da settare
const char* value, // @parm Stringa da assegnare alla variabile
const char* section, // @parm Nome del paragrafo a cui appartiene la variabile
bool force, // @parm Per la creazione di una variabile inesistente
int index) // @parm Eventuale indice della variabile
// @parm long | value | Valore da assegnare alla variabile
{
// @syntax set(const char* var, const char* value, const char* section, bool force, int index);
// @syntax set(const char* var, long value, const char* section, bool force, int index);
//
// @comm Se <p force> == TRUE crea il paragrafo e la variabile se non esistono;
// altrimenti da' errore.
// <nl>Passando <p index> <gt>= 0 viene appeso al nome variabile per
// implementare un array.
// <nl>Il paragrafo passato in <p section> diventa quello attivo.
if (section)
set_paragraph(section);
const bool itwas = exist(var, index);
if (itwas && !force)
warning_box("Tentativo di ridefinizione simbolo: %s(%d)", var, index);
else
{
TString256 vvar(var); if (index >= 0) vvar << '(' << index << ')';
_data.add(vvar, new TString(value), force);
_dirty = TRUE;
}
return itwas;
}
bool TConfig::set(const char* var, long value, const char* section,
bool force, int index)
{
TString16 t; t << value;
return set(var,t,section,force,index);
}
bool TConfig::set_color(const char* var, COLOR col, const char* section,
bool force, int index)
{
TString16 t;
t.format("%d,%d,%d", XVT_COLOR_GET_RED(col), XVT_COLOR_GET_GREEN(col), XVT_COLOR_GET_BLUE(col));
return set(var,t,section,force,index);
}
// @doc EXTERNAL
// @mfunc Ritorna quanti elementi dell'array nominato sono presenti nella
// sezione indicata.
word TConfig::items(
const char* var, // @parm Nome dell'array
const char* section) // @parm Sezione indicata
// @comm Il paragrafo passato in <p section> diventa quello attivo.
// <nl>Possono esserci dei "buchi" causati da set() errate
{
if (section) set_paragraph(section);
for (int cnt = 0; exist(var, cnt); cnt++);
return cnt;
}
// @doc EXTERNAL
// @mfunc Inizializza il paragrafo leggendo dal file i dati
void TConfig::init(
const char *fn, // @parm Nome del file da leggere
const char* pa) // @parm Nome del paragrafo da utilizzare
// @comm Apre il file <p fn> e cerca il paragrafo <p pa>. Se il file non esiste
// viene creato con il paragrafo passato.
{
_file = fn;
_paragraph = pa;
_dirty = FALSE;
if (!fexist(_file))
{
warning_box("Creazione del file di configurazione %s", fn );
ofstream c(fn);
c.close();
}
if (_paragraph.blank())
{
_paragraph = main_app().name();
_paragraph.cut(2);
}
_ispresent = _read_paragraph();
}
int TConfig::list_paragraphs(TString_array& pl)
{
TScanner s(_file);
pl.destroy();
while (s.line().not_empty())
{
if (s.token()[0] == '[')
{
TToken_string* p = new TToken_string(s.token());
p->strip("[]");
pl.add(p);
}
}
return pl.items();
}
int TConfig::list_variables(TString_array& vl, bool value, const char* section)
{
set_paragraph(section);
vl.destroy();
_data.restart();
for (int i = 0; i < _data.items(); i++)
{
THash_object* o = _data.get_hashobj();
TToken_string* t = new TToken_string(o->key());
if (value) t->add((TString&)(o->obj()));
vl.add(t);
}
return vl.items();
}
const TAssoc_array& TConfig::list_variables(const char* section)
{
set_paragraph(section);
return _data;
}
TConfig::TConfig(int which_config, const char* paragraph)
{
switch (which_config)
{
case CONFIG_DITTA:
_file << main_app().get_firm_dir() << '/' << "prassid.ini";
if (!fexist(_file))
fcopy("prassid.ini", _file);
break;
case CONFIG_STUDIO:
case CONFIG_USER:
case CONFIG_STAMPE:
_file = firm2dir(-1); // Directory dati
_file.add("config"); // Directory config
if (!fexist(_file)) // Creala se becessario
make_dir(_file);
switch (which_config)
{
case CONFIG_STUDIO:
_file.add("prassis.ini");
if (!fexist(_file))
fcopy("prassis.ini", _file);
break;
case CONFIG_STAMPE:
_file.add("print.ini");
break;
case CONFIG_USER:
{
TString16 u = user();
if (u.blank())
u = "PRASSI";
else
u.upper();
_file.add(u);
_file.ext("ini");
if (u != "PRASSI" && !fexist(_file))
{
TFilename prassi = _file.path();
prassi.add("prassi.ini");
fcopy(prassi, _file);
}
}
break;
default:
break;
}
break;
case CONFIG_FCONV:
_file = "fconv.ini";
break;
case CONFIG_GOLEM:
_file.add("golem.ini");
break;
default:
_file = "prassi.ini";
CHECK(0, "Chi ca$$o usa prassi.ini?");
break;
}
init(_file, paragraph);
}
TConfig::TConfig(const char *fn, const char* pa)
{ init(fn, pa); }
TConfig::~TConfig()
{
// il distruttore riscrive il file con le modifiche se necessario
if (_dirty) _write_file();
}