Files correlati : ba0 lv3 Ricompilazione Demo : [ ] Commento : Migliorata gestione schermi molto piccoli (240x320) git-svn-id: svn://10.65.10.50/trunk@19664 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			900 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			900 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <applicat.h>
 | 
						|
#include <colors.h>
 | 
						|
#include <config.h>
 | 
						|
#include <dongle.h>
 | 
						|
#include <scanner.h>
 | 
						|
#include <prefix.h>
 | 
						|
#include <utility.h>
 | 
						|
 | 
						|
#include <extcdecl.h>   // CGetPrawinName
 | 
						|
 | 
						|
bool TConfig::add_line(const TString& l)
 | 
						|
{
 | 
						|
  const int ind = l.find('=');
 | 
						|
  if (ind < 0)
 | 
						|
    return FALSE;
 | 
						|
 
 | 
						|
  TString256 key = l.left(ind); key.trim();
 | 
						|
  TString val = l.mid(ind+1); val.trim();
 | 
						|
 | 
						|
  if (val[0] == '%')
 | 
						|
  {
 | 
						|
    if (val == "%yr%")
 | 
						|
    {
 | 
						|
      struct tm * oggi = xvt_time_now();
 | 
						|
      if (oggi != NULL)
 | 
						|
        val.format("%04d", 1900 + oggi->tm_year);
 | 
						|
      else
 | 
						|
        NFCHECK("Impossibile reperire la data corrente del sistema.");
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (val == "%frm%") 
 | 
						|
        val.format("%05ld", prefix().get_codditta());
 | 
						|
    }
 | 
						|
  }
 | 
						|
  // sostituzione abilitata
 | 
						|
  return _data.add(key,val,TRUE);
 | 
						|
}
 | 
						|
 | 
						|
// @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
 | 
						|
    while(TRUE)
 | 
						|
    {
 | 
						|
      const TString& l = scan.line();
 | 
						|
      if (l.empty() || l[0] == '[') break;           // Fine paragrafo
 | 
						|
      if (l[0] == '#' || l[0] == '/') continue;      // Riga di commento
 | 
						|
      add_line(l);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  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';
 | 
						|
*/
 | 
						|
    TString_array a; list_variables(a, FALSE,_paragraph,TRUE); // get array sorted by varname
 | 
						|
    for (int i = 0; i < a.items(); i++)
 | 
						|
    {
 | 
						|
      TToken_string& name = a.row(i);
 | 
						|
      out << name << " = ";
 | 
						|
      out << get(name) << endl;
 | 
						|
    }
 | 
						|
 | 
						|
    out << endl;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TConfig::_write_file()
 | 
						|
{
 | 
						|
  if (_write_protected)
 | 
						|
    return;
 | 
						|
 | 
						|
  TFilename temp;
 | 
						|
  temp.temp("cnf");
 | 
						|
  ofstream out(temp);
 | 
						|
  if (!out.good())
 | 
						|
  {        
 | 
						|
    NFCHECK("Impossibile scrivere %s per aggiornare %s", 
 | 
						|
            (const char*)temp, (const char*)_file);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  bool skip = FALSE, done = FALSE, skip_empty = TRUE;
 | 
						|
    
 | 
						|
  if (_file.exist())  
 | 
						|
  {
 | 
						|
    ifstream in(_file);
 | 
						|
    if (in.good()) 
 | 
						|
    {
 | 
						|
      TString l(1024);
 | 
						|
      TString cnf; cnf << '[' << _paragraph << ']';
 | 
						|
      while (!in.eof())
 | 
						|
      {
 | 
						|
        in.getline(l.get_buffer(), 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;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      NFCHECK("Impossibile aggiornare il file %s", (const char*)_file);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  // new paragraph
 | 
						|
  if (!done) 
 | 
						|
    _write_paragraph(out);
 | 
						|
  out.close();
 | 
						|
 | 
						|
  if (fexist(_file))
 | 
						|
  {
 | 
						|
    while (xvt_fsys_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
 | 
						|
}
 | 
						|
 | 
						|
bool TConfig::set_paragraph(const char* section)
 | 
						|
{
 | 
						|
  bool ok = TRUE;
 | 
						|
  if (section != NULL && _paragraph != section)
 | 
						|
  {
 | 
						|
    if (_dirty)
 | 
						|
      _write_file();
 | 
						|
    _paragraph = section;
 | 
						|
    _dirty = FALSE;
 | 
						|
    _ispresent = _read_paragraph();
 | 
						|
     ok = _ispresent;
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
const char* TConfig::get_varkey(const char* var, int index) const
 | 
						|
{
 | 
						|
  if (index >= 0)
 | 
						|
  {
 | 
						|
    TString& tmp = get_tmp_string();
 | 
						|
    tmp << var << '(' << index << ')';
 | 
						|
    return tmp;
 | 
						|
  }
 | 
						|
  return var;
 | 
						|
}
 | 
						|
 | 
						|
// @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>.
 | 
						|
{
 | 
						|
  const char* key = get_varkey(var, index);
 | 
						|
  return _data.is_key(key);
 | 
						|
}
 | 
						|
 | 
						|
// @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>.
 | 
						|
{
 | 
						|
  const char* key = get_varkey(var, index);
 | 
						|
  const bool ok = _data.remove(key);
 | 
						|
  if (ok) _dirty = TRUE;
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TConfig::remove_all()
 | 
						|
{
 | 
						|
  if (_data.items() > 0)
 | 
						|
  {
 | 
						|
    _data.destroy();
 | 
						|
    _dirty = TRUE;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @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>
 | 
						|
const TString& TConfig::get(
 | 
						|
  const char* var,     // @parm Variabile della quale ritornare il valore
 | 
						|
  const char* section, // @parm Sezione della variabile (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 && *section)                            // Cambia paragrafo se necessario
 | 
						|
    set_paragraph(section);
 | 
						|
  
 | 
						|
  const char* key = get_varkey(var, index);
 | 
						|
  const TString* val = (TString*)_data.objptr(key);
 | 
						|
 | 
						|
  if (val == NULL)                        // Se non la trova inserisci il default
 | 
						|
  {      
 | 
						|
    if (def && *def)   
 | 
						|
    {
 | 
						|
      set(var, def, section, TRUE, index);
 | 
						|
      val = &get(var, NULL, index);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      val = &EMPTY_STRING;
 | 
						|
  }
 | 
						|
 | 
						|
  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 if (def != 0)
 | 
						|
  {
 | 
						|
    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 variabile (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 if (!isspace(def))            
 | 
						|
  {
 | 
						|
    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 char* d = def ? "X" : "";
 | 
						|
  TString& s = (TString&)get(var, section, index, d);
 | 
						|
  s.upper();
 | 
						|
  return s != "" && (s == "X" || s == "Y" || s == "1" || 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>
 | 
						|
{
 | 
						|
  TToken_string s(get(var, section, index), ',');
 | 
						|
  if (s.full())
 | 
						|
  {
 | 
						|
    if (s.find(',') > 0)
 | 
						|
    {
 | 
						|
      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
 | 
						|
    {
 | 
						|
      def = atol(s);
 | 
						|
      if (def == 0L) 
 | 
						|
        def = COLOR_BLACK;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  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 && *section)
 | 
						|
    set_paragraph(section);
 | 
						|
 | 
						|
  const char* key = get_varkey(var, index);
 | 
						|
  TString* val = (TString*)_data.objptr(key);
 | 
						|
  const bool itwas = val != NULL;
 | 
						|
 | 
						|
  if (itwas && !force)
 | 
						|
    error_box("Tentativo di ridefinizione simbolo: %s", (const char*)key);
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (itwas)
 | 
						|
    {
 | 
						|
      const TFixed_string str(value);
 | 
						|
      // Se la variabile esisteva ed aveva un valore diverso ...
 | 
						|
      if (*val != str && !(str.blank() && val->empty()))
 | 
						|
      {
 | 
						|
        *val = str;     // ... allora la sostituisco ...
 | 
						|
        val->trim();
 | 
						|
        _dirty = TRUE;  // ... e metto a dirty.
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      // Se la variabile non esisteva allora la aggiungo e metto a dirty.
 | 
						|
      val = new TString(value);
 | 
						|
      val->trim();
 | 
						|
      _data.add(key, val, TRUE);
 | 
						|
      _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
 | 
						|
{
 | 
						|
  int cnt;
 | 
						|
 | 
						|
  if (section && *section)
 | 
						|
    set_paragraph(section);
 | 
						|
  for (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;
 | 
						|
  _write_protected = FALSE;
 | 
						|
  
 | 
						|
  if (!_file.exist())
 | 
						|
  {
 | 
						|
    ofstream c(fn);
 | 
						|
    c.close();
 | 
						|
  }
 | 
						|
 | 
						|
  if (_paragraph.blank())
 | 
						|
  { 
 | 
						|
    _paragraph = main_app().name();
 | 
						|
    _paragraph.cut(2);         
 | 
						|
    _paragraph.lower();
 | 
						|
  }
 | 
						|
 | 
						|
  _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();
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN int compare_ini_variables(const TObject**o1, const TObject**o2)
 | 
						|
{
 | 
						|
  const TString* s1 = (const TString*)*o1;
 | 
						|
  const TString* s2 = (const TString*)*o2;
 | 
						|
  const int p1 = s1->find('(');
 | 
						|
  if (p1 < 0)
 | 
						|
    return strcmp(*s1, *s2);
 | 
						|
  else
 | 
						|
  {
 | 
						|
    // variabile tipo XX(i)
 | 
						|
    int result= strncmp(*s1, *s2,p1);
 | 
						|
    if (result==0)
 | 
						|
    {
 | 
						|
      if (s2->find('(')<0)
 | 
						|
        result = 1;
 | 
						|
      else
 | 
						|
      {
 | 
						|
        CHECKS(s1->find(')')>=0,"Errore: parentesi non chiusa in ",(const char *)(*s1));
 | 
						|
        CHECKS(s2->find(')')>=0,"Errore: parentesi non chiusa in ",(const char *)(*s2));
 | 
						|
        const int i1=atoi(s1->sub(p1+1,s1->len()-1));
 | 
						|
        const int i2=atoi(s2->sub(p1+1,s2->len()-1));
 | 
						|
        result = i1-i2;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TConfig::list_variables(TString_array& vl, bool value, const char* section, const bool sort)
 | 
						|
{              
 | 
						|
  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);
 | 
						|
  }
 | 
						|
 | 
						|
  if (sort)
 | 
						|
    vl.TArray::sort(compare_ini_variables);
 | 
						|
 | 
						|
  return vl.items();
 | 
						|
}
 | 
						|
 | 
						|
TAssoc_array& TConfig::list_variables(const char* section)
 | 
						|
{
 | 
						|
  set_paragraph(section);
 | 
						|
  return _data;
 | 
						|
}
 | 
						|
 | 
						|
int TConfig::for_each_paragraph(CONFIG_CALLBACK cfgcb, void* jolly)
 | 
						|
{
 | 
						|
  int count = 0;
 | 
						|
  TScanner scanner(_file);
 | 
						|
 | 
						|
  _paragraph.cut(0);
 | 
						|
  bool needs_call = FALSE;
 | 
						|
 | 
						|
  while (scanner.line().not_empty())
 | 
						|
  {
 | 
						|
    const TString& riga = scanner.token();
 | 
						|
    if (riga[0] == '[')
 | 
						|
    {
 | 
						|
      count++;
 | 
						|
      if (needs_call)
 | 
						|
      {
 | 
						|
        needs_call = FALSE;
 | 
						|
        if (cfgcb && cfgcb(*this, jolly))
 | 
						|
          break;
 | 
						|
      }
 | 
						|
      _paragraph = riga;
 | 
						|
      _paragraph.strip("[]");
 | 
						|
      _data.destroy();
 | 
						|
      needs_call = TRUE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      add_line(riga);
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (needs_call && cfgcb)
 | 
						|
    cfgcb(*this, jolly);
 | 
						|
 | 
						|
  return count;
 | 
						|
}
 | 
						|
 | 
						|
static void cfg2file(int which_config, TFilename& file)
 | 
						|
{
 | 
						|
  switch (which_config)
 | 
						|
  {
 | 
						|
  case CONFIG_GENERAL:
 | 
						|
    file = "./install.ini";
 | 
						|
    break;
 | 
						|
  case CONFIG_DITTA:
 | 
						|
    file = firm2dir(prefix().get_codditta());
 | 
						|
    file.add("ditta.ini");
 | 
						|
    if (!file.exist())
 | 
						|
		{
 | 
						|
			TFilename oldfile = file;
 | 
						|
      const int pos = oldfile.find("ditta.ini");
 | 
						|
      oldfile.cut(pos);
 | 
						|
      oldfile.add("prassid.ini"); // Old config file!
 | 
						|
			if (oldfile.exist())
 | 
						|
        fcopy(oldfile, file);   
 | 
						|
		}
 | 
						|
    break;
 | 
						|
  case CONFIG_STUDIO:
 | 
						|
  case CONFIG_STAMPE:
 | 
						|
  case CONFIG_GUI:
 | 
						|
  case CONFIG_USER:
 | 
						|
  case CONFIG_WST:
 | 
						|
    file = firm2dir(-1);       // Directory dati
 | 
						|
    file.add("config");        // + Directory config
 | 
						|
    if (!file.exist())         // Creala se necessario
 | 
						|
      make_dir(file);
 | 
						|
 | 
						|
    switch (which_config)
 | 
						|
    {
 | 
						|
    case CONFIG_STUDIO:
 | 
						|
      file.add("studio.ini");
 | 
						|
      if (!file.exist())
 | 
						|
		  {
 | 
						|
			  TFilename oldfile = file;
 | 
						|
        const int pos = oldfile.find("studio.ini");
 | 
						|
        oldfile.cut(pos);
 | 
						|
        oldfile.add("prassis.ini"); // Old config file!
 | 
						|
			  if (oldfile.exist())
 | 
						|
          fcopy(oldfile, file);   
 | 
						|
		  }
 | 
						|
      break;
 | 
						|
    case CONFIG_STAMPE:
 | 
						|
      file.add("print.ini");
 | 
						|
      break;
 | 
						|
    case CONFIG_GUI:
 | 
						|
      {
 | 
						|
        TFilename gui = "gui.ini";
 | 
						|
        if (gui.custom_path()) 
 | 
						|
        {
 | 
						|
          file = gui; // I colori sono qui ...
 | 
						|
          break;      // ... scavalca utente
 | 
						|
        }
 | 
						|
      }
 | 
						|
    case CONFIG_USER:
 | 
						|
      {
 | 
						|
        TString80 u = user();
 | 
						|
        if (u.blank())
 | 
						|
          u = ::dongle().administrator();
 | 
						|
        u.lower();
 | 
						|
        file.add(u);
 | 
						|
        file.ext("ini");
 | 
						|
        if (u != "admin" && !file.exist())
 | 
						|
        {
 | 
						|
          TFilename prassi = file.path();
 | 
						|
          prassi.add("admin.ini");
 | 
						|
          fcopy(prassi, file);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case CONFIG_WST:
 | 
						|
      {
 | 
						|
        TString80 u = get_hostname();
 | 
						|
        if (u.blank())
 | 
						|
          u = "localhost";
 | 
						|
        u.lower();
 | 
						|
        file.add(u);
 | 
						|
        file.ext("ini");
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case CONFIG_FCONV:
 | 
						|
    file = "fconv.ini";
 | 
						|
    break;
 | 
						|
  case CONFIG_INSTALL:
 | 
						|
    file = CGetCampoIni();
 | 
						|
    break;
 | 
						|
  case CONFIG_OEM:
 | 
						|
    file = "setup/oem.ini";
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    NFCHECK("Chi usa questo strano .ini?");
 | 
						|
    break;
 | 
						|
  }  
 | 
						|
}
 | 
						|
 | 
						|
TConfig::TConfig(int which_config, const char* paragraph)
 | 
						|
{
 | 
						|
  cfg2file(which_config, _file);
 | 
						|
  init(_file, paragraph);
 | 
						|
}
 | 
						|
 | 
						|
TConfig::TConfig(const char *fn, const char* pa)
 | 
						|
{
 | 
						|
  TFilename f(fn);
 | 
						|
  f.custom_path();
 | 
						|
  init(f, pa); 
 | 
						|
}
 | 
						|
 | 
						|
TConfig::~TConfig()
 | 
						|
{
 | 
						|
  // il distruttore riscrive il file con le modifiche se necessario
 | 
						|
  if (_dirty && !_write_protected)
 | 
						|
    _write_file();
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Utilities
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#define DECLARE_VARNAME(name, idx) const char* varname = idx >= 0 ? (const char*)(get_tmp_string() << name << '(' << idx << ')') : name
 | 
						|
#define DECLARE_FILENAME(cfg) TFilename filename; cfg2file(cfg, filename)
 | 
						|
 | 
						|
const TString& ini_get_string(const char* file, const char* paragraph, const char* name, const char* defval, int idx)
 | 
						|
{
 | 
						|
  DECLARE_VARNAME(name, idx);
 | 
						|
  TString& tmp = get_tmp_string();
 | 
						|
  const int len = xvt_sys_get_profile_string(file, paragraph, varname, defval,  tmp.get_buffer(), tmp.size());
 | 
						|
  if (len > tmp.size())
 | 
						|
  {
 | 
						|
    tmp.get_buffer(len);
 | 
						|
    xvt_sys_get_profile_string(file, paragraph, varname, defval,  tmp.get_buffer(), tmp.size());
 | 
						|
  }
 | 
						|
  if (tmp[0] == '"')
 | 
						|
  {
 | 
						|
    tmp.rtrim(1);
 | 
						|
    tmp.ltrim(1);
 | 
						|
  }
 | 
						|
  return tmp;
 | 
						|
}
 | 
						|
 | 
						|
bool ini_set_string(const char* file, const char* paragraph, const char* name, const char* val, int idx)
 | 
						|
{
 | 
						|
  DECLARE_VARNAME(name, idx);
 | 
						|
  return xvt_sys_set_profile_string(file, paragraph, varname, val) != 0;
 | 
						|
}
 | 
						|
 | 
						|
bool ini_get_bool(const char* file, const char* para, const char* name, bool defval, int idx)
 | 
						|
{
 | 
						|
  const char b = ini_get_string(file, para, name, defval ? "1" : "0", idx)[0];
 | 
						|
  return b ? (strchr("XY1", b) != NULL) : defval;
 | 
						|
}
 | 
						|
 | 
						|
bool ini_get_bool(int cfg, const char* para, const char* name, bool defval, int idx)
 | 
						|
{
 | 
						|
  DECLARE_FILENAME(cfg);
 | 
						|
  return ini_get_bool(filename, para, name, defval, idx);
 | 
						|
}
 | 
						|
 | 
						|
int ini_get_int(const char* file, const char* para, const char* name, int defval, int idx)
 | 
						|
{
 | 
						|
  DECLARE_VARNAME(name, idx);
 | 
						|
  return xvt_sys_get_profile_int(file, para, name, defval);
 | 
						|
}
 | 
						|
 | 
						|
bool ini_set_int(const char* file, const char* paragraph, const char* name, int val, int idx)
 | 
						|
{
 | 
						|
  TString16 value; value << val;
 | 
						|
  return ini_set_string(file, paragraph, name, value, idx);
 | 
						|
}
 | 
						|
 | 
						|
bool ini_set_bool(const char* file, const char* paragraph, const char* name, bool val, int idx)
 | 
						|
{
 | 
						|
  return ini_set_string(file, paragraph, name, val ? "1" : "0", idx);
 | 
						|
}
 | 
						|
 | 
						|
const TString& ini_get_string(int cfg, const char* paragraph, const char* name, const char* defval, int idx)
 | 
						|
{
 | 
						|
  DECLARE_FILENAME(cfg);
 | 
						|
  return ini_get_string(filename, paragraph, name, defval, idx);
 | 
						|
}
 | 
						|
 | 
						|
bool ini_set_string(int cfg, const char* paragraph, const char* name, const char* val, int idx)
 | 
						|
{
 | 
						|
  DECLARE_FILENAME(cfg);
 | 
						|
  return ini_set_string(filename, paragraph, name, val);
 | 
						|
}
 | 
						|
 | 
						|
int ini_get_int(int cfg, const char* paragraph, const char* name, int defval, int idx)
 | 
						|
{
 | 
						|
  DECLARE_FILENAME(cfg);
 | 
						|
  return ini_get_int(filename, paragraph, name, defval, idx);
 | 
						|
}
 | 
						|
 | 
						|
bool ini_set_int(int cfg, const char* paragraph, const char* name, int val, int idx)
 | 
						|
{
 | 
						|
  DECLARE_FILENAME(cfg);
 | 
						|
  return ini_set_int(filename, paragraph, name, val, idx);
 | 
						|
}
 | 
						|
 | 
						|
bool ini_set_bool(int cfg, const char* paragraph, const char* name, bool val, int idx)
 | 
						|
{
 | 
						|
  DECLARE_FILENAME(cfg);
 | 
						|
  return ini_set_string(filename, paragraph, name, val ? "1" : "0", idx);
 | 
						|
}
 | 
						|
 | 
						|
const TString& get_oem_info(const char* varname)
 | 
						|
{
 | 
						|
  TString& tmp = get_tmp_string(50);
 | 
						|
  xvt_sys_get_oem_string(varname, tmp, tmp.get_buffer(), tmp.size());
 | 
						|
  return tmp;
 | 
						|
}
 |