bf819df0be
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
607 lines
17 KiB
C++
Executable File
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();
|
|
}
|
|
|