Migliorata gestione variabili insestenti nel TConfig Segato via _isatab dai TLocalisamfile Cambiata la finestra di F_11 nelle maschere Corretto errore nella TPrintrow::encoded_row() (resa pure const) Aggiunto bottone di global un/check negli sheet git-svn-id: svn://10.65.10.50/trunk@832 c028cbd2-c16b-5b4b-a496-9718f37d4682
274 lines
6.4 KiB
C++
Executable File
274 lines
6.4 KiB
C++
Executable File
#include <stdlib.h>
|
|
|
|
#include <applicat.h>
|
|
#include <config.h>
|
|
#include <utility.h>
|
|
#include <scanner.h>
|
|
|
|
HIDDEN const char * files[] = {"prassi.ini", "prassis.ini",
|
|
"prassid.ini", "fconv.ini"};
|
|
|
|
extern "C"
|
|
{
|
|
int rename(const char*, const char*);
|
|
};
|
|
|
|
bool TConfig::_read_paragraph()
|
|
// ritorna TRUE se il paragrafo c'era, FALSE altrimenti
|
|
{
|
|
bool itwas = FALSE;
|
|
_data.destroy();
|
|
TScanner scan(_file);
|
|
if (scan.paragraph(_paragraph))
|
|
{
|
|
itwas = TRUE;
|
|
// populate array
|
|
TString l, key, val;
|
|
for (;;)
|
|
{
|
|
l = scan.line();
|
|
if (l[0] == '#') continue;
|
|
if (l == "" || l[0] == '[') break;
|
|
int ind = l.find('=');
|
|
if (ind == -1)
|
|
{
|
|
warning_box("Errore configurazione: file %s, vicino alla riga %ud",
|
|
(const char*)_file, scan.linenum());
|
|
continue;
|
|
}
|
|
|
|
key = l.left(ind); key.trim();
|
|
val = l.mid(ind+1); val.trim();
|
|
// sostituzione abilitata
|
|
_data.add(key,val,TRUE);
|
|
}
|
|
}
|
|
return itwas;
|
|
}
|
|
|
|
void TConfig::_write_paragraph(ofstream& out)
|
|
{
|
|
_data.restart();
|
|
TString cnf(16);
|
|
cnf << '[' << _paragraph << ']';
|
|
out << cnf << '\n';
|
|
for (int i = 0; i < _data.items(); i++)
|
|
{
|
|
THash_object* o = _data.get_hashobj();
|
|
out << o->key() << "\t= " << (TString&)(o->obj()) << '\n';
|
|
}
|
|
out << '\n';
|
|
}
|
|
|
|
void TConfig::_write_file()
|
|
{
|
|
ifstream in(_file);
|
|
TFilename temp;
|
|
temp.temp("cnf");
|
|
ofstream out(temp);
|
|
|
|
TFixed_string l(__tmp_string, sizeof(__tmp_string));
|
|
TString cnf(16);
|
|
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();
|
|
TFilename bak(_file); bak.ext("bak");
|
|
rename(_file, bak);
|
|
fcopy(temp, _file); // Copia dalla tempdir al nuovo .ini
|
|
remove(temp); // Cancella file temporaneo
|
|
}
|
|
|
|
|
|
void TConfig::_check_paragraph(const char* section)
|
|
{
|
|
if (section != NULL && section != _paragraph)
|
|
{
|
|
if (_dirty) _write_file();
|
|
_paragraph = section;
|
|
_dirty = FALSE;
|
|
_read_paragraph();
|
|
}
|
|
}
|
|
|
|
bool TConfig::exist(const char* var, int index)
|
|
{
|
|
TString80 vvar(var);
|
|
if (index != -1) vvar << '(' << index << ')';
|
|
return _data.is_key(vvar);
|
|
}
|
|
|
|
TString& TConfig::get(const char* var, const char* section, int index, const char* def)
|
|
{
|
|
// ritorna valore di variabile nella sezione corrente o in
|
|
// quella specificata
|
|
static TFixed_string s(__tmp_string, 256);
|
|
TString80 vvar(var); if (index != -1) vvar << '(' << index << ')';
|
|
|
|
_check_paragraph(section);
|
|
|
|
if (_data.is_key(vvar))
|
|
s = (TString&)_data[vvar];
|
|
else
|
|
{
|
|
s = def;
|
|
if (s.not_empty())
|
|
set(var, s, section, TRUE, index);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
long TConfig::get_long(const char* var, const char* section, int index, long def)
|
|
{
|
|
const char* n = get(var,section,index);
|
|
if (*n)
|
|
def = atol(n);
|
|
else
|
|
set(var, format("%ld", def), section, TRUE, index);
|
|
return def;
|
|
}
|
|
|
|
bool TConfig::get_bool(const char* var, const char* section, int index, bool def)
|
|
{
|
|
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;
|
|
}
|
|
|
|
COLOR TConfig::get_color(const char* var, const char* section, int index, COLOR def)
|
|
{
|
|
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;
|
|
}
|
|
|
|
bool TConfig::set(const char* var, const char* value, const char* section,
|
|
bool force, int index)
|
|
{
|
|
// setta variabile nella sezione corrente o specificata
|
|
// se force == TRUE crea la variabile se non esiste; altrimenti
|
|
// da' errore; ritorna TRUE se la variabile c'era, FALSE diversamente
|
|
|
|
_check_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);
|
|
}
|
|
|
|
word TConfig::items(const char* var, const char* section)
|
|
{
|
|
_check_paragraph(section);
|
|
TString vvar(16);
|
|
for (int cnt = 0; /* uncazzo */ ;cnt++)
|
|
{
|
|
vvar = var; vvar << '(' << cnt << ')';
|
|
if (!_data.is_key(var))
|
|
break;
|
|
}
|
|
return cnt;
|
|
}
|
|
|
|
void TConfig::init(const char *fn, const char* pa)
|
|
{
|
|
_file = fn;
|
|
_paragraph = pa;
|
|
_dirty = FALSE;
|
|
|
|
if (!fexist(_file))
|
|
fatal_box("Impossibile aprire il file di configurazione %s", fn );
|
|
|
|
if (_paragraph.empty())
|
|
{
|
|
_paragraph = main_app().name();
|
|
_paragraph.cut(2);
|
|
}
|
|
_ispresent = _read_paragraph();
|
|
}
|
|
|
|
|
|
TConfig::TConfig(int which_config, const char* paragraph)
|
|
: _file(files[which_config])
|
|
{
|
|
if (which_config == CONFIG_DITTA)
|
|
{
|
|
_file.insert(format("%s/", main_app().get_firm_dir()));
|
|
if (!fexist(_file))
|
|
fcopy(files[CONFIG_DITTA], _file);
|
|
}
|
|
if (!fexist(_file))
|
|
fatal_box("Impossibile aprire la configurazione %s",
|
|
which_config == CONFIG_GENERAL ? "generale" :
|
|
which_config == CONFIG_STUDIO ? "di studio" :
|
|
which_config == CONFIG_DITTA ? "della ditta": "per la conversione archivi");
|
|
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();
|
|
}
|
|
|