campo-sirio/include/config.cpp
guy 2fbfb0a6b5 cfiles, isam Correzioni gestione date su file
controls 	Corretta sottolineatura dell'acceleratore dei bottoni
config          Risolto conflitto sulla correzione di prassis.ini
checks          Editato per errore
default.url     Aggiunto acceleratore ALT-F


git-svn-id: svn://10.65.10.50/trunk@1547 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-07-03 16:19:39 +00:00

497 lines
14 KiB
C++
Executable File

#include <io.h>
#include <stdlib.h>
#include <xvt.h>
#include <applicat.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 INTERNAL
// @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: file %s, vicino alla riga %ud: %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;
}
// @mfunc Scrive i dati del paragrafo
void TConfig::_write_paragraph(
ofstream& out) // @parm Indirizzo dell'utput sul quale scrivere il paragrafo
// @comm Scrive le variabili del paragrafo attivo. Nel caso il paragrafo non
// era presente viene aggiunto nel file.
{
_data.restart();
out << '[' << _paragraph << ']' << endl;
for (int i = 0; i < _data.items(); i++)
{
THash_object* o = _data.get_hashobj();
out << o->key() << "\t= " << (TString&)(o->obj()) << '\n';
}
out << endl;
}
void TConfig::_write_file()
{
ifstream in(_file);
TFilename temp;
temp.temp("cnf");
ofstream out(temp);
TFixed_string l(__tmp_string, sizeof(__tmp_string));
TString80 cnf; cnf << '[' << _paragraph << ']';
bool skip = FALSE, done = FALSE;
while (!in.eof())
{
in.getline(__tmp_string,sizeof(__tmp_string)-1);
l.trim();
if (cnf == l)
{
// write paragraph and all variables
_write_paragraph(out);
skip = TRUE; done = TRUE;
}
else
{
if (skip) skip = l[0] != '[';
if (!skip) out << l << '\n';
}
}
// new paragraph
if (!done) _write_paragraph(out);
out.close(); in.close();
if (_file[0] > 'B' || _file[1] != ':') // Non creare il .bak su dischetto
{
while (access(_file, 02) != 0)
message_box("Il file %s e' gia' in uso", (const char*)_file);
TFilename bak(_file); bak.ext("bak");
rename(_file, bak);
}
fcopy(temp, _file); // Copia dalla tempdir al nuovo .ini
remove(temp); // Cancella file temporaneo
}
// @doc EXTERNAL
void TConfig::set_paragraph(const char* section)
{
if (section != NULL && section != _paragraph)
{
if (_dirty) _write_file();
_paragraph = section;
_dirty = FALSE;
_read_paragraph();
}
}
// @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)
{
TString80 vvar(var);
vvar << '(' << index << ')';
return _data.is_key(vvar);
}
return _data.is_key(var);
}
// @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>
{
HIDDEN TString256 s;
const char* v = var;
if (index >= 0) // Mette indice tra parentesi
{
s = var;
s << '(' << index << ')';
v = s;
}
set_paragraph(section);
if (_data.is_key(v))
s = (TString&)_data[v];
else
{
s = def;
if (s.not_empty())
set(var, def, section, TRUE, index);
}
return s;
}
// @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
set(var, format("%ld", def), section, TRUE, index);
return def;
}
// @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);
}
// @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>
{
if (def) strcpy(__tmp_string, "X");
else *__tmp_string = '\0';
const TString& s = get(var, section, index, __tmp_string).upper();
return s != "" && (s == "X" || s == "ON" || s == "YES" || s == "OK" || s == "TRUE");
}
HIDDEN void RGB_COLOR(COLOR c, int& r, int& g, int& b)
{
r = int(c >> 16) & 0xFF;
g = int(c >> 8) & 0xFF;
b = int(c) & 0xFF;
}
// @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 int r = s.get_int();
const int g = s.get_int();
const int b = s.get_int();
def = MAKE_COLOR(r, g, b);
}
else
{
int r, g, b; RGB_COLOR(def, r, g, b);
set(var, format("%d,%d,%d", r, g, b), section, TRUE, index);
}
return def;
}
// @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.
set_paragraph(section);
TString vvar(var); if (index != -1) vvar << '(' << index << ')';
bool itwas = _data.is_key(vvar);
if (itwas && !force)
warning_box("Tentativo di ridefinizione simbolo: %s", (const char*)vvar);
else
{
_dirty = TRUE;
_data.add(vvar, new TString(value), force);
}
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);
}
// @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
{
set_paragraph(section);
TString vvar(16);
for (int cnt = 0; /* uncazzo */ ;cnt++)
{
vvar = var; vvar << '(' << cnt << ')';
if (!_data.is_key(var))
break;
}
return cnt;
}
// @doc INTERNAL
// @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.empty())
{
_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();
}
// @doc EXTERNAL
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");
if (!fexist(_file))
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;
default:
if (user().not_empty())
_file.add(user());
else
_file.add("prassi");
_file.ext("ini");
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();
}