Files correlati : agalib.lib Ricompilazione Demo : [ ] Commento : Aggiunto valore di ritorno agli handler delle finestre void TWindow::handler(WINDOW win, EVENT* e) e' diventato long TWindow::handler(WINDOW win, EVENT* e) git-svn-id: svn://10.65.10.50/trunk@19478 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			4788 lines
		
	
	
		
			120 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			4788 lines
		
	
	
		
			120 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#define __FORM_CPP
 | 
						||
 | 
						||
#include <applicat.h>
 | 
						||
#include <defmask.h>
 | 
						||
#include <expr.h>
 | 
						||
#include <form.h>
 | 
						||
#include <msksheet.h>
 | 
						||
#include <printer.h>
 | 
						||
#include <relation.h>
 | 
						||
#include <recarray.h>
 | 
						||
#include <tabutil.h>
 | 
						||
#include <utility.h> 
 | 
						||
 | 
						||
#include "../ba/bafrm.h"
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Utility functions
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
 | 
						||
// @doc INTERNAL
 | 
						||
 | 
						||
// @func Funzione che converte dalla notazione carattere al corrispondente
 | 
						||
//       enum <t pagetype>
 | 
						||
//
 | 
						||
// @rdesc Ritorna il <t pagetype> corrispondente
 | 
						||
pagetype char2page(
 | 
						||
         char c)  // @parm Notazione carattere del tipo di pagina
 | 
						||
         
 | 
						||
{  
 | 
						||
  pagetype pt;
 | 
						||
  switch(c)
 | 
						||
  {
 | 
						||
  case '1':
 | 
						||
  case 'E':
 | 
						||
    pt = even_page; break;
 | 
						||
  case '2':
 | 
						||
  case 'F':
 | 
						||
    pt = first_page; break;
 | 
						||
  case '3':
 | 
						||
  case 'L':
 | 
						||
    pt = last_page; break;
 | 
						||
  default:
 | 
						||
    pt = odd_page; break;   
 | 
						||
  }
 | 
						||
  return pt;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_flags
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TForm_flags::TForm_flags()
 | 
						||
{
 | 
						||
  automagic = dirty = finkr = finkl = memo = newpage = price = FALSE;
 | 
						||
  shown = enabled  = TRUE;
 | 
						||
}
 | 
						||
 | 
						||
// Read from string
 | 
						||
// Certified 100%
 | 
						||
bool TForm_flags::update(const char* s)
 | 
						||
{
 | 
						||
  CHECK(s, "NULL flags string");
 | 
						||
  for (; *s; s++) switch(toupper(*s))
 | 
						||
  {
 | 
						||
  case 'A': 
 | 
						||
    automagic = TRUE; break;
 | 
						||
  case 'D': 
 | 
						||
    enabled = FALSE; break;
 | 
						||
  case 'H': 
 | 
						||
    shown = FALSE; break;
 | 
						||
  case 'F': 
 | 
						||
    finkl = TRUE; break;
 | 
						||
  case 'K': 
 | 
						||
    finkr = TRUE; break;
 | 
						||
  case 'M':
 | 
						||
    memo = TRUE; break;
 | 
						||
  case 'N':
 | 
						||
    newpage = TRUE; break;
 | 
						||
  case 'U':
 | 
						||
    price = TRUE; break;
 | 
						||
  default : 
 | 
						||
    error_box("Unknown form item flag '%c'", *s); break;
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Print on stream
 | 
						||
// Certified 100%
 | 
						||
void TForm_flags::print_on(ostream& out) const
 | 
						||
{
 | 
						||
  TString16 s;
 | 
						||
 | 
						||
  if (automagic) s << "A";
 | 
						||
  if (!enabled) s << "D";
 | 
						||
  if (!shown) s << "H";
 | 
						||
  if (memo) s << "M";
 | 
						||
  if (newpage) s << "N";
 | 
						||
  if (finkl) s << "F";
 | 
						||
  if (finkr) s << "K";
 | 
						||
  if (price) s << "U";
 | 
						||
 | 
						||
  if (s.not_empty()) 
 | 
						||
    out << " FLAGS \"" << s << '"' << endl;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_item
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
TForm_item::TForm_item(TPrint_section* section)
 | 
						||
: _temp(FALSE), _section(section), _id(0), _x(-1), _y(-1), 
 | 
						||
  _width(0), _height(0), _effective_height(0),
 | 
						||
  _ofs(0)
 | 
						||
{}
 | 
						||
 | 
						||
void TForm_item::copy_to_form_item(TForm_item* fi) const
 | 
						||
{
 | 
						||
  fi->_flag = _flag; fi->_group = _group;
 | 
						||
  
 | 
						||
  /* come copiarlo facendo una cosa orrenda...
 | 
						||
  fi->_special.destroy();
 | 
						||
  specials().restart();
 | 
						||
  int items = special_items();
 | 
						||
  for (int k = 0; k < items; k++)
 | 
						||
  {
 | 
						||
    THash_object*  ho = specials().get_hashobj();
 | 
						||
    fi->_special.add(ho->key(),ho->obj());
 | 
						||
  }
 | 
						||
  */
 | 
						||
  fi->_special = _special; // sarebbe utile avere un "operator =" per i TAssoc_array
 | 
						||
 | 
						||
  fi->_temp = _temp; fi->_id = _id;
 | 
						||
  fi->_x = _x; fi->_y = _y;
 | 
						||
  fi->_width = _width; fi->_height = _height;
 | 
						||
  fi->_effective_height = _effective_height;
 | 
						||
  fi->_ofs = _ofs;  fi->_prompt = _prompt;
 | 
						||
  fi->_desc = _desc; fi->_col_head = _col_head;
 | 
						||
  
 | 
						||
  /* Anche qui... copia uno alla volta
 | 
						||
  items = _message.items();
 | 
						||
  for (k = 0; k < items; k++)
 | 
						||
    fi->_message.add(_message.row(k),k);
 | 
						||
  */    
 | 
						||
  fi->_message = _message; // sarebbe utile avere un "operator =" per i TString_array
 | 
						||
}
 | 
						||
 | 
						||
TObject* TForm_item::dup() const
 | 
						||
{
 | 
						||
  TForm_item * fi = new TForm_item(_section);
 | 
						||
  copy_to_form_item(fi);
 | 
						||
  return fi;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_item::parse_head(TScanner& scanner)
 | 
						||
{
 | 
						||
  _id = scanner.integer();
 | 
						||
 | 
						||
  if (_id == 0)                             // Temporary
 | 
						||
    _id = _section->fields()+1;
 | 
						||
 | 
						||
  _width  = scanner.integer();
 | 
						||
  if (_width > 0)
 | 
						||
    _height = scanner.integer();
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TForm_item::print_on(ostream& out) const
 | 
						||
{
 | 
						||
  out << class_name() << ' ' << id();
 | 
						||
  if (_width > 0)
 | 
						||
  {
 | 
						||
    out << ' ' << _width;
 | 
						||
    if (_height > 0)
 | 
						||
      out << ' ' << _height;
 | 
						||
  }
 | 
						||
  out << "\nBEGIN\n";
 | 
						||
 | 
						||
  print_body(out);
 | 
						||
 | 
						||
  out << "END\n" << endl;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TForm_item::print_body(ostream& out) const
 | 
						||
{
 | 
						||
  out << " KEY \"" << _desc << "\"\n";
 | 
						||
 | 
						||
  if (_y >= 0)
 | 
						||
    out << " PROMPT " << _x << ' ' << _y << " \"" << _prompt << "\"\n";
 | 
						||
 | 
						||
  if (_group.ones())
 | 
						||
    out << " GROUP " << _group << "\n";
 | 
						||
 | 
						||
  out << _flag;
 | 
						||
 | 
						||
  if (_message.items() == 1)
 | 
						||
  {
 | 
						||
    const TToken_string& m = _message.row(0);
 | 
						||
    if (!m.empty_items())
 | 
						||
      out << " MESSAGE " << m << endl;
 | 
						||
  }
 | 
						||
 | 
						||
  if (_special.items() > 0)
 | 
						||
  {
 | 
						||
    TAssoc_array& aa = specials();
 | 
						||
    aa.restart();
 | 
						||
 | 
						||
    THash_object* op;
 | 
						||
 | 
						||
    while ((op = aa.get_hashobj()) != NULL)
 | 
						||
    {
 | 
						||
      TToken_string& t = (TToken_string&)op->obj();
 | 
						||
      TString typ(t.get(0));
 | 
						||
      TString val(t.get(1));
 | 
						||
      TString des(t.get(2));
 | 
						||
      out << " SPECIAL " << typ << " " << op->key()
 | 
						||
          << " \"" << val << "\" \"" << des << "\"\n";
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_item::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (scanner.key() == "PR")
 | 
						||
  {
 | 
						||
    _x = scanner.integer();
 | 
						||
    _y = scanner.integer();
 | 
						||
    _prompt = scanner.string();
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  if (scanner.key() == "FL")
 | 
						||
    return _flag.update(scanner.string());
 | 
						||
 | 
						||
  if (scanner.key() == "ME")
 | 
						||
  {
 | 
						||
    TFixed_string m(scanner.line());
 | 
						||
    m.strip_spaces();
 | 
						||
    int n = 0;
 | 
						||
    if (m.left(5) == "EMPTY")
 | 
						||
    {
 | 
						||
      n = 1;
 | 
						||
      m.ltrim(5);
 | 
						||
    }
 | 
						||
    if (!m.blank())
 | 
						||
      message(n).add(m);
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  if (scanner.key() == "KE")
 | 
						||
  {
 | 
						||
    _desc = scanner.string();
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  if (scanner.key() == "GR")
 | 
						||
  {
 | 
						||
    _group.set(scanner.line());
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  if (scanner.key() == "SP")
 | 
						||
  {
 | 
						||
    TToken_string val(scanner.pop());
 | 
						||
    TString16 var = scanner.pop();
 | 
						||
    val.add(scanner.string());
 | 
						||
    val.add(scanner.string());
 | 
						||
 | 
						||
    _special.add(var,val);
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  yesnofatal_box("Unknown symbol in item '%s': '%s'",
 | 
						||
                 (const char*)key(), (const char*)scanner.token());
 | 
						||
 | 
						||
  return FALSE;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_item::parse(TScanner& scanner)
 | 
						||
{
 | 
						||
  bool ok = parse_head(scanner);
 | 
						||
 | 
						||
  if (ok && scanner.popkey() != "BE")
 | 
						||
    ok = yesnofatal_box("Missing BEGIN in form item %s", (const char*)key());
 | 
						||
 | 
						||
  while (ok && scanner.popkey() != "EN")
 | 
						||
    ok = parse_item(scanner);
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_item::read_from(const TRectype& prof)
 | 
						||
{
 | 
						||
  CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
 | 
						||
  bool changed = FALSE;
 | 
						||
 | 
						||
  int i = prof.get_int("X");
 | 
						||
  if (_x != i)
 | 
						||
  {
 | 
						||
    _x = i;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
  i = prof.get_int("Y");
 | 
						||
  if (_y != i)
 | 
						||
  {
 | 
						||
    _y = i;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
  i = prof.get_int("LEN");
 | 
						||
  if (_width != i)
 | 
						||
  {
 | 
						||
    _width = i;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
  i = prof.get_int("HGT");
 | 
						||
  if (_height != i)
 | 
						||
  {
 | 
						||
    _height = i;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
  TString p(prof.get("PROMPT"));
 | 
						||
  if (p.not_empty())
 | 
						||
  {
 | 
						||
    if (p[0] == '\xFE') p.cut(0);
 | 
						||
    const int l = p.len();
 | 
						||
    if (l > 0 && p[l-1] == '\xFF')
 | 
						||
    {
 | 
						||
      p[l-1] = ' ';
 | 
						||
      p << '\0';
 | 
						||
    }
 | 
						||
    _prompt = p;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  const bool s = prof.get_bool("ATTIVO");
 | 
						||
  if (_flag.shown != s)
 | 
						||
  {
 | 
						||
    _flag.shown = s;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  TToken_string special(prof.get("SPECIAL"),'\n');
 | 
						||
  special.rtrim();
 | 
						||
  const int sp_items = special.items();
 | 
						||
  for (i = 0; i < sp_items; i++)
 | 
						||
  {
 | 
						||
    TToken_string sp(special.get(i), '$');
 | 
						||
    TString key(sp.get(0));
 | 
						||
    TString val(sp.get(1));
 | 
						||
 | 
						||
    if (!_special.is_key(key))
 | 
						||
    {
 | 
						||
      error_box(FR("Variabile speciale non presente nel profilo: %s"),
 | 
						||
                 (const char*)key);
 | 
						||
      continue;
 | 
						||
    }
 | 
						||
    TToken_string& tt = (TToken_string&)_special[key];
 | 
						||
    tt.add(val,1);
 | 
						||
    // forza riscrittura su memo
 | 
						||
    if (tt.items() == 3) tt.add("X");
 | 
						||
  }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::print_on(TRectype& prof)
 | 
						||
{
 | 
						||
  CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
 | 
						||
  prof.put("ID", id());
 | 
						||
  prof.put("X", _x);
 | 
						||
  prof.put("Y", _y);
 | 
						||
  prof.put("LEN", width());
 | 
						||
  prof.put("HGT", height());
 | 
						||
  if (_prompt.empty()) _prompt << '\xFE' << '\0';
 | 
						||
  const int l = _prompt.len();
 | 
						||
  const char c = _prompt[l-1];
 | 
						||
  if (c==' ') _prompt[l-1]='\xFF';
 | 
						||
  prof.put("PROMPT", _prompt);
 | 
						||
  prof.put("ATTIVO", shown() ? "X" : " ");
 | 
						||
 | 
						||
  // specials: se e' stato cambiato, la tokenstring del valore contiene
 | 
						||
  // una X alla fine (campo 3)
 | 
						||
  {
 | 
						||
    TToken_string special(128,'\n');
 | 
						||
    _special.restart();
 | 
						||
 | 
						||
    for (int i = 0; i < _special.items(); i++)
 | 
						||
    {
 | 
						||
      THash_object* o = _special.get_hashobj();
 | 
						||
 | 
						||
      TString key(o->key());
 | 
						||
      TToken_string& tt = (TToken_string&)o->obj();
 | 
						||
 | 
						||
      if (tt.items() == 4)
 | 
						||
      {
 | 
						||
        TToken_string sp(key,'$');
 | 
						||
        TString val(tt.get(1));
 | 
						||
        sp.add(val);
 | 
						||
        special.add(sp);
 | 
						||
      }
 | 
						||
    }
 | 
						||
    special.rtrim();
 | 
						||
    prof.put("SPECIAL", special);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Abilita/Disabilita il campo
 | 
						||
void TForm_item::enable(
 | 
						||
     bool on) // @parm Operazione da svolgere sul campo:
 | 
						||
    // @flag TRUE | Il campo viene abiliato
 | 
						||
    // @flag FALSE | Il campo viene disabiliato
 | 
						||
 | 
						||
// @comm Viene automaticamente setta se il campo diventi visibile o nascosto (chiama <mf TForm_item::show>)
 | 
						||
{
 | 
						||
  _flag.enabled = on;
 | 
						||
  show(on);
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::set_special_value(const char* s, const char* val)
 | 
						||
{
 | 
						||
  TToken_string& tt = (TToken_string&) _special[s];
 | 
						||
  tt.add(val,1);
 | 
						||
  if (tt.items()==3) tt.add("X");
 | 
						||
}
 | 
						||
 | 
						||
const char* TForm_item::get_special_item(const char* s, int n) const
 | 
						||
{
 | 
						||
  TAssoc_array& sp = (TAssoc_array&)_special;
 | 
						||
  if (sp.is_key(s))
 | 
						||
  {
 | 
						||
    TToken_string& tt = (TToken_string&) sp[s];
 | 
						||
    return tt.get(n);
 | 
						||
  } else return "";
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::string_at(int x, int y, const char* s)
 | 
						||
{
 | 
						||
  if (shown())
 | 
						||
  {
 | 
						||
    if (section().columnwise()) x += _ofs;
 | 
						||
    TPrintrow& row = section().row(y-1);         // Seleziona riga di stampa
 | 
						||
 | 
						||
    if (_width > 0 && strlen(s) > (word)_width)  // Tronca testo se necessario
 | 
						||
    {
 | 
						||
      TString& tmp = get_tmp_string();
 | 
						||
      tmp.strncpy(s, _width);
 | 
						||
      s = tmp;
 | 
						||
    }
 | 
						||
    row.put(s, x-1);                             // Stampa testo
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TToken_string& TForm_item::message(int m)
 | 
						||
{
 | 
						||
  TToken_string* t = (TToken_string*)_message.objptr(m);
 | 
						||
  if (t == NULL)
 | 
						||
  {
 | 
						||
    t = new TToken_string(16);
 | 
						||
    _message.add(t, m);
 | 
						||
  }
 | 
						||
  return *t;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Manda il messaggio al campo <p dest>
 | 
						||
void TForm_item::send_message(
 | 
						||
     const TString& cmd,  // @parm Messaggio di comando
 | 
						||
     TForm_item& des) const // @parm Campo a cui destinare il messaggio
 | 
						||
{
 | 
						||
  if (cmd == "ADD" || cmd == "INC")
 | 
						||
  {
 | 
						||
    if (form().message_add_enabled())
 | 
						||
    {
 | 
						||
      const real n((cmd[0] == 'I') ? "1.0" : get());
 | 
						||
      real r(des.get());
 | 
						||
      r += n;
 | 
						||
      des.set(r.string());
 | 
						||
    }
 | 
						||
  } else if (cmd == "COPY") {
 | 
						||
    des.set(get());
 | 
						||
  } else if (cmd == "APPEND") {
 | 
						||
    TString256 val = des.get();
 | 
						||
    if (val.not_empty()) val << ' ';
 | 
						||
      val << get();
 | 
						||
      des.set(val);
 | 
						||
  } else if (cmd == "RESET") {
 | 
						||
    des.set("");
 | 
						||
  } else if (cmd == "DISABLE") {
 | 
						||
    des.disable();
 | 
						||
  } else if (cmd == "ENABLE") {
 | 
						||
    des.enable();
 | 
						||
  } else if (cmd == "HIDE") {
 | 
						||
    des.hide();
 | 
						||
  } else if (cmd == "SHOW") {
 | 
						||
    des.show();
 | 
						||
  } else if (cmd == "SUB") {
 | 
						||
    const real n(get());
 | 
						||
    real r(des.get());
 | 
						||
    r -= n;
 | 
						||
    des.set(r.string());
 | 
						||
  } else if (cmd[0] == '"') {
 | 
						||
    TString256 val(cmd);
 | 
						||
    val.strip("\"");
 | 
						||
    des.set(val);
 | 
						||
  } else
 | 
						||
    error_box("Unknown message in item '%s': '%s'",
 | 
						||
                  (const char*)key(), (const char*)cmd);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TForm_item& TForm_item::find_field(const TString& id) const
 | 
						||
{
 | 
						||
  if (isdigit(id[0]))              // Field in the same section
 | 
						||
  {
 | 
						||
    TForm_item& des = section().find_field(atoi(id));
 | 
						||
    return des;
 | 
						||
  }
 | 
						||
 | 
						||
  const int freccia = id.find("->");
 | 
						||
  const pagetype pt = (freccia==2) ? char2page(id[1]) : section().page_type() ;
 | 
						||
  char se;
 | 
						||
  int id_num;
 | 
						||
  int pos_id;
 | 
						||
  if (freccia >= 0)
 | 
						||
  {
 | 
						||
    pos_id=freccia+2;
 | 
						||
    id_num=atoi(id.mid(pos_id));
 | 
						||
    se = id[0];
 | 
						||
  } else {
 | 
						||
    id_num=0;
 | 
						||
    se = section().section_type();
 | 
						||
    pos_id=0;
 | 
						||
  }
 | 
						||
  if (id_num)  // id numerico: campo semplice
 | 
						||
  {
 | 
						||
    TForm_item& des = form().find_field(se, pt, id_num);
 | 
						||
    return des;
 | 
						||
  } else {  // id stringa : campo sezione
 | 
						||
    TForm_item& des = form().find_field(se, pt, id.mid(pos_id));
 | 
						||
    return des;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// il parametro num serve per identificare il messaggio nelle listbox...
 | 
						||
bool TForm_item::do_message(int num)
 | 
						||
{
 | 
						||
  TToken_string& messaggio = message(num);
 | 
						||
  if (messaggio.empty_items()) 
 | 
						||
    return FALSE;
 | 
						||
  TToken_string msg(16, ',');
 | 
						||
  for (const char* m = messaggio.get(0); m; m = messaggio.get())
 | 
						||
  {
 | 
						||
    msg = m;
 | 
						||
    if (*m == '_')
 | 
						||
      form().validate(*this, msg);
 | 
						||
    else
 | 
						||
    {
 | 
						||
      const TString80 cmd(msg.get());      // Get command
 | 
						||
      const TString80 id = msg.get();      // Get destination
 | 
						||
 | 
						||
      if (id.right(1) == "@")
 | 
						||
      {
 | 
						||
        const byte group = atoi(id);
 | 
						||
        // Send the message to all fields in local and upper sections with the given group
 | 
						||
        send_message_to_group(cmd,group,section(),§ion());
 | 
						||
      }
 | 
						||
      else 
 | 
						||
      {
 | 
						||
        TForm_item& des = find_field(id);
 | 
						||
        send_message(cmd, des);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::send_message_to_group(const char * cmd,byte id,const TPrint_section & section, const TPrint_section *starting_section) 
 | 
						||
{
 | 
						||
  TForm_item * f ;
 | 
						||
  // look into local section
 | 
						||
  for(word i = 0; i < section.fields(); i++)
 | 
						||
  {
 | 
						||
    f = §ion.field(i);
 | 
						||
    if (f->in_group(id))
 | 
						||
      send_message(cmd,*f);
 | 
						||
  }
 | 
						||
  // look into the section above ("father" )
 | 
						||
  if (section.section_above() && section.section_above()!=starting_section) {
 | 
						||
    send_message_to_group(cmd,id,*section.section_above(),§ion);
 | 
						||
  }   
 | 
						||
  // look into sections beside ("brothers" )
 | 
						||
  for (int j = 0; j < section.subsections(); j++) {
 | 
						||
    const TPrint_section &bs=section.subsection(j)->printsection();
 | 
						||
    if (&bs!=starting_section) {
 | 
						||
      send_message_to_group(cmd,id,section.subsection(j)->printsection(),§ion);
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_item::update()
 | 
						||
{  
 | 
						||
  if (_prompt.right(1) == "#")
 | 
						||
  {
 | 
						||
    TString prompt(_prompt);
 | 
						||
    int i;
 | 
						||
    
 | 
						||
    for (i = prompt.len()-2; i >= 0; i--)
 | 
						||
      if (prompt[i] != '#') break;
 | 
						||
    prompt.cut(i+1);
 | 
						||
    string_at(x(), _y, prompt);
 | 
						||
  }
 | 
						||
  else string_at(x(), _y, _prompt);
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::print_on(TToken_string& row)  const
 | 
						||
{
 | 
						||
  row.cut(0);
 | 
						||
  row.add(id());
 | 
						||
  row.add(key());
 | 
						||
  row.add(_y);
 | 
						||
  row.add(_x);
 | 
						||
  row.add(shown() ? " " : "X");
 | 
						||
 | 
						||
  if (form().edit_level() > 1)
 | 
						||
  {
 | 
						||
    const long fu = _group.first_one();
 | 
						||
    if (fu > 0) row.add(fu);
 | 
						||
    else row.add(" ");
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
const TString& TForm_item::picture() const
 | 
						||
{
 | 
						||
  NFCHECK("Can't get the picture of a generic form item!");
 | 
						||
  return EMPTY_STRING;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::set_picture(const char*)
 | 
						||
{
 | 
						||
  NFCHECK("Can't set the picture of a generic form item!");
 | 
						||
}
 | 
						||
 | 
						||
TToken_string& TForm_item::memo_info()
 | 
						||
{
 | 
						||
  NFCHECK("Can't get a memo of a generic form item!");
 | 
						||
  return (TToken_string &) EMPTY_STRING;
 | 
						||
}
 | 
						||
 | 
						||
short TForm_item::x()
 | 
						||
{
 | 
						||
  if (_section == NULL || !_section->columnwise())
 | 
						||
    return _x;
 | 
						||
  return _section->tab(_x-1) + _section->ofspc();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_subsection
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
 | 
						||
TForm_subsection::TForm_subsection(TPrint_section* s, const char* nm) 
 | 
						||
                : TForm_item(s), _title_section(NULL), _qtitle_section(NULL),
 | 
						||
                  _ssec(&(s->form()), s->section_type(), s->page_type()), 
 | 
						||
                  _name(nm), _title_type(type_notitle), 
 | 
						||
                  _show_title(FALSE), _file_id(-1), _condexpr(NULL)
 | 
						||
{
 | 
						||
  _ssec.set_subsection_above(this);
 | 
						||
}
 | 
						||
 | 
						||
TForm_subsection::~TForm_subsection()
 | 
						||
{
 | 
						||
  if (_condexpr) delete _condexpr;
 | 
						||
  // _title_section e _qtitle_section sono puntatori a subsection contenute nel corpo, quindi non vanno deallocati
 | 
						||
}
 | 
						||
 | 
						||
TObject* TForm_subsection::dup() const
 | 
						||
{
 | 
						||
  TForm_subsection* fs = new TForm_subsection(_section);
 | 
						||
  copy_to_form_item(fs);
 | 
						||
  fs->_ssec = _ssec;
 | 
						||
  fs->_name = _name;
 | 
						||
  fs->_file_id = _file_id;
 | 
						||
  fs->_title_type = _title_type;
 | 
						||
  fs->_show_title=_show_title;
 | 
						||
  if (_condexpr)
 | 
						||
    fs->_condexpr=new TExpression((const char *)_condexpr);
 | 
						||
  else
 | 
						||
    fs->_condexpr=NULL;
 | 
						||
  if (_title_section)
 | 
						||
    fs->_title_section=(TForm_subsection* )_title_section->dup();
 | 
						||
  else
 | 
						||
    fs->_title_section=NULL;
 | 
						||
  if (_qtitle_section)
 | 
						||
    fs->_qtitle_section=(TForm_subsection* )_qtitle_section->dup();
 | 
						||
  else
 | 
						||
    fs->_qtitle_section=NULL;
 | 
						||
  return fs;
 | 
						||
}
 | 
						||
 | 
						||
int TForm_subsection::fileid()
 | 
						||
{
 | 
						||
  return _file_id;
 | 
						||
}
 | 
						||
// restituisce la condizione della sottosezione
 | 
						||
const char * TForm_subsection::condition()
 | 
						||
{
 | 
						||
  if (_condexpr)
 | 
						||
    return (const char *)_condexpr->string();
 | 
						||
  else  
 | 
						||
    return NULL;
 | 
						||
}
 | 
						||
 | 
						||
// imposta la condizione della sottosezione
 | 
						||
void TForm_subsection::setcondition(const char* cond,TTypeexp type)
 | 
						||
{
 | 
						||
  if (_condexpr) 
 | 
						||
  {
 | 
						||
    if (_file_id != -1)
 | 
						||
      printsection().set_subs_cond(_file_id,cond,_condexpr->string());
 | 
						||
    delete _condexpr;
 | 
						||
  }
 | 
						||
  _condexpr=new TExpression(cond,type); 
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// imposta la sottosezione titolo
 | 
						||
void TForm_subsection::set_title_section(TForm_subsection* s)
 | 
						||
{
 | 
						||
  if (_title_section) delete _title_section;
 | 
						||
  _title_section=s; 
 | 
						||
}
 | 
						||
 | 
						||
// imposta la sottosezione titolo di coda
 | 
						||
void TForm_subsection::set_qtitle_section(TForm_subsection* s)
 | 
						||
{
 | 
						||
  if (_qtitle_section) delete _qtitle_section;
 | 
						||
  _qtitle_section=s; 
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TPrint_section::print_title()
 | 
						||
{
 | 
						||
  TPrinter& pr = printer();
 | 
						||
    
 | 
						||
  if (pr.current_row() > pr.headersize()+1)
 | 
						||
    if (word(height()) > pr.rows_left())
 | 
						||
      pr.formfeed();
 | 
						||
  word last_printed_row=0;
 | 
						||
  const word maxs=(word)subsections() ;
 | 
						||
  for (word s = 0;  s < (word)maxs ;s++)
 | 
						||
  {
 | 
						||
    TForm_subsection &ssec=*subsection(s);
 | 
						||
    for (;  last_printed_row < (word)ssec.y() -1;last_printed_row++)
 | 
						||
      pr.print(titlerow(last_printed_row));
 | 
						||
    if (ssec.shown())
 | 
						||
      ssec.printsection().print_title();
 | 
						||
  }
 | 
						||
  for (;  last_printed_row < (word)height() ;last_printed_row++)
 | 
						||
    pr.print(titlerow(last_printed_row));
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TPrint_section::set_subs_cond(int file,const char *newcond,const char * oldcond)
 | 
						||
{
 | 
						||
  TForm_subsection * s;
 | 
						||
  s=(TForm_subsection * )(_subsections.first_item());
 | 
						||
  while (s) {
 | 
						||
    TString newsubcond(s->condition());
 | 
						||
    if (file!=-1 && s->fileid()==file && newsubcond.not_empty()) {
 | 
						||
      // there's another file group subsection below....
 | 
						||
      newsubcond=newsubcond.mid(strlen(oldcond));
 | 
						||
      newsubcond.insert(newcond);
 | 
						||
      s->setcondition(newsubcond,_strexpr);
 | 
						||
    }
 | 
						||
    s=(TForm_subsection * )(_subsections.succ_item()) ;
 | 
						||
  } 
 | 
						||
}
 | 
						||
 | 
						||
// ritorna l'indirizzo della prima sottosezione condizionale di livello superiore alla corrente
 | 
						||
TForm_subsection *TForm_subsection::upper_conditional() const 
 | 
						||
{
 | 
						||
  if (section().subsection_above()) 
 | 
						||
  {
 | 
						||
    if (section().subsection_above()->_condexpr && section().subsection_above()->_file_id>0)
 | 
						||
      return section().subsection_above();
 | 
						||
    else 
 | 
						||
      return section().subsection_above()->upper_conditional();
 | 
						||
  } else
 | 
						||
    return NULL;
 | 
						||
}
 | 
						||
 | 
						||
// Esegue una post visita dell'albero delle subsection, stampando tutte le section "Titolo"
 | 
						||
bool TForm_subsection::print_titles() 
 | 
						||
{
 | 
						||
  if (section().subsection_above())
 | 
						||
    section().subsection_above()->print_titles();
 | 
						||
  bool ok=TRUE;
 | 
						||
  // print the title
 | 
						||
  if (_title_section != NULL && _title_section->_show_title)
 | 
						||
  {
 | 
						||
    if ( shown() && _title_section->shown() )
 | 
						||
    {
 | 
						||
      _title_section->printsection().print_title();
 | 
						||
    }
 | 
						||
    _title_section->show_title(FALSE);
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_subsection::print_qtitle() 
 | 
						||
{
 | 
						||
  bool ok=TRUE;
 | 
						||
  // print the title
 | 
						||
  if (_qtitle_section != NULL)
 | 
						||
  {
 | 
						||
    if (shown() && _qtitle_section->shown())
 | 
						||
    {
 | 
						||
      print_titles();
 | 
						||
      _qtitle_section->printsection().print_title();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
bool TForm_subsection::parse(TScanner& s)
 | 
						||
{
 | 
						||
  _section->add_subsection(this);
 | 
						||
  name(s.pop());
 | 
						||
  //_width  = s.integer();  // ...unused
 | 
						||
  //_x      = s.integer();  // ...unused
 | 
						||
  _y      = s.integer();  // posizione rispetto ai campi della sezione "padre"
 | 
						||
  _height = s.integer();  // minima altezza (primo "header")
 | 
						||
 | 
						||
  _ssec.parse_head(s);
 | 
						||
  s.popkey();
 | 
						||
  if (s.key() == "FI")     // FI_LE su cui iterare con next_match
 | 
						||
  {
 | 
						||
    _file_id = name2log(s.pop());
 | 
						||
    if (s.popkey() == "GR" || s.key() == "BY") 
 | 
						||
    {  
 | 
						||
      // GR_OUP or BY group : gestione dei raggruppamenti o big skip
 | 
						||
      TString e;
 | 
						||
      TForm_subsection * uppersec=upper_conditional();
 | 
						||
      e = s.line();
 | 
						||
      if (uppersec && uppersec->_file_id==_file_id)
 | 
						||
      {
 | 
						||
        // se anche la sezione soprastante 
 | 
						||
        const TString& eu = uppersec->_condexpr->string();
 | 
						||
        if (e != eu)
 | 
						||
        {
 | 
						||
          e.insert("+");
 | 
						||
          if (e != eu.right(e.len()))
 | 
						||
            e.insert(eu);  // Aggiungo espressione precedente
 | 
						||
          else
 | 
						||
            e = eu;        // Inutile aggiungere espressione gi<67> presente
 | 
						||
        }    
 | 
						||
      }  
 | 
						||
      _condexpr = new TExpression(e,_strexpr);   
 | 
						||
      _bigskip = s.key() == "BY";
 | 
						||
    } else
 | 
						||
      s.push();
 | 
						||
  } else {
 | 
						||
    if (s.key() == "NU")     // NU_MERIC CONDITION di gestione della sezione
 | 
						||
      _condexpr = new TExpression(s.line(),_numexpr);   // 
 | 
						||
    else if (s.key() == "ST")     // ST_RING CONDITION di gestione della sezione
 | 
						||
      _condexpr = new TExpression(s.line(),_strexpr);   // 
 | 
						||
    else if (s.key() == "HE")     // sottosezione HE_ADER (titolo), stampa solo se altr sotto sez verranno stampati
 | 
						||
    {
 | 
						||
      _title_type=type_title;
 | 
						||
      if (section().subsection_above()) 
 | 
						||
        section().subsection_above()->set_title_section(this);
 | 
						||
    }
 | 
						||
    else if (s.key() == "FO")     // sottosezione FO_OOTER (titolo di coda), stampato solo se altr sotto sez verranno stampati
 | 
						||
    {
 | 
						||
      _title_type=type_qtitle;
 | 
						||
      if (section().subsection_above()) 
 | 
						||
        section().subsection_above()->set_qtitle_section(this);
 | 
						||
    }
 | 
						||
    else if (s.key() != "GR")     // GR_OUP section (raggruppamento puro)
 | 
						||
      s.push();
 | 
						||
  } 
 | 
						||
  if (s.popkey() == "FL")
 | 
						||
    _flag.update(s.string());
 | 
						||
  else s.push();
 | 
						||
  return(_ssec.parse_body(s)) ;
 | 
						||
}
 | 
						||
 | 
						||
// nel caso di subsection viene chiamata la set_body anzich<63> la update
 | 
						||
bool TForm_subsection::update()
 | 
						||
{ 
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_subsection::print_body(sec_print_mode showfields)
 | 
						||
{
 | 
						||
  bool at_newpage=(atnewpage() || printer().rows_left() < (word)minheight());
 | 
						||
  bool ok = FALSE;
 | 
						||
  TCursor* cur = form().cursor();
 | 
						||
 | 
						||
  set_effective_height(0); // resetta l'altezza della sottosezione al suo "minimo"
 | 
						||
 | 
						||
  if (!enabled() ) 
 | 
						||
    return FALSE;
 | 
						||
 | 
						||
  if (is_title())
 | 
						||
  {
 | 
						||
    show_title(TRUE);
 | 
						||
    showfields=printmode_title  ; // calcola e bufferizza ora, rimanda la stampa dopo ...
 | 
						||
  }
 | 
						||
  if (!shown()) 
 | 
						||
    showfields = printmode_noprint;
 | 
						||
  
 | 
						||
  if (cur == NULL || (_file_id == -1 && _condexpr==NULL)) // ...unused
 | 
						||
    ok = _ssec.update_and_print(showfields,at_newpage);
 | 
						||
  else if (_file_id == -1 && _condexpr!=NULL) // subsection condizionale 
 | 
						||
    {
 | 
						||
      if ((bool)(_section->eval_expr(*_condexpr,_file_id)))
 | 
						||
        ok = _ssec.update_and_print(showfields,at_newpage);
 | 
						||
    } 
 | 
						||
  else  
 | 
						||
  {
 | 
						||
    _ssec.set_repeat_count(0);
 | 
						||
    if (_condexpr) { // sottosezione di raggruppamenti su file
 | 
						||
      int i = 0;
 | 
						||
      TString group_expr = _section->eval_expr(*_condexpr,_file_id).as_string();
 | 
						||
      bool again=TRUE;
 | 
						||
      while (again && group_expr==_section->eval_expr(*_condexpr,_file_id).as_string())
 | 
						||
      {
 | 
						||
        form().match_result(_file_id);
 | 
						||
        if (!_bigskip || i==0)
 | 
						||
        {
 | 
						||
          ok |= _ssec.update_and_print(showfields,at_newpage);
 | 
						||
          _ssec.set_repeat_count(++i);
 | 
						||
        } 
 | 
						||
        if (form().next_match_done(_file_id))
 | 
						||
        {
 | 
						||
          again=form().last_match_result(_file_id); // continue if there WAS a match
 | 
						||
        } else  {
 | 
						||
          again=cur->next_match(_file_id) ;       
 | 
						||
          form().match_result(_file_id,again);      // store if a match occoured
 | 
						||
        }
 | 
						||
        at_newpage=(atnewpage() || printer().rows_left() < (word)minheight());
 | 
						||
      }
 | 
						||
//      _ssec.set_repeat_count(0);
 | 
						||
    } else {  // sottosezione di file 
 | 
						||
      int i = 0;
 | 
						||
      if (cur->is_first_match(_file_id))
 | 
						||
      {
 | 
						||
        bool again;
 | 
						||
        do {
 | 
						||
          form().match_result(_file_id);
 | 
						||
          ok |= _ssec.update_and_print(showfields,at_newpage);
 | 
						||
          _ssec.set_repeat_count(++i);
 | 
						||
          if (form().next_match_done(_file_id))
 | 
						||
            again=form().last_match_result(_file_id);
 | 
						||
          else 
 | 
						||
            again= cur->next_match(_file_id);
 | 
						||
          at_newpage=(atnewpage() || printer().rows_left() < (word)minheight());
 | 
						||
        }  while (again);
 | 
						||
        ok |= (_ssec.repeat_count()>0); // (ovvero, sempre true: se c'e' un first match)
 | 
						||
      }
 | 
						||
//      _ssec.set_repeat_count(0);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
// @mfunc Abilita (default) o disabilita la stampa di tutti i campi della sottosezione
 | 
						||
/*void TForm_subsection::show(bool on)
 | 
						||
{
 | 
						||
  TForm_item::show(on);
 | 
						||
  for (unsigned int i = 0; i < _ssec.fields(); i++)
 | 
						||
    _ssec.field(i).show(on);
 | 
						||
}
 | 
						||
 | 
						||
// @mfunc Abilita (default) o disabilita la valutazione e la stampa di tutti i campi della sottosezione
 | 
						||
void TForm_subsection::enable(bool on)
 | 
						||
{
 | 
						||
  TForm_item::enable(on);
 | 
						||
  for (unsigned int i = 0; i < _ssec.fields(); i++)
 | 
						||
    _ssec.field(i).enable(on);
 | 
						||
} */
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_string
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
 | 
						||
TForm_string::TForm_string(TPrint_section* section)
 | 
						||
            : TForm_item(section), _memo("",'\n')
 | 
						||
{}
 | 
						||
 | 
						||
TObject* TForm_string::dup() const
 | 
						||
{
 | 
						||
  TForm_string* fs = new TForm_string(_section);
 | 
						||
  copy_to_form_item(fs);
 | 
						||
  fs->_str = _str;
 | 
						||
  fs->_picture = _picture;
 | 
						||
  fs->_field = _field;
 | 
						||
  fs->_memo = _memo;
 | 
						||
  return fs;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_string::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (scanner.key() == "FI")  // FIELD reference
 | 
						||
  {
 | 
						||
    TFieldref* fr = new TFieldref(scanner.line(), 0);
 | 
						||
    _field.add(fr);
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  if (scanner.key() == "PI")  // PICTURE def
 | 
						||
  {
 | 
						||
    set_picture(scanner.string());
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  return TForm_item::parse_item(scanner);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_string::set(const char* s)
 | 
						||
{
 | 
						||
  _str = s;
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
const char* TForm_string::get() const
 | 
						||
{ return _str; }
 | 
						||
 | 
						||
 | 
						||
// Se un campo e' abilitato ed ha almeno un riferimento su file leggilo
 | 
						||
bool TForm_string::read()
 | 
						||
{
 | 
						||
  const bool ok = enabled();
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    if (_field.items() != 0)
 | 
						||
    {
 | 
						||
      const char* s = "";
 | 
						||
  // !?!?!?!!
 | 
						||
      const TRelation* r = (TRelation* )form().relation();
 | 
						||
      CHECK(r, "Can't read from null relation");
 | 
						||
      for (int i = 0; i < _field.items() && *s == '\0'; i++)
 | 
						||
        s = field(i).read(*r);
 | 
						||
      set(s);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_string::put_paragraph(const char* s)
 | 
						||
{
 | 
						||
  if (hidden()) return;          
 | 
						||
 | 
						||
  const int h = height();
 | 
						||
 | 
						||
  if (h > 1)
 | 
						||
  {
 | 
						||
    TString lines;
 | 
						||
    if (_prompt.not_empty())
 | 
						||
      lines = _prompt;
 | 
						||
    lines << s; 
 | 
						||
    TParagraph_string p(lines, width());
 | 
						||
    int i;
 | 
						||
    
 | 
						||
    for (i = 0; (s = p.get()) != NULL && i < h; i++)
 | 
						||
      string_at(x(), _y+i, s);
 | 
						||
    _effective_height = i;
 | 
						||
 | 
						||
    TForm_subsection *subsec= section().subsection_above();
 | 
						||
    if (subsec)
 | 
						||
    {
 | 
						||
      // aggiorno l'altezza effettiva della sottosezione
 | 
						||
      if (effective_height() > 1)
 | 
						||
      {
 | 
						||
        // il campo si <20> "espanso"
 | 
						||
        const int last_y=effective_height()+y()-1;
 | 
						||
        if (last_y > subsec->height())
 | 
						||
          subsec->set_effective_height(last_y);
 | 
						||
      }    
 | 
						||
    }    
 | 
						||
    
 | 
						||
  }
 | 
						||
  else       
 | 
						||
  {
 | 
						||
    if (_prompt.empty())
 | 
						||
      string_at(x(), _y, s);
 | 
						||
    else
 | 
						||
      string_at(-1 , _y, s);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TForm_string::apply_format(TString& s) const
 | 
						||
{
 | 
						||
  const TString& strpic = picture();
 | 
						||
  if (strpic.full())
 | 
						||
  {
 | 
						||
    TToken_string* delim = NULL;         // Stringa con i due delimitatori
 | 
						||
 | 
						||
    const char* pic = strpic;            // Picture senza delimitatori
 | 
						||
    if (pic[0] == '(')                   // Se ci sono i delimitatori ...
 | 
						||
    {
 | 
						||
      const int bra = strpic.find(')');
 | 
						||
      if (bra > 1)                       // ... cerca la parentesi chiusa
 | 
						||
      {
 | 
						||
        delim = new TToken_string(strpic.sub(1, bra), ','); // memorizza delimitatori
 | 
						||
        pic += bra+1;                                       // toglili dalla picture
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    TString80 tmp;
 | 
						||
    if (s.blank() && strcmp(class_name(),"DATA")==0)
 | 
						||
      tmp.cut(0);
 | 
						||
    else
 | 
						||
      tmp.picture(pic, s);               // riempi la stringa col valore pitturato
 | 
						||
 | 
						||
    if (delim != NULL)            // Aggiungi delimitatori
 | 
						||
    {
 | 
						||
      TString16 d(delim->get(0));
 | 
						||
      const int ld = d.len();
 | 
						||
 | 
						||
      if (ld > 0)                  // Se il primo delimitatore e' valido ...
 | 
						||
      {
 | 
						||
        int spc;
 | 
						||
        for (spc = 0;s[spc]==' ' ; spc++) ;
 | 
						||
        if (spc < ld)
 | 
						||
        {
 | 
						||
          TString16 spazi;
 | 
						||
          spazi.spaces(ld - spc);
 | 
						||
          tmp.insert(spazi,0);
 | 
						||
          spc = ld;
 | 
						||
        }
 | 
						||
        tmp.overwrite(d,spc - ld);
 | 
						||
      }
 | 
						||
      d = delim->get();
 | 
						||
      if (d.not_empty())                 // Se il secondo delimitatore e' valido ...
 | 
						||
        tmp << d;                        // ... aggiungilo alla fine
 | 
						||
      
 | 
						||
      delete delim;
 | 
						||
    }
 | 
						||
    s = tmp;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_string::update()
 | 
						||
{
 | 
						||
  if (read()) // valuta il campo
 | 
						||
  {
 | 
						||
    TForm_item::update();
 | 
						||
    // esegue i messaggi
 | 
						||
    const int n = (_message.objptr(1) != NULL && *get()=='\0' ? 1 : 0);
 | 
						||
    do_message(n);
 | 
						||
    // prende il campo e lo stampa
 | 
						||
    TString s(get());
 | 
						||
    apply_format(s);
 | 
						||
    put_paragraph(s);
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
const char* TForm_string::example() const
 | 
						||
{
 | 
						||
  TString& prova = get_tmp_string(); 
 | 
						||
  prova = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
 | 
						||
  apply_format(prova);
 | 
						||
  const int w = width();
 | 
						||
  if (w > 0 && prova.size() > w) 
 | 
						||
    prova.cut(w);
 | 
						||
  return prova;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_number
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TForm_number : public TForm_string
 | 
						||
{
 | 
						||
protected: // TForm_string
 | 
						||
  virtual const char* class_name() const { return "NUMERO"; }
 | 
						||
  virtual bool parse_head(TScanner& scanner);
 | 
						||
  virtual bool update();
 | 
						||
 | 
						||
protected:
 | 
						||
  int decimals() const { return _height; }
 | 
						||
 | 
						||
public:
 | 
						||
 | 
						||
  void real2currency(const real& r, TString& str) const;
 | 
						||
  virtual TObject* dup() const;
 | 
						||
  void set_decimals(int d) { _height = d; }
 | 
						||
  virtual const char* example() const;
 | 
						||
  virtual void set_picture(const char* p);
 | 
						||
  virtual void apply_format(TString& s) const;
 | 
						||
  virtual void put_paragraph(const char * s);
 | 
						||
 | 
						||
  TForm_number(TPrint_section* section) : TForm_string(section) {}
 | 
						||
  virtual ~TForm_number() {}
 | 
						||
};
 | 
						||
 | 
						||
bool TForm_number::parse_head(TScanner& scanner)
 | 
						||
{
 | 
						||
  return TForm_item::parse_head(scanner);
 | 
						||
}
 | 
						||
 | 
						||
TObject* TForm_number::dup() const
 | 
						||
{
 | 
						||
  TForm_number *fn = new TForm_number(_section);
 | 
						||
  copy_to_form_item(fn);
 | 
						||
  return fn;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_number::put_paragraph(const char* s)
 | 
						||
{
 | 
						||
  if (hidden()) return;  
 | 
						||
  
 | 
						||
  int gap = 0;
 | 
						||
  if (section().columnwise())
 | 
						||
  {
 | 
						||
    const int w = width();
 | 
						||
    const int l = strlen(s);
 | 
						||
    if (w>l) gap = w-l;
 | 
						||
  }
 | 
						||
  if (_prompt.empty())
 | 
						||
    string_at(x()+gap, _y, s);
 | 
						||
  else
 | 
						||
    string_at(-1, _y, s); // se ha il prompt stampa all'ultima posizione raggiunta
 | 
						||
}
 | 
						||
 | 
						||
void TForm_number::real2currency(const real& r, TString& str) const
 | 
						||
{
 | 
						||
  TCurrency c(r);
 | 
						||
  c.set_price(_flag.price != 0);
 | 
						||
  
 | 
						||
  const TExchange* oe = form().output_exchange();
 | 
						||
  if (oe && !c.get_exchange().same_value_as(*oe))
 | 
						||
    c.change_value(*oe);
 | 
						||
  
 | 
						||
  const TString& pic = picture();
 | 
						||
  const int piclen = pic.len();
 | 
						||
  const bool dotted = pic.empty() || pic.find('.') >= 0;
 | 
						||
  str = c.string(dotted);
 | 
						||
  const int w = width();
 | 
						||
  if (w > piclen)
 | 
						||
    str.right_just(w);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_number::update()
 | 
						||
{
 | 
						||
  if (read()) // valuta il campo
 | 
						||
  {
 | 
						||
    TForm_item::update();
 | 
						||
    
 | 
						||
    real n = get(); // Trasforma la stringa in numero reale
 | 
						||
 | 
						||
    // Arrotonda intelligentemente il numero
 | 
						||
    int round_dec = decimals();
 | 
						||
    if (round_dec == 0 && width() > 9 && form().magic_currency()) // Magic currency?
 | 
						||
      round_dec = TCurrency::get_firm_dec();
 | 
						||
    n.round(round_dec); 
 | 
						||
 | 
						||
    if (_message.items() > 0)
 | 
						||
    {
 | 
						||
      const int nm = (_message.objptr(1) != NULL && n.is_zero()) ? 1 : 0;
 | 
						||
      do_message(nm);
 | 
						||
      n = get();          // Il numero potrebbe essere cambiato dal messaggio!
 | 
						||
      n.round(round_dec); 
 | 
						||
    }
 | 
						||
 | 
						||
    bool print = TRUE;
 | 
						||
    if (n.is_zero())
 | 
						||
    {
 | 
						||
      char sep = picture().find('E') >= 0 ? '.' :',';
 | 
						||
      int comma = picture().find(sep);
 | 
						||
      if (comma < 0 )
 | 
						||
        comma = picture().len();
 | 
						||
      print = comma > 0 && picture()[comma-1] == '@';
 | 
						||
    }
 | 
						||
 | 
						||
    if (print)
 | 
						||
    {
 | 
						||
      TString80 print_string;           
 | 
						||
      bool app_for = TRUE;  // Apply format?
 | 
						||
      if (form().magic_currency()) 
 | 
						||
      {
 | 
						||
        const bool b1 = picture() == "." || (picture().len() >= 9 && picture().find(',') < 0);
 | 
						||
        const bool b2 = width() >= 9 && decimals() == 0;
 | 
						||
        if (b1 || b2)
 | 
						||
        {
 | 
						||
          real2currency(n, print_string);
 | 
						||
          app_for = FALSE; // La stringa <20> gi<67> belle che formattata!
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (app_for)
 | 
						||
      {
 | 
						||
        print_string = n.string();
 | 
						||
        apply_format(print_string);
 | 
						||
      }
 | 
						||
      put_paragraph(print_string);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_number::apply_format(TString& s) const
 | 
						||
{
 | 
						||
  if (picture().full())
 | 
						||
  { 
 | 
						||
    real n(s);
 | 
						||
    TToken_string delim(4, ',');         // Stringa con i due delimitatori
 | 
						||
    TString pic(picture());              // Picture senza delimitatori
 | 
						||
    int maxlen = -1;
 | 
						||
 | 
						||
    if (pic[0] == '(')                   // Se ci sono i delimitatori ...
 | 
						||
    {
 | 
						||
      const int bra = pic.find(')');
 | 
						||
      if (bra > 0)                       // ... cerca la parentesi chiusa
 | 
						||
      {
 | 
						||
        delim = pic.sub(1, bra);         // memorizza delimitatori
 | 
						||
        pic.ltrim(bra + 1);              // toglili dalla picture
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    const int at = pic.find('@');
 | 
						||
    if (at > 0)
 | 
						||
    {
 | 
						||
      const int len = atoi(&pic[at+1]);
 | 
						||
      if (len > 0)
 | 
						||
      {
 | 
						||
        maxlen = len;
 | 
						||
        pic.cut(at);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    s=n.string(pic);          // riempi la stringa col valore pitturato
 | 
						||
 | 
						||
    if (maxlen >= 0 && maxlen < s.size())
 | 
						||
      s.cut(maxlen);
 | 
						||
    if (!delim.empty_items())            // Aggiungi delimitatori
 | 
						||
    {
 | 
						||
      TString16 d(delim.get(0));
 | 
						||
      const int ld = d.len();
 | 
						||
 | 
						||
      if (ld > 0)                  // Se il primo delimitatore e' valido ...
 | 
						||
      {
 | 
						||
      	int spc;
 | 
						||
      	
 | 
						||
        for (spc = 0;s[spc]==' ' ; spc++) ;
 | 
						||
        if (spc < ld)
 | 
						||
        {
 | 
						||
          TString16 spazi;
 | 
						||
           spazi.spaces(ld - spc);
 | 
						||
           s.insert(spazi,0);
 | 
						||
           spc = ld;
 | 
						||
         }
 | 
						||
         s.overwrite(d,spc - ld);
 | 
						||
       }
 | 
						||
       d = delim.get();
 | 
						||
       if (d.not_empty())                 // Se il secondo delimitatore e' valido ...
 | 
						||
         s << d;                          // ... aggiungilo alla fine
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    real n(s);
 | 
						||
    s = n.stringa(width(), decimals());
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TForm_number::set_picture(const char *p)
 | 
						||
{
 | 
						||
  TForm_string::set_picture(p);
 | 
						||
  const int comma = picture().find(',');
 | 
						||
  if (comma > 0) 
 | 
						||
    set_decimals(picture().len() - comma -1);
 | 
						||
}
 | 
						||
 | 
						||
const char* TForm_number::example() const
 | 
						||
{
 | 
						||
  TString& s = get_tmp_string();
 | 
						||
  s = "1234567890.123456";
 | 
						||
  apply_format(s);
 | 
						||
  return s;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_currency
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
class TForm_currency : public TForm_number
 | 
						||
{
 | 
						||
  TForm_item* _driver;
 | 
						||
 | 
						||
protected: // TForm_string
 | 
						||
  virtual const char* class_name() const { return "VALUTA"; }
 | 
						||
  virtual bool parse_head(TScanner& scanner);
 | 
						||
  virtual bool parse_item(TScanner& scanner);
 | 
						||
  virtual bool update();
 | 
						||
  virtual const char* get() const;
 | 
						||
  // @cmember Manda il messaggio al campo <p dest>
 | 
						||
  virtual void send_message(const TString& cmd, TForm_item& dest) const;
 | 
						||
public:  
 | 
						||
  virtual TObject* dup() const;
 | 
						||
  virtual TCurrency get_currency() const;
 | 
						||
  
 | 
						||
  TForm_currency(TPrint_section* section) : TForm_number(section), _driver(NULL) {}
 | 
						||
  virtual ~TForm_currency() {}
 | 
						||
};
 | 
						||
                        
 | 
						||
bool TForm_currency::parse_head(TScanner& scanner)
 | 
						||
{
 | 
						||
  return TForm_item::parse_head(scanner);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_currency::parse_item(TScanner& scanner)
 | 
						||
{                                
 | 
						||
  if (scanner.key() == "DR")
 | 
						||
  {             
 | 
						||
    _driver = &find_field(scanner.pop());
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
  return TForm_number::parse_item(scanner);
 | 
						||
}
 | 
						||
 | 
						||
TObject* TForm_currency::dup() const
 | 
						||
{
 | 
						||
  TForm_currency *fn = new TForm_currency(_section);
 | 
						||
  copy_to_form_item(fn);
 | 
						||
  return fn;
 | 
						||
}
 | 
						||
 | 
						||
const char* TForm_currency::get() const
 | 
						||
{
 | 
						||
  const char* val = TForm_string::get();
 | 
						||
  return val;
 | 
						||
}
 | 
						||
 | 
						||
TCurrency TForm_currency::get_currency() const
 | 
						||
{
 | 
						||
  const char * codval = _driver ? _driver->get() : (const char *) form().get_curr_codval();
 | 
						||
  const real n(get());
 | 
						||
  return TCurrency(n, codval, ZERO, _exchange_undefined, _flag.price != 0);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_currency::update()
 | 
						||
{
 | 
						||
  if (read()) // valuta il campo
 | 
						||
  {
 | 
						||
    TForm_item::update();
 | 
						||
   
 | 
						||
    if (_message.items() > 0)
 | 
						||
    {
 | 
						||
      const int nm = (_message.objptr(1) != NULL && real::is_null(get())) ? 1 : 0;
 | 
						||
      do_message(nm);
 | 
						||
    }
 | 
						||
 | 
						||
    if (!real::is_null(get()))
 | 
						||
    {
 | 
						||
      TCurrency curr = get_currency();
 | 
						||
      if (!_driver)
 | 
						||
      { 
 | 
						||
        const TExchange* oe = form().output_exchange();
 | 
						||
        if (oe != NULL && !curr.get_exchange().same_value_as(*oe))
 | 
						||
          curr.change_value(*oe);
 | 
						||
      }
 | 
						||
 | 
						||
      // Niente apply_format(), la picture viene ignorata per i TForm_currency
 | 
						||
      TString80 v;
 | 
						||
      const TString& pic = picture();
 | 
						||
      if (pic.find("LETTERE") >= 0)
 | 
						||
      {
 | 
						||
        v = get();
 | 
						||
        apply_format(v);
 | 
						||
        const int slash = v.rfind('/');
 | 
						||
        TString16 tail;
 | 
						||
        for (int i = v.len()-1; i > 0 && !isalnum(v[i]); i--)
 | 
						||
        {
 | 
						||
          tail << v[i];
 | 
						||
          v.cut(i);
 | 
						||
        }
 | 
						||
        const int zeroes_needed = curr.decimals();
 | 
						||
        if (zeroes_needed > 0)
 | 
						||
        {    
 | 
						||
          int zeroes_missing = 0;
 | 
						||
          if (slash >= 0)
 | 
						||
          {      
 | 
						||
            const int decimals_already_there = v.len() - slash - 1;
 | 
						||
            zeroes_missing =  zeroes_needed - decimals_already_there;
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {   
 | 
						||
            v << '/';
 | 
						||
            zeroes_missing = zeroes_needed;
 | 
						||
          }
 | 
						||
          for ( ; zeroes_missing > 0; zeroes_missing--)
 | 
						||
            v << '0';
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (slash >= 0)
 | 
						||
            v.cut(slash);
 | 
						||
        }
 | 
						||
        v << tail;
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        const bool dotted = pic.empty() || pic.find('.') > 0;
 | 
						||
        v = curr.string(dotted);
 | 
						||
        if (pic.right(3) == "^^^")  // 770 only: to be improved
 | 
						||
        {
 | 
						||
          const int dec = curr.decimals();
 | 
						||
          if (dec == 0)
 | 
						||
            v.rtrim(3+dotted);
 | 
						||
          else
 | 
						||
            v.rtrim(dec+1);  
 | 
						||
        }
 | 
						||
        const int w = width() - (_section->columnwise() ? _prompt.len() : 0);
 | 
						||
        if (w > v.len())
 | 
						||
          v.right_just(w);
 | 
						||
      }
 | 
						||
      put_paragraph(v);
 | 
						||
    }                                    
 | 
						||
    else
 | 
						||
    {
 | 
						||
      const TString& pic = picture();
 | 
						||
      if (pic.right(1)[0] == '@')
 | 
						||
      {
 | 
						||
        TString80 v;
 | 
						||
        const int w = width() - (_section->columnwise() ? _prompt.len() : 0);
 | 
						||
        int d = 0;
 | 
						||
        if (_driver)
 | 
						||
        {
 | 
						||
          const TCurrency z(ZERO, _driver->get(), ZERO, _exchange_base, _flag.price != 0);
 | 
						||
          d = z.decimals();
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {                         
 | 
						||
          const TExchange* oe =  form().output_exchange();
 | 
						||
          if (oe != NULL)
 | 
						||
          {
 | 
						||
            const TCurrency z(ZERO, *oe, _flag.price != 0);
 | 
						||
            d = z.decimals();
 | 
						||
          }
 | 
						||
          else
 | 
						||
            d = TCurrency::get_firm_dec(_flag.price != 0);
 | 
						||
        }
 | 
						||
      
 | 
						||
        if (d > 0)
 | 
						||
        {
 | 
						||
          v.format("%*.*lf", w, d, 0.0);
 | 
						||
          v.replace('.', ',');
 | 
						||
        }
 | 
						||
        else
 | 
						||
          v.format("%*d", w, 0);
 | 
						||
        
 | 
						||
        put_paragraph(v);
 | 
						||
      }
 | 
						||
      else
 | 
						||
        put_paragraph("");
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_currency::send_message(const TString& cmd, TForm_item& dest) const
 | 
						||
{
 | 
						||
  if (cmd == "ADD")
 | 
						||
  {
 | 
						||
    TCurrency total;
 | 
						||
    if (dest.class_name() != class_name()) // La destinazione non e' un TForm_currency
 | 
						||
    {               
 | 
						||
      const real n = dest.get();
 | 
						||
      total.set_num(n);
 | 
						||
    }
 | 
						||
    else
 | 
						||
      total = ((TForm_currency&)dest).get_currency();
 | 
						||
    total += get_currency();
 | 
						||
    dest.set(total.get_num().string());
 | 
						||
  }
 | 
						||
  else
 | 
						||
    TForm_number::send_message(cmd, dest);
 | 
						||
}
 | 
						||
                        
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_date
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TForm_date : public TForm_string
 | 
						||
{
 | 
						||
  TString16 _format;
 | 
						||
 | 
						||
protected:
 | 
						||
  virtual const char* class_name() const { return "DATA"; }
 | 
						||
  virtual bool read();
 | 
						||
  virtual bool set(const char*);
 | 
						||
  bool set(const TDate& d);
 | 
						||
  virtual bool parse_item(TScanner& scanner);
 | 
						||
  virtual void print_body(ostream& out) const;
 | 
						||
 | 
						||
  virtual void print_on(TMask& m);
 | 
						||
  virtual void read_from(const TMask& m);
 | 
						||
 | 
						||
  virtual bool read_from(const TRectype& rform);
 | 
						||
  virtual void print_on(TRectype& rform);
 | 
						||
 | 
						||
public:
 | 
						||
  virtual TObject* dup() const;
 | 
						||
  void set_format(const char* f) { _format = f; }
 | 
						||
  virtual bool edit(TMask& m);
 | 
						||
  virtual const char* example() const;
 | 
						||
  TForm_date(TPrint_section* section);
 | 
						||
  virtual ~TForm_date() {}
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
TForm_date::TForm_date(TPrint_section* section)
 | 
						||
: TForm_string(section), _format("1444-")
 | 
						||
{}
 | 
						||
 | 
						||
TObject* TForm_date::dup() const
 | 
						||
{
 | 
						||
  TForm_date* fd = new TForm_date(_section);
 | 
						||
  copy_to_form_item(fd);
 | 
						||
  fd->_format = _format;
 | 
						||
  return fd;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_date::read()
 | 
						||
{
 | 
						||
  bool ok = TForm_string::read();
 | 
						||
  if (ok && !get()[0] && automagic())
 | 
						||
    set(printer().getdate());
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_date::print_body(ostream& out) const
 | 
						||
{
 | 
						||
  TForm_string::print_body(out);
 | 
						||
  out << " FORMAT \"" << _format << "\"\n";
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_date::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (scanner.key() == "FO")
 | 
						||
  {
 | 
						||
    _format = scanner.string();
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
  return TForm_string::parse_item(scanner);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_date::read_from(const TRectype& prof)
 | 
						||
{
 | 
						||
  bool changed = TForm_string::read_from(prof);
 | 
						||
 | 
						||
  const TString& df = prof.get("DATEFORM");
 | 
						||
  if (df.not_empty() && df != _format)
 | 
						||
  {
 | 
						||
    _format = df;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  return changed;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_date::print_on(TRectype& prof)
 | 
						||
{
 | 
						||
  TForm_string::print_on(prof);
 | 
						||
  prof.put("DATEFORM", _format);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_date::set(const char* s)
 | 
						||
{
 | 
						||
  const TDate da(s);
 | 
						||
  return set(da);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_date::set(const TDate& da)
 | 
						||
{
 | 
						||
  TFormatted_date d(da); d.set_format(_format);
 | 
						||
  TForm_string::set(d.string());
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_date::print_on(TMask& m)
 | 
						||
{
 | 
						||
  const TDate dd(TODAY);
 | 
						||
  TFormatted_date d(dd); d.set_format(_format);
 | 
						||
  m.set(F_DEXAMPLE, d.string());
 | 
						||
 | 
						||
  m.set(F_DFORMAT, _format.mid(0,1));
 | 
						||
  m.set(F_DDAY,    _format.mid(1,1));
 | 
						||
  m.set(F_DMONTH,  _format.mid(2,1));
 | 
						||
  m.set(F_DYEAR,   _format.mid(3,1));
 | 
						||
  m.set(F_DSEP,    _format.mid(4,1));
 | 
						||
 | 
						||
  TForm_string::print_on(m);
 | 
						||
}
 | 
						||
 | 
						||
void TForm_date::read_from(const TMask& m)
 | 
						||
{
 | 
						||
  TForm_string::read_from(m);
 | 
						||
 | 
						||
  // adjust format string
 | 
						||
  _format[0] = m.get(F_DFORMAT)[0];
 | 
						||
  _format[1] = m.get(F_DDAY   )[0];
 | 
						||
  _format[2] = m.get(F_DMONTH )[0];
 | 
						||
  _format[3] = m.get(F_DYEAR  )[0];
 | 
						||
  _format[4] = m.get(F_DSEP   )[0];
 | 
						||
  _format[5] = '\0';
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_date::edit(TMask& m)
 | 
						||
{
 | 
						||
  return TForm_string::edit(m);
 | 
						||
}
 | 
						||
 | 
						||
const char* TForm_date::example() const
 | 
						||
{
 | 
						||
  const TDate dd(TODAY);
 | 
						||
  TFormatted_date d(dd); d.set_format(_format);
 | 
						||
  TString& s = get_tmp_string();
 | 
						||
  s = d.string();
 | 
						||
  return s;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_list
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TForm_list : public TForm_string
 | 
						||
{
 | 
						||
  TToken_string _codes;
 | 
						||
  TToken_string _values;
 | 
						||
 | 
						||
protected:
 | 
						||
  virtual const char* class_name() const { return "LISTA"; }
 | 
						||
  virtual bool parse_item(TScanner& scanner);
 | 
						||
  virtual void print_on(TMask& m);
 | 
						||
  virtual void read_from(const TMask& m);
 | 
						||
  virtual void print_body(ostream& out) const;
 | 
						||
  virtual bool update();
 | 
						||
 | 
						||
public:
 | 
						||
  virtual TObject* dup() const;
 | 
						||
  TForm_list(TPrint_section* section);
 | 
						||
  virtual ~TForm_list() {}
 | 
						||
};
 | 
						||
 | 
						||
TForm_list::TForm_list(TPrint_section* section)
 | 
						||
: TForm_string(section)
 | 
						||
{}
 | 
						||
 | 
						||
TObject* TForm_list::dup() const
 | 
						||
{
 | 
						||
  TForm_list* fl = new TForm_list(_section);
 | 
						||
  copy_to_form_item(fl);
 | 
						||
  fl->_codes = _codes;
 | 
						||
  fl->_values = _values;
 | 
						||
  return fl;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_list::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (scanner.key() == "IT")
 | 
						||
  {
 | 
						||
    TToken_string s(scanner.string());
 | 
						||
    _codes.add(s.get());
 | 
						||
    _values.add(s.get());
 | 
						||
 | 
						||
    while (scanner.popkey() == "ME")
 | 
						||
    {
 | 
						||
      TFixed_string m(scanner.line());
 | 
						||
      m.strip_spaces();
 | 
						||
      message(_values.items()-1).add(m);
 | 
						||
    }
 | 
						||
    scanner.push();
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  return TForm_string::parse_item(scanner);
 | 
						||
}
 | 
						||
 | 
						||
void TForm_list::print_on(TMask& m)
 | 
						||
{
 | 
						||
  TForm_string::print_on(m);
 | 
						||
  TSheet_field& s = (TSheet_field&)m.field(F_ITEMS);
 | 
						||
  s.reset();
 | 
						||
  _codes.restart(); _values.restart();
 | 
						||
  for (int i = 0; i < _codes.items(); i++)
 | 
						||
  {
 | 
						||
    TToken_string& row = s.row(i);
 | 
						||
    row = _codes.get();
 | 
						||
    row.add(_values.get());
 | 
						||
    row.add(message(i));
 | 
						||
  }
 | 
						||
  //  s.force_update();
 | 
						||
}
 | 
						||
 | 
						||
void TForm_list::read_from(const TMask& m)
 | 
						||
{
 | 
						||
  TForm_string::read_from(m);
 | 
						||
 | 
						||
  TSheet_field& s = (TSheet_field&)m.field(F_ITEMS);
 | 
						||
 | 
						||
  _codes = _values = "";
 | 
						||
  for (int i = 0; i < s.items(); i++)
 | 
						||
  {
 | 
						||
    TToken_string& row = s.row(i);
 | 
						||
    _codes.add(row.get(0));
 | 
						||
    _values.add(row.get());
 | 
						||
    message(i) = row.get();
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TForm_list::print_body(ostream& out) const
 | 
						||
{
 | 
						||
  TForm_string::print_body(out);
 | 
						||
 | 
						||
  TToken_string& cod = (TToken_string&)_codes; // Trick to skip const
 | 
						||
  TToken_string& val = (TToken_string&)_values;
 | 
						||
 | 
						||
  int i = 0;
 | 
						||
  TString c(cod.get(0));
 | 
						||
  TString v(val.get(0));
 | 
						||
 | 
						||
  for (; c[0]; c = cod.get(), v = val.get(), i++)
 | 
						||
  {
 | 
						||
    out << " ITEM \"" << c;
 | 
						||
    if (v.not_empty()) out << '|' << v;
 | 
						||
    out << '"';
 | 
						||
 | 
						||
    const char* m = ((TForm_list*)this)->message(i);
 | 
						||
    if (*m) out << " MESSAGE " << m;
 | 
						||
 | 
						||
    out << endl;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_list::update()
 | 
						||
{
 | 
						||
  bool ok = TRUE;
 | 
						||
 | 
						||
  if (!read()) return ok;
 | 
						||
 | 
						||
  const TString& val =get();
 | 
						||
  int pos = _codes.get_pos(val);
 | 
						||
  if (pos < 0)
 | 
						||
  {
 | 
						||
    TString def= _codes.get(0);
 | 
						||
    def.trim();
 | 
						||
    if (val == def) pos = 0; // Test default (first & empty) value
 | 
						||
    else
 | 
						||
    {
 | 
						||
      ok = yesno_box(FR("Il campo '%s' non puo' valere '%s': continuare ugualmente"),
 | 
						||
                     (const char*)key(), (const char*)val);
 | 
						||
      set(_codes.get(pos = 0));
 | 
						||
    }
 | 
						||
  }
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    do_message(pos);
 | 
						||
 | 
						||
    if (!hidden())
 | 
						||
    {
 | 
						||
      const char* c = _values.get(pos);
 | 
						||
      if (c == NULL) c = val;
 | 
						||
      if (c) string_at(x(), _y, c);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_group
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TForm_group : public TForm_item
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual const char* class_name() const { return "GRUPPO"; }
 | 
						||
  virtual bool update() { return TRUE; }
 | 
						||
 | 
						||
public:
 | 
						||
  TForm_group(TPrint_section* section) : TForm_item(section) {};
 | 
						||
  virtual ~TForm_group() {}
 | 
						||
};
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TGraphic_section
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TGraphic_section : public TPrint_section
 | 
						||
{
 | 
						||
  TString _back;
 | 
						||
 | 
						||
protected:
 | 
						||
  // @cmember Crea un campo della classe specificata
 | 
						||
  virtual TForm_item* create_item(const TString& s);
 | 
						||
 | 
						||
  virtual bool update();
 | 
						||
 | 
						||
public:
 | 
						||
  void append(const char* s) { _back << s; }
 | 
						||
  
 | 
						||
  TGraphic_section(TForm* f, pagetype pt) : TPrint_section(f, 'G', pt) {}
 | 
						||
  virtual ~TGraphic_section() {}
 | 
						||
};
 | 
						||
 | 
						||
class TForm_picture : public TForm_item
 | 
						||
{ 
 | 
						||
  TFieldref _field;
 | 
						||
 | 
						||
protected:
 | 
						||
  virtual const char* class_name() const { return "FIGURA"; }
 | 
						||
  virtual bool parse_item(TScanner& scanner);
 | 
						||
  virtual bool update();
 | 
						||
 | 
						||
public:
 | 
						||
  TForm_picture(TPrint_section* section) : TForm_item(section) {}
 | 
						||
  virtual ~TForm_picture() {}
 | 
						||
};
 | 
						||
 | 
						||
class TForm_line : public TForm_item
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual const char* class_name() const { return "LINEA"; }
 | 
						||
  virtual bool update();
 | 
						||
 | 
						||
public:
 | 
						||
  TForm_line(TGraphic_section* section) : TForm_item(section) {}
 | 
						||
  virtual ~TForm_line() {}
 | 
						||
};
 | 
						||
 | 
						||
class TForm_box : public TForm_item
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual const char* class_name() const { return "BOX"; }
 | 
						||
  virtual bool update();
 | 
						||
 | 
						||
public:
 | 
						||
  TForm_box(TGraphic_section* section) : TForm_item(section) {}
 | 
						||
  virtual ~TForm_box() {}
 | 
						||
};
 | 
						||
 | 
						||
bool TForm_picture::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (scanner.key() == "FI")  // FIELD reference
 | 
						||
  {
 | 
						||
    _field = scanner.line();
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
  return TForm_item::parse_item(scanner);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_picture::update()
 | 
						||
{
 | 
						||
  TFilename i;
 | 
						||
  if (_field.ok())
 | 
						||
  {
 | 
						||
    const TRelation* r = form().relation();
 | 
						||
    if (r)
 | 
						||
    {  
 | 
						||
      TToken_string list(_field.read(*r), '\n');
 | 
						||
      FOR_EACH_TOKEN(list, tok)
 | 
						||
      {
 | 
						||
        i = tok;
 | 
						||
        const int pos = i.find('|');
 | 
						||
        if (pos >= 0)
 | 
						||
          i.cut(pos);
 | 
						||
        if (xvt_str_compare_ignoring_case(i.ext(), "bmp") == 0)
 | 
						||
        {
 | 
						||
          i.replace('\\', '/');
 | 
						||
          i.trim();  
 | 
						||
          break;
 | 
						||
        }  
 | 
						||
        else
 | 
						||
          i.cut(0);   
 | 
						||
      }
 | 
						||
    }
 | 
						||
    else
 | 
						||
      NFCHECK("Can't read picture from NULL relation");
 | 
						||
  }  
 | 
						||
  else    
 | 
						||
    i = _prompt;
 | 
						||
  i.custom_path();
 | 
						||
  bool ok = i.not_empty() && i.exist();  
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    i << ',' << _x << ',' << _y << ',' << (_x+width()-1) << ',' << (_y+height()-1);
 | 
						||
    
 | 
						||
    if (section().section_type() == 'G')
 | 
						||
    {
 | 
						||
      i.insert("i{", 0); i << '}';
 | 
						||
      ((TGraphic_section&)section()).append(i);
 | 
						||
    }   
 | 
						||
    else
 | 
						||
    {
 | 
						||
      i.insert("@F[", 0); i << ']';
 | 
						||
      TPrintrow& row = section().row(_y-1);         
 | 
						||
      row.put(i);                             
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_line::update()
 | 
						||
{
 | 
						||
  int spessore = 1;
 | 
						||
  char codice = 'l';
 | 
						||
  for (int j = _prompt.len()-1; j >= 0; j--)
 | 
						||
  {
 | 
						||
    switch (_prompt[j])
 | 
						||
    {
 | 
						||
    case 'B':
 | 
						||
    case 'b':
 | 
						||
      spessore = 3; break;
 | 
						||
    case 'R':
 | 
						||
    case 'r':
 | 
						||
      codice = 'r'; break;
 | 
						||
    default:
 | 
						||
      break;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  // Calcola la vera coordinata y della linea
 | 
						||
  const int y = _y >= 0 ? _y : (printer().formlen()+_y+1);
 | 
						||
  
 | 
						||
  TString80 i;
 | 
						||
  i << 'W' << spessore << codice
 | 
						||
    << '{' << _x << ',' << y << ','
 | 
						||
    << (_x+width()-1) << ',' << (y+height()-1) << '}';
 | 
						||
 | 
						||
  ((TGraphic_section&)section()).append(i);
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_box::update()
 | 
						||
{
 | 
						||
  TString80 i;
 | 
						||
  const int w = _prompt[0] == '@' ? 3 : 1;
 | 
						||
  i << 'W' << w << "b{" << _x << ',' << _y << ','
 | 
						||
    << (_x+width()-1) << ',' << (_y+height()-1) << '}';
 | 
						||
 | 
						||
  ((TGraphic_section&)section()).append(i);
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
TForm_item* TGraphic_section::create_item(const TString& typ)
 | 
						||
{
 | 
						||
  TForm_item* fff = NULL;
 | 
						||
  if (typ.compare("LINEA", 2, TRUE) == 0)
 | 
						||
    fff = new TForm_line(this); else 
 | 
						||
  if (typ.compare("BOX", 2, TRUE) == 0)
 | 
						||
    fff = new TForm_box(this); else 
 | 
						||
  if (typ.compare("FIGURA", 2, TRUE) == 0)
 | 
						||
    fff = new TForm_picture(this);
 | 
						||
  return fff;  
 | 
						||
}
 | 
						||
 | 
						||
bool TGraphic_section::update()
 | 
						||
{
 | 
						||
  _back.cut(0);
 | 
						||
  const bool ok = TPrint_section::update();
 | 
						||
  
 | 
						||
  int index;
 | 
						||
  switch(page_type())
 | 
						||
  {        
 | 
						||
  case even_page : index = 1; break;
 | 
						||
  case first_page: index = 2; break;
 | 
						||
  case last_page : index = 3; break;
 | 
						||
  default        : index = 0; break;
 | 
						||
  }
 | 
						||
  printer().setbackground(_back, index);
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TPrint_section
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TMask* TPrint_section::_msk = NULL;
 | 
						||
 | 
						||
 | 
						||
word TPrint_section::height() const
 | 
						||
{ 
 | 
						||
  word h = _height;
 | 
						||
  if (subsection_above() && (word)subsection_above()->effective_height() > h)
 | 
						||
  {
 | 
						||
    h = subsection_above()->effective_height();
 | 
						||
  }  
 | 
						||
  if (short(h) < 0)                  // Can't write h < 0!
 | 
						||
  {
 | 
						||
    if (section_type() == 'F')
 | 
						||
    {  
 | 
						||
      h += printer().formlen();
 | 
						||
      if (short(h) < 0) // Still < 0 ?? get out...
 | 
						||
        h = 0;
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      h = _rows.items();
 | 
						||
      if (h == 0)
 | 
						||
        h = 0xFFFF - _height + 1;    // Same as abs(_height)
 | 
						||
    }    
 | 
						||
  }
 | 
						||
  return h;  
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TExpression & TPrint_section::eval_expr(TExpression & expr,int defaultfile_id)
 | 
						||
{ 
 | 
						||
  for (int j = 0; j < expr.numvar(); j++) 
 | 
						||
  { // scansione delle variabili dell'espressione di rvalue
 | 
						||
    TString var= expr.varname(j);
 | 
						||
    if (var[0]=='#') 
 | 
						||
    { // riferimento ad un campo del form
 | 
						||
      var.ltrim(1);
 | 
						||
      TForm_item &fi= find_field(atoi(var));
 | 
						||
      expr.setvar(j, fi.get()); // il valore corrente del campo viene settato nell'espressione
 | 
						||
    } 
 | 
						||
    else 
 | 
						||
    { // riferimento ad un campo di file
 | 
						||
      TFieldref fr = TFieldref(var, 0);
 | 
						||
      int fileno=fr.file();
 | 
						||
      // choose logical file number 
 | 
						||
      fileno= (fileno==0) ? (defaultfile_id>0 ? defaultfile_id : 0): fileno;
 | 
						||
      expr.setvar(j, fr.read( form().relation()->lfile(fileno).curr() ) ); // il valore corrente del campo viene settato nell'espressione
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return expr;
 | 
						||
}
 | 
						||
 | 
						||
TPrint_section::TPrint_section(TForm* f, char st, pagetype pt, TForm_subsection* father)
 | 
						||
: _height(0), _ofspc(0), _ofsvr(0), _nfld(0), _dirty(FALSE), 
 | 
						||
  _columnwise(FALSE), _temp(0), _form(f), _sec_type(st), _page_type(pt),
 | 
						||
  _upsection(father), _repeat_count(0)
 | 
						||
{
 | 
						||
  reset_tabs();
 | 
						||
}
 | 
						||
 | 
						||
TPrint_section::~TPrint_section()
 | 
						||
{
 | 
						||
  if (_msk)
 | 
						||
  {
 | 
						||
    delete _msk;
 | 
						||
    _msk = NULL;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
TForm_item* TPrint_section::create_item(const TString& s)
 | 
						||
{
 | 
						||
  TForm_item* f = NULL;
 | 
						||
  if (s.compare("STRINGA", 2, TRUE) == 0)
 | 
						||
    f = new TForm_string(this); else
 | 
						||
  if (s.compare("NUMERO", 2, TRUE) == 0)
 | 
						||
    f = new TForm_number(this); else
 | 
						||
  if (s.compare("VALUTA", 2, TRUE) == 0)
 | 
						||
    f = new TForm_currency(this); else
 | 
						||
  if (s.compare("DATA", 2, TRUE) == 0)
 | 
						||
    f = new TForm_date(this); else
 | 
						||
  if (s.compare("LISTA", 2, TRUE) == 0)
 | 
						||
    f = new TForm_list(this); else
 | 
						||
  if (s.compare("GRUPPO", 2, TRUE) == 0)
 | 
						||
    f = new TForm_group(this); else
 | 
						||
  if (s.compare("SECTION", 2, TRUE) == 0)
 | 
						||
    f = new TForm_subsection(this); else
 | 
						||
  if (s.compare("FIGURA", 2, TRUE) == 0)
 | 
						||
    f = new TForm_picture(this);
 | 
						||
  
 | 
						||
  return f;  
 | 
						||
}
 | 
						||
 | 
						||
void  TPrint_section::change_field(int n, TForm_item* f)
 | 
						||
{
 | 
						||
  _item.add(f,n);
 | 
						||
}
 | 
						||
 | 
						||
void  TPrint_section::insert_field(int n, TForm_item* f)
 | 
						||
{
 | 
						||
  _item.insert(f,n);
 | 
						||
}
 | 
						||
 | 
						||
void  TPrint_section::add_field(TForm_item* f)
 | 
						||
{
 | 
						||
  _item.add(f);
 | 
						||
}
 | 
						||
 | 
						||
inline int TPrint_section::subsections()const 
 | 
						||
{
 | 
						||
  return _subsections.items();
 | 
						||
}
 | 
						||
 | 
						||
inline TForm_subsection* TPrint_section::subsection(int n) const 
 | 
						||
{
 | 
						||
  return (TForm_subsection* )_subsections.objptr(n);
 | 
						||
}
 | 
						||
 | 
						||
inline void  TPrint_section::add_subsection(TForm_subsection* s)
 | 
						||
{
 | 
						||
  _subsections.add(s);
 | 
						||
}
 | 
						||
 | 
						||
const TPrint_section& TPrint_section::copy(const TPrint_section& ps)
 | 
						||
{
 | 
						||
  _msk = ps._msk;  _height = ps._height;  _ofspc = ps._ofspc;
 | 
						||
  _ofsvr = ps._ofsvr;  _nfld  = ps._nfld;  _dirty = ps._dirty;
 | 
						||
  _temp = ps._temp; _form = ps._form;
 | 
						||
  _sec_type = ps._sec_type; _page_type = ps._page_type; 
 | 
						||
  _item = ps._item; 
 | 
						||
  // subsections
 | 
						||
  _upsection = ps._upsection;  _repeat_count = ps._repeat_count;  _subsections=ps._subsections;
 | 
						||
  // columnwise
 | 
						||
  _columnwise = ps._columnwise;  
 | 
						||
  for (int i = 0; i < MAXCOLUMNS; i++) _tab[i] = ps._tab[i];
 | 
						||
  return ps;
 | 
						||
}
 | 
						||
 | 
						||
TPrintrow& TPrint_section::row(int num)
 | 
						||
{
 | 
						||
  TPrintrow* pr = (TPrintrow*)_rows.objptr(num);
 | 
						||
  if (pr == NULL)
 | 
						||
  {
 | 
						||
    pr = new TPrintrow;
 | 
						||
    _rows.add(pr, num);
 | 
						||
  }
 | 
						||
  return *pr;
 | 
						||
}
 | 
						||
 | 
						||
TPrintrow& TPrint_section::titlerow(int num)
 | 
						||
{
 | 
						||
  TPrintrow* pr = (TPrintrow*)_titlerows.objptr(num);
 | 
						||
  if (pr == NULL)
 | 
						||
  {
 | 
						||
    pr = new TPrintrow;
 | 
						||
    _titlerows.add(pr, num);
 | 
						||
  }
 | 
						||
  return *pr;
 | 
						||
}
 | 
						||
 | 
						||
void TPrint_section::reset_tabs()
 | 
						||
{
 | 
						||
  for (int i = 0; i < MAXCOLUMNS; i++)
 | 
						||
    _tab[i] = -1;
 | 
						||
}
 | 
						||
 | 
						||
int TPrint_section::tab(int col)
 | 
						||
{
 | 
						||
  int ret = -1;
 | 
						||
  if (_columnwise)
 | 
						||
  {
 | 
						||
    if (_tab[0] == -1 && fields())
 | 
						||
    {
 | 
						||
      _tab[0] = 2;
 | 
						||
      {
 | 
						||
        int extraoff=0;
 | 
						||
        // compute column offset
 | 
						||
        _nfld = 0;
 | 
						||
        short maxcolreached = 0,mincolreached = MAXCOLUMNS+1;
 | 
						||
        word i;
 | 
						||
        
 | 
						||
        for (i = 0; i < fields(); i++)
 | 
						||
        {
 | 
						||
          const TForm_item& fi = field(i);
 | 
						||
          if (!fi.is_section() && fi.shown())
 | 
						||
          {
 | 
						||
            const int curr_col=fi._x;
 | 
						||
            CHECKD (curr_col >=0 && curr_col < MAXCOLUMNS, "Colonna ammessa e non concessa: ", field(i)._x);
 | 
						||
            _tab[curr_col] = fi._width + 1; // one is for separation
 | 
						||
            if (curr_col < mincolreached) mincolreached = curr_col;
 | 
						||
            if (curr_col > maxcolreached) maxcolreached = curr_col;
 | 
						||
            _nfld++;
 | 
						||
          }
 | 
						||
        }
 | 
						||
        // cumulate offsets
 | 
						||
        
 | 
						||
        if (_upsection)
 | 
						||
        {
 | 
						||
          if (mincolreached<=MAXCOLUMNS && mincolreached>0)
 | 
						||
          {
 | 
						||
            // print section of a subsection: extra offset
 | 
						||
            extraoff=_upsection->section().tab(mincolreached-1);
 | 
						||
            for (i = 1 ; i < (word)mincolreached; i++)
 | 
						||
            {
 | 
						||
              _tab[i]=_upsection->section()._tab[i];
 | 
						||
            }
 | 
						||
            if (extraoff== _tab[mincolreached-1])
 | 
						||
              extraoff=0;
 | 
						||
            else
 | 
						||
              extraoff-=_upsection->section().tab(0);
 | 
						||
          } 
 | 
						||
        } 
 | 
						||
          
 | 
						||
        int last = 0;
 | 
						||
        for (i = mincolreached ; i <= (word)maxcolreached; i++)
 | 
						||
        {
 | 
						||
          if (_tab[i - 1] != -1)
 | 
						||
            last = i - 1;
 | 
						||
          if (_tab[i] != -1)
 | 
						||
            _tab[i] += _tab[last]+extraoff;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    // se manca la colonna, vai a prendere quella immediatamente prima
 | 
						||
    while (_tab[col] == -1 && col > 0)
 | 
						||
      col--;
 | 
						||
    ret = _tab[col];
 | 
						||
  }
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
word TPrint_section::subs_height() const 
 | 
						||
{ 
 | 
						||
  TForm_subsection *fss;
 | 
						||
  word h=0;
 | 
						||
  if (subsections())
 | 
						||
  {
 | 
						||
    fss=subsection(0);
 | 
						||
    h=subsection(0)->minheight();
 | 
						||
    h+=subsection(0)->printsection().subs_height(); // ricorsione...
 | 
						||
  }
 | 
						||
  return h; 
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TPrint_section::offset(int& x, int& y)
 | 
						||
{
 | 
						||
  if (x >= 0)
 | 
						||
  {
 | 
						||
    if (_columnwise) x = tab(x-1) + _ofspc;
 | 
						||
    x += form().offset_x();
 | 
						||
  }
 | 
						||
  if (y >= 0) 
 | 
						||
    y += form().offset_y() + (_height * _repeat_count);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TForm_item* TPrint_section::parse_item(const TString& s)
 | 
						||
{          
 | 
						||
  TForm_item* f = create_item(s);
 | 
						||
#ifdef DBG
 | 
						||
  if (f == NULL)
 | 
						||
    yesnofatal_box(FR("Tipo di campo del form non riconosciuto: '%s'"), (const char*)s);
 | 
						||
#endif
 | 
						||
  return f;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TForm_item* TPrint_section::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  return parse_item(scanner.key());
 | 
						||
}
 | 
						||
 | 
						||
bool TPrint_section::parse_head(TScanner& scanner)
 | 
						||
{
 | 
						||
  _height = scanner.integer();
 | 
						||
  scanner.integer();scanner.integer(); // Eat offset X and Y of Print_section if present
 | 
						||
 | 
						||
  if (scanner.popkey() == "CO")        // COLUMNWISE attribute
 | 
						||
    _columnwise = TRUE;
 | 
						||
  else if (scanner.key() == "NO")        // NORMAL (no COLUMNWISE) attribute
 | 
						||
    _columnwise = FALSE;
 | 
						||
  else 
 | 
						||
  {
 | 
						||
    if (section_above())
 | 
						||
      _columnwise = section_above()->_columnwise;
 | 
						||
    else
 | 
						||
      _columnwise = FALSE;
 | 
						||
    scanner.push();
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrint_section::parse_body(TScanner& scanner)
 | 
						||
{
 | 
						||
  while (scanner.popkey() != "EN")
 | 
						||
  {
 | 
						||
    TForm_item *fi = parse_item(scanner);
 | 
						||
    if (fi == NULL) return FALSE;
 | 
						||
 | 
						||
    if (fi->parse(scanner)) 
 | 
						||
    {
 | 
						||
      _item.add(fi);
 | 
						||
    } else
 | 
						||
      return FALSE;
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrint_section::parse(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (parse_head(scanner))
 | 
						||
    return parse_body(scanner);
 | 
						||
  return FALSE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Azzera tutte le righe della sezione di stampa
 | 
						||
void TPrint_section::reset()
 | 
						||
{          
 | 
						||
  for (int i = _rows.last(); i >= 0; i--)
 | 
						||
  {
 | 
						||
    if (_height > 0xF000)
 | 
						||
      _rows.destroy(i);
 | 
						||
    else
 | 
						||
      row(i).reset();
 | 
						||
  }  
 | 
						||
}
 | 
						||
 | 
						||
// Azzera tutti i campi della sezione di stampa
 | 
						||
void TPrint_section::reset_fields()
 | 
						||
{
 | 
						||
  for (word i = 0; i < fields(); i++)
 | 
						||
  {
 | 
						||
		TForm_item& f = field(i);
 | 
						||
    if (f.is_section())
 | 
						||
    {
 | 
						||
			TPrint_section& s = ((TForm_subsection&)f).printsection();
 | 
						||
			s.reset_fields();
 | 
						||
		}
 | 
						||
		else
 | 
						||
			f.set("");
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// Aggiorna tutti i campi
 | 
						||
bool TPrint_section::update()
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
 | 
						||
  reset();
 | 
						||
  for (word i = 0; i < fields(); i++)
 | 
						||
  {
 | 
						||
    if (!field(i).is_section())
 | 
						||
    {
 | 
						||
      const bool esito = field(i).update();
 | 
						||
      if (!esito) 
 | 
						||
        ok = false;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (ok && _sec_type == 'B' && _page_type == odd_page) 
 | 
						||
  {
 | 
						||
    printer().set_form_name(_form->filename());
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
TForm_item* TPrint_section::exist_field(short id) const
 | 
						||
{
 | 
						||
  TForm_item* f = find_field_everywhere(id,this);
 | 
						||
  return f;
 | 
						||
}
 | 
						||
 | 
						||
TForm_item& TPrint_section::find_field(short id) const
 | 
						||
{
 | 
						||
  TForm_item* f = exist_field(id);
 | 
						||
  if (f) return *f;
 | 
						||
 | 
						||
  TString4 str;
 | 
						||
  str << section_type();
 | 
						||
  switch (page_type())
 | 
						||
  {
 | 
						||
  case first_page: str << 'F'; break;
 | 
						||
  case even_page : str << 'E'; break;
 | 
						||
  case last_page : str << 'L'; break;
 | 
						||
  default        : str << 'O'; break;
 | 
						||
  }
 | 
						||
  yesnofatal_box(FR("Impossibile trovare il campo %d nella sezione %s del form %s"), 
 | 
						||
                 id, (const char*)str, (const char*)form().name());
 | 
						||
  return field(0);
 | 
						||
}
 | 
						||
 | 
						||
// Ricerca i campi verso l'alto:
 | 
						||
//   prima la sezione attuale, poi le sezioni sopra
 | 
						||
TForm_item *TPrint_section::find_field_everywhere(short id,const TPrint_section *starting_section) const
 | 
						||
{
 | 
						||
  TForm_item * f ;
 | 
						||
  for(word i = 0; i < fields(); i++)
 | 
						||
  {
 | 
						||
    f = &field(i);
 | 
						||
    if (f->id() == id) return f;
 | 
						||
  }
 | 
						||
  // look into the section above ("father" )
 | 
						||
  if (section_above() && section_above()!=starting_section) {
 | 
						||
    f=section_above()->find_field_everywhere(id,this);
 | 
						||
    if (f)
 | 
						||
      return f;
 | 
						||
  }   
 | 
						||
  // look into sections beside ("brothers" )
 | 
						||
  for (int j = 0; j < subsections(); j++) 
 | 
						||
  {
 | 
						||
    const TPrint_section &bs=subsection(j)->printsection();
 | 
						||
    if (&bs!=starting_section) {
 | 
						||
      f=bs.find_field_everywhere(id,this);
 | 
						||
      if (f)
 | 
						||
        return f;
 | 
						||
      }
 | 
						||
  }
 | 
						||
  return NULL;
 | 
						||
}
 | 
						||
 | 
						||
TForm_item* TPrint_section::exist_field(const char *sec_name) const
 | 
						||
{
 | 
						||
  TForm_item* f = find_field_everywhere(sec_name,this);
 | 
						||
  return f;
 | 
						||
}
 | 
						||
 | 
						||
TForm_item& TPrint_section::find_field(const char *sec_name) const
 | 
						||
{
 | 
						||
  TForm_item* f = exist_field(sec_name);
 | 
						||
  if (f) return *f;
 | 
						||
  yesnofatal_box("Can't find subsection '%s'", sec_name);
 | 
						||
  return field(0);
 | 
						||
}
 | 
						||
 | 
						||
// Ricerca i campi verso il basso:
 | 
						||
//   prima la sezione attuale, poi le sottosezioni
 | 
						||
TForm_item *TPrint_section::find_field_everywhere(const char *sec_name,const TPrint_section *starting_section) const
 | 
						||
{
 | 
						||
  // search here
 | 
						||
  int j;
 | 
						||
  
 | 
						||
  for (j = 0; j < subsections(); j++) {
 | 
						||
    const char *n=subsection(j)->name();
 | 
						||
    if (strcmp(n,sec_name)==0)
 | 
						||
      return subsection(j);
 | 
						||
  }
 | 
						||
  // search down
 | 
						||
  for (j = 0; j < subsections(); j++) {
 | 
						||
    TForm_item *it=subsection(j)->printsection().find_field_everywhere(sec_name,starting_section);
 | 
						||
    if (it)
 | 
						||
      return it;
 | 
						||
  }
 | 
						||
  return NULL;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
// classe per le informazioni sugli skip dei file del cursore del form
 | 
						||
class TForm_skip_info : public TObject
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual TObject * dup() const;  
 | 
						||
public :
 | 
						||
  bool _match_result;
 | 
						||
  int _match_number;
 | 
						||
  ~TForm_skip_info(){};
 | 
						||
  TForm_skip_info();
 | 
						||
};
 | 
						||
 | 
						||
TObject * TForm_skip_info ::dup() const
 | 
						||
{
 | 
						||
  TForm_skip_info *p=new TForm_skip_info;
 | 
						||
  p->_match_result=_match_result;
 | 
						||
  p->_match_number=_match_number;
 | 
						||
  return p;
 | 
						||
}
 | 
						||
 | 
						||
TForm_skip_info::TForm_skip_info()
 | 
						||
{
 | 
						||
  _match_result=FALSE;
 | 
						||
  _match_number=0;
 | 
						||
}
 | 
						||
 | 
						||
TForm_editor& TForm::editor() const
 | 
						||
{ return (TForm_editor&)main_app(); }
 | 
						||
 | 
						||
// 
 | 
						||
bool TForm::parse_use(TScanner& scanner, TString & filter)
 | 
						||
{
 | 
						||
  const int logicnum = scanner.integer();
 | 
						||
  const char* tab = NULL;
 | 
						||
 | 
						||
  if (logicnum > 0)
 | 
						||
    _relation = new TRelation(logicnum);
 | 
						||
  else
 | 
						||
  {
 | 
						||
    tab = scanner.pop();
 | 
						||
    _relation = new TRelation(tab);
 | 
						||
  }
 | 
						||
 | 
						||
  int key = 1;  // key number
 | 
						||
  if (scanner.popkey() == "KE")
 | 
						||
    key = scanner.integer();
 | 
						||
  else
 | 
						||
    scanner.push();
 | 
						||
 | 
						||
	if (scanner.popkey() == "FI" || scanner.key() == "SE")  // "Filter" : sorted defined by the user 
 | 
						||
    filter = parse_filter(scanner);
 | 
						||
	else
 | 
						||
    scanner.push();
 | 
						||
 | 
						||
  if (scanner.popkey() == "BY")  // "sort BY": user-defined sort
 | 
						||
 | 
						||
  {
 | 
						||
    TToken_string ordexpr(parse_sortexpr(scanner));
 | 
						||
    _cursor = new TSorted_cursor(_relation, ordexpr, "", key);
 | 
						||
  }
 | 
						||
	else
 | 
						||
	{
 | 
						||
    scanner.push();
 | 
						||
    _cursor = new TCursor(_relation, "", key);
 | 
						||
  }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm::parse_join(TScanner& scanner)
 | 
						||
{
 | 
						||
  TString16 j(scanner.pop());           // File or table
 | 
						||
 | 
						||
  int to = 0;
 | 
						||
  if (scanner.popkey() == "TO")         // TO keyword
 | 
						||
  {
 | 
						||
    const char* n = scanner.pop();
 | 
						||
    to = name2log(n);
 | 
						||
  }
 | 
						||
  else scanner.push();
 | 
						||
  return parse_join_param(scanner,_relation,j,to);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm::parse_join_param(TScanner& scanner,TRelation * rel, TString16 j, int to )
 | 
						||
{
 | 
						||
  int key = 1;
 | 
						||
  if (scanner.popkey() == "KE")
 | 
						||
    key = scanner.integer();
 | 
						||
  else scanner.push();
 | 
						||
 | 
						||
  int alias = 0;
 | 
						||
  if (scanner.popkey() == "AL")
 | 
						||
    alias = scanner.integer();
 | 
						||
  else scanner.push();
 | 
						||
 | 
						||
  TToken_string exp(80);
 | 
						||
  if (scanner.pop() == "INTO")
 | 
						||
  {
 | 
						||
    exp=parse_filter(scanner);
 | 
						||
  }
 | 
						||
  if (exp.empty())
 | 
						||
    yesnofatal_box("JOIN senza espressioni INTO");
 | 
						||
 | 
						||
  if (isdigit(j[0]))
 | 
						||
    rel->add(atoi(j), exp, key, to, alias);   // join file
 | 
						||
  else
 | 
						||
    rel->add(j, exp, key, to, alias);         // join table
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm::parse_sortedjoin(TScanner& scanner)
 | 
						||
{
 | 
						||
  TToken_string filter,sortexp;
 | 
						||
  TString16 j(scanner.pop());           // File or table
 | 
						||
  if (scanner.popkey() == "BY" )
 | 
						||
  {
 | 
						||
    sortexp=parse_sortexpr(scanner);
 | 
						||
  } else scanner.push();
 | 
						||
  if (scanner.popkey() == "FI" ) {
 | 
						||
    filter=parse_filter(scanner);
 | 
						||
  } else scanner.push();
 | 
						||
  if (filter.empty() && sortexp.empty())
 | 
						||
    yesnofatal_box(TR("Sort senza espressioni di ordinamento o filtri"));
 | 
						||
  TRelation * sortrel=new TRelation(atoi(j)); 
 | 
						||
  while (ok() && scanner.popkey() != "JO" )
 | 
						||
  {
 | 
						||
    if (scanner.key() == "US")         // USING keyword
 | 
						||
    {
 | 
						||
      TString16 subj(scanner.pop());           // File or table
 | 
						||
      parse_join_param(scanner,sortrel,subj,atoi(j));
 | 
						||
    } else
 | 
						||
      yesnofatal_box(FR("Token non riconosciuto in SORT:%s"), (const char *) scanner.key());
 | 
						||
  } 
 | 
						||
 | 
						||
  int to = 0;
 | 
						||
  if (scanner.popkey() == "TO")         // TO keyword
 | 
						||
  {
 | 
						||
    const char* n = scanner.pop();
 | 
						||
    to = name2log(n);
 | 
						||
  }
 | 
						||
  else scanner.push();
 | 
						||
 | 
						||
  int key = 1;
 | 
						||
  if (scanner.popkey() == "KE")
 | 
						||
    key = scanner.integer();
 | 
						||
  else scanner.push();
 | 
						||
 | 
						||
  int alias = 0;
 | 
						||
  if (scanner.popkey() == "AL")
 | 
						||
    alias = scanner.integer();
 | 
						||
  else scanner.push();
 | 
						||
 | 
						||
  TToken_string exp(80);
 | 
						||
  if (scanner.pop() == "INTO")
 | 
						||
  {
 | 
						||
    const char* r = scanner.pop();
 | 
						||
    while (strchr(r, '=') != NULL)
 | 
						||
    {
 | 
						||
      exp.add(r);
 | 
						||
      r = scanner.pop();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  if (exp.empty())
 | 
						||
    yesnofatal_box(TR("JOIN senza espressioni INTO"));
 | 
						||
  scanner.push();
 | 
						||
 | 
						||
  TSortedfile *sf= new TSortedfile(atoi(j),sortrel,sortexp,filter,key);
 | 
						||
 | 
						||
  _relation->add((TLocalisamfile *)sf, exp, key, to, alias,FALSE);         // join table
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
TToken_string TForm::parse_filter(TScanner& scanner)
 | 
						||
{
 | 
						||
  TToken_string filter;
 | 
						||
  const char* r = scanner.pop();
 | 
						||
  while (strchr(r, '=') != NULL)
 | 
						||
  {
 | 
						||
    filter.add(r);
 | 
						||
    r = scanner.pop();
 | 
						||
  }
 | 
						||
  scanner.push();
 | 
						||
  return filter;
 | 
						||
}
 | 
						||
 | 
						||
TToken_string TForm::parse_sortexpr(TScanner& scanner)
 | 
						||
{
 | 
						||
  TToken_string sortexp;
 | 
						||
  TToken_string se(scanner.line(),' ');
 | 
						||
  const char * c;
 | 
						||
  while ((c=se.get())) 
 | 
						||
    if (*c!='\0')
 | 
						||
      sortexp.add(c);
 | 
						||
  return sortexp;
 | 
						||
}
 | 
						||
 | 
						||
TRelation_description& TForm::rel_desc() const
 | 
						||
{
 | 
						||
  CHECK(_rel_desc, "No relation description");
 | 
						||
  return *_rel_desc;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm::parse_description(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (edit_level() > 0)
 | 
						||
  {
 | 
						||
    CHECK(_rel_desc == NULL, "Can't parse descriptions two times");
 | 
						||
    _rel_desc = new TRelation_description(*_relation);
 | 
						||
  }
 | 
						||
 | 
						||
  bool ok = scanner.popkey() == "DE";
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    if (edit_level() > 0)
 | 
						||
    {
 | 
						||
      scanner.popkey(); // eat BEGIN
 | 
						||
      TFieldref fld;
 | 
						||
      while (scanner.pop() != "END")
 | 
						||
      {
 | 
						||
        fld = scanner.token();
 | 
						||
        _rel_desc->set_cur_file(fld.file());
 | 
						||
        if (fld.name() == "*")
 | 
						||
          _rel_desc->file_desc(scanner.string());
 | 
						||
        else
 | 
						||
          _rel_desc->set_field_description(fld.name(), scanner.string());
 | 
						||
      }
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      while (scanner.line() != "END");
 | 
						||
      ok = FALSE;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else scanner.push();
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
void TForm::print_description(ostream& out) const
 | 
						||
{
 | 
						||
  out << "DESCRIPTION\nBEGIN\n";
 | 
						||
  out << rel_desc();
 | 
						||
  out << "END\n" << endl;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm::parse_general(TScanner &scanner)
 | 
						||
{
 | 
						||
  bool ok = scanner.popkey() == "GE";
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    while (scanner.pop() != "END")
 | 
						||
    {
 | 
						||
      if (scanner.key() == "OF")   // Offsets
 | 
						||
      {
 | 
						||
        _x = scanner.integer();
 | 
						||
        _y = scanner.integer();
 | 
						||
      }
 | 
						||
      if (scanner.key() == "FO")   // Font name
 | 
						||
        _fontname = scanner.string();
 | 
						||
      if (scanner.key() == "SI")   // Font size
 | 
						||
        _fontsize = scanner.integer();
 | 
						||
      if (scanner.key() == "CA")   // Carattere di posizionamento
 | 
						||
        _char_to_pos = scanner.string()[0];
 | 
						||
      if (scanner.key() == "IN")   // Riga e colonna del posizionamento iniziale
 | 
						||
      {
 | 
						||
        _ipx = scanner.integer();
 | 
						||
        _ipy = scanner.integer();
 | 
						||
      }
 | 
						||
      if (scanner.key() == "FI")   // Riga e colonna del posizionamento finale
 | 
						||
        _fpx = scanner.integer();
 | 
						||
 | 
						||
      if (scanner.key() == "GR")   // Carattere di fincatura
 | 
						||
        set_fincatura(scanner.string());
 | 
						||
 | 
						||
      if (scanner.key() == "PA")   // Numero di pagine fisso
 | 
						||
        _npages=scanner.integer();
 | 
						||
 | 
						||
      if (scanner.key() == "VA")   // Valuta/Divisa impiegata 
 | 
						||
      {
 | 
						||
        _curr_codval=scanner.string();   // DA ELIMINARE
 | 
						||
      }
 | 
						||
 | 
						||
      extended_parse_general(scanner); // Parse non-standard parameters
 | 
						||
    }
 | 
						||
  } else scanner.push();
 | 
						||
 | 
						||
  return (ok);
 | 
						||
}
 | 
						||
 | 
						||
void TForm::print_general(ostream& out) const
 | 
						||
{
 | 
						||
  out << "GENERAL\nBEGIN\n";
 | 
						||
  out << "  OFFSET " << _x << " " << _y << "\n";
 | 
						||
  out << "  FONT " << "\"" << _fontname << "\"\n";
 | 
						||
  out << "  SIZE " << _fontsize << "\n" ;
 | 
						||
  if (_char_to_pos != '\0')
 | 
						||
  {
 | 
						||
    out << "  CARATTERE \"" << _char_to_pos << "\"\n" ;
 | 
						||
    out << "  INIZIO_POS " << _ipx << " " << _ipy << "\n";
 | 
						||
    out << "  FINE_POS " << _fpx << "\n";
 | 
						||
  }
 | 
						||
  out << "  GRID \"" << _fink << "\"\n";
 | 
						||
  out << "END\n" << endl;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Controlla se esiste una sezione di stampa
 | 
						||
//
 | 
						||
// @rdesc Ritorna la <c TPrint_section> trovata o creata
 | 
						||
TPrint_section* TForm::exist(
 | 
						||
      char s,   // @parm Indica in quale parte deve cercare:
 | 
						||
        //
 | 
						||
        // @flag F | Tra i footers
 | 
						||
        // @flag G | Tra gli sfondi
 | 
						||
        // @flag H | Tra gli headers
 | 
						||
        // @flag B | Tra i bodies (default)
 | 
						||
    pagetype t,   // @parm Tipo di pagina (vedi <t pagetype>)
 | 
						||
    bool create)  // @parm Indica se creare la sezione nel caso non esista
 | 
						||
{
 | 
						||
  TArray* a;
 | 
						||
  switch (toupper(s))
 | 
						||
  {
 | 
						||
  case 'F':
 | 
						||
    a = &_foot; break;
 | 
						||
  case 'G':
 | 
						||
    a = &_back; break;
 | 
						||
  case 'H':
 | 
						||
    a = &_head; break;
 | 
						||
  default:
 | 
						||
    a = &_body; break;
 | 
						||
  }
 | 
						||
 | 
						||
  TPrint_section* sec = (TPrint_section*)a->objptr(t);
 | 
						||
  if (sec == NULL && create)
 | 
						||
  {
 | 
						||
    sec = (s == 'G') ? new TGraphic_section(this, t) : new TPrint_section(this, s, t);
 | 
						||
    a->add(sec, t);
 | 
						||
  }
 | 
						||
 | 
						||
  return sec;
 | 
						||
}
 | 
						||
 | 
						||
TForm_item* TForm::exist_field(char s, pagetype t, short id) const
 | 
						||
{
 | 
						||
  const TPrint_section* ps = ((TForm*)this)->exist(s, t);
 | 
						||
  CHECKD(ps, "Can't find section for field ", id);
 | 
						||
  return ps->exist_field(id);
 | 
						||
}
 | 
						||
 | 
						||
TForm_subsection* TForm::exist_field(char s, pagetype t, const char *section) const
 | 
						||
{
 | 
						||
  const TPrint_section* ps = ((TForm*)this)->exist(s, t);
 | 
						||
  CHECKS(ps, "Can't find section for field ", section);
 | 
						||
  return (TForm_subsection*)ps->exist_field(section);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TForm_item& TForm::find_field(char s, pagetype t, short id) const
 | 
						||
{                                    
 | 
						||
  const TPrint_section* ps = ((TForm*)this)->exist(s, t);
 | 
						||
  CHECKD(ps, "Can't find section for field ", id);
 | 
						||
  return ps->find_field(id);
 | 
						||
}
 | 
						||
 | 
						||
TForm_subsection& TForm::find_field(char s, pagetype t, const char *section) const
 | 
						||
{
 | 
						||
  const TPrint_section* ps = ((TForm*)this)->exist(s, t);
 | 
						||
  CHECKS(ps, "Can't find section for field ", section);
 | 
						||
  return (TForm_subsection&)ps->find_field(section);
 | 
						||
}
 | 
						||
 | 
						||
TPrint_section& TForm::section(char s, pagetype pos)
 | 
						||
{
 | 
						||
  TPrint_section* sec = exist(s, pos, TRUE);
 | 
						||
  return *sec;
 | 
						||
}
 | 
						||
 | 
						||
TPrint_section& TForm::section(char s, word pagenum)
 | 
						||
{
 | 
						||
  pagetype pt = odd_page;
 | 
						||
  if (pagenum == 0 && exist(s, last_page))
 | 
						||
    pt = last_page;
 | 
						||
  if (pagenum == 1 && exist(s, first_page))
 | 
						||
    pt = first_page;
 | 
						||
  if (pt == odd_page && (pagenum & 0x1) == 0 && exist(s, even_page))
 | 
						||
    pt = even_page;
 | 
						||
 | 
						||
  return section(s, pt);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Rilegge la sezione specificata
 | 
						||
//
 | 
						||
// @rdesc Ritorna se ce l'ha fatta
 | 
						||
bool TForm::reread(
 | 
						||
     char sec,    // @parm Sezione da rileggere
 | 
						||
     pagetype p,  // @parm Posizione della pagina
 | 
						||
     bool force)  // @parm Forza rilettura anche se nessun campo e' cambiato
 | 
						||
{
 | 
						||
  TPrint_section* s = exist(sec,p);
 | 
						||
  bool ok = force;
 | 
						||
  if (s != NULL)
 | 
						||
      for (word j = 0; j < s->fields(); j++)
 | 
						||
        ok |= s->field(j).dirty();
 | 
						||
  if (s != NULL && ok)
 | 
						||
  {
 | 
						||
    s->destroy_fields();  // Distrugge tutti gli items...
 | 
						||
    // ...si posiziona nel file sorgente alla sezione opportuna...
 | 
						||
    TFilename n(_name); n.ext("frm");
 | 
						||
    TScanner scanner(n);
 | 
						||
    bool ok = FALSE;
 | 
						||
    while (!ok)
 | 
						||
    {
 | 
						||
      while (TRUE)     // ...scans searching for a section...
 | 
						||
      {
 | 
						||
        const TString& key = scanner.popkey();
 | 
						||
        if (key == "SE" || key == "") // ..if section or end of file...
 | 
						||
          break;
 | 
						||
      }
 | 
						||
      const char   secr = scanner.popkey()[0];             // Section name (GRAPH, HEAD, BODY, FOOT)
 | 
						||
      if (secr=='\0') break;
 | 
						||
      const pagetype pr = char2page(scanner.popkey()[0]);  // Section type (odd, even, first, last)
 | 
						||
      if (secr==sec && pr==p) ok = TRUE;  // L'ha trovata...
 | 
						||
    }
 | 
						||
    // ...riesegue la parse della sezione leggendo dal file sorgente
 | 
						||
    if(ok && s->parse(scanner))
 | 
						||
    {
 | 
						||
     // Legge le modifiche su archivio e poi e' finita.
 | 
						||
      s->set_dirty(FALSE);
 | 
						||
      TLocalisamfile rprof(LF_RFORM);
 | 
						||
      const char sez[3] = {sec,p+'0','\0'};
 | 
						||
      rprof.zero();
 | 
						||
      rprof.put("TIPOPROF", _name);
 | 
						||
      rprof.put("CODPROF", _code);
 | 
						||
      rprof.put("SEZ", sez);
 | 
						||
      const TRectype filter(rprof.curr());
 | 
						||
 | 
						||
      for (int err = rprof.read(_isgteq); err == NOERR && rprof.curr() == filter; err = rprof.next())
 | 
						||
      {
 | 
						||
        const short id = rprof.get_int("ID");
 | 
						||
 | 
						||
        if (id == 0)
 | 
						||
        {
 | 
						||
          TPrint_section& se = section(sec, p);
 | 
						||
          se.read_from(rprof.curr());
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          TForm_item& item = find_field(sec, p, id);
 | 
						||
          item.read_from(rprof.curr());
 | 
						||
        }
 | 
						||
      }
 | 
						||
      set_compulsory_specials();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Cambia il formato di tutte le date nel form
 | 
						||
//
 | 
						||
// @rdesc Ritorna sempre TRUE
 | 
						||
bool TForm::ps_change_date_format(
 | 
						||
     TPrint_section& s,   // @parm Sezione nella quale modificare le date
 | 
						||
     const char* f)   // @parm Nuovo formato delle date
 | 
						||
 | 
						||
// @comm Ha le stesse funzioni di <mf TForm::change_date_format>, ma per <c TPrint_section>,
 | 
						||
//   all'uopo di chiamarla con ricorsiva insistenza
 | 
						||
 | 
						||
{
 | 
						||
  for (word i = 0; i < s.fields(); i++)
 | 
						||
  {
 | 
						||
    TForm_item& fi = s.field(i);
 | 
						||
    if (fi.is_section())
 | 
						||
    {
 | 
						||
      TPrint_section& ps = ((TForm_subsection&)fi).printsection();
 | 
						||
      ps_change_date_format(ps, f);
 | 
						||
    }
 | 
						||
    else if (strcmp(fi.class_name(), "DATA") == 0)
 | 
						||
    {
 | 
						||
      ((TForm_date&)fi).set_format(f);
 | 
						||
      if (!s.dirty()) s.set_dirty();
 | 
						||
      if (!fi.dirty()) fi.set_dirty();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Cambia il formato di tutti i numeri nel form
 | 
						||
//
 | 
						||
// @rdesc Ritorna sempre TRUE
 | 
						||
bool TForm::ps_change_number_format(
 | 
						||
     TPrint_section& s,   // @parm Sezione nella quale modificare i numeri
 | 
						||
     int w,       // @parm Dimensione massima del fomato numerico
 | 
						||
     int dec,       // @parm Numero di decimali
 | 
						||
     const char* p)   // @parm Picture del nuovo formato
 | 
						||
 | 
						||
// @comm Ha le stesse funzioni di <mf TForm::change_number_format>, ma per <c TPrint_section>,
 | 
						||
//   all'uopo di chiamarla con ricorsiva insistenza
 | 
						||
{
 | 
						||
  for (word i = 0; i < s.fields(); i++)
 | 
						||
  {
 | 
						||
    TForm_item& fi = s.field(i);
 | 
						||
    if (fi.is_section())
 | 
						||
    {
 | 
						||
      TPrint_section& ps = ((TForm_subsection&)fi).printsection();
 | 
						||
      ps_change_number_format(ps, w, dec, p);
 | 
						||
    }
 | 
						||
    else if (strcmp(fi.class_name(), "NUMERO") == 0)
 | 
						||
    {
 | 
						||
      TForm_number& fn = (TForm_number&)fi;
 | 
						||
      fn.width() = w;
 | 
						||
      fn.set_decimals(dec);
 | 
						||
      fn.set_picture(p);
 | 
						||
      if (!s.dirty()) s.set_dirty();
 | 
						||
      if (!fn.dirty()) fn.set_dirty();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TForm::change_date_format(const char* f)
 | 
						||
{
 | 
						||
  char secs[] = { "FHGB" };
 | 
						||
  char ptyp[] = { "LOEF" };
 | 
						||
  TPrint_section* ps;
 | 
						||
 | 
						||
  for (int sc = 0; sc < 4; sc++)
 | 
						||
    for (int pt = 0; pt < 4; pt++)
 | 
						||
       if ((ps = exist(secs[sc], char2page(ptyp[pt]), FALSE)) != NULL)
 | 
						||
         ps_change_date_format(*ps, f);
 | 
						||
}
 | 
						||
 | 
						||
void TForm::change_number_format(int w, int dec, const char* p)
 | 
						||
{
 | 
						||
  char secs[] = { "FHGB" };
 | 
						||
  char ptyp[] = { "LOEF" };
 | 
						||
  TPrint_section* ps;
 | 
						||
 | 
						||
  for (int sc = 0; sc < 4; sc++)
 | 
						||
    for (int pt = 0; pt < 4; pt++)
 | 
						||
       if ((ps = exist(secs[sc], char2page(ptyp[pt]), FALSE)) != NULL)
 | 
						||
         ps_change_number_format(*ps, w, dec, p);
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Effettua l'update della sezione grafica background
 | 
						||
//
 | 
						||
// @rdesc Ritorna la lunghezza della pagina da stampare
 | 
						||
word TForm::set_background(
 | 
						||
     word p,  // @parm Numero pagina
 | 
						||
     bool u)  // @parm Indica se aggiornare lo sfondo nella stampante corrente
 | 
						||
 | 
						||
// @xref <mf TForm::set_header> <mf TForm::set_body> <mf TForm::set_footer>
 | 
						||
{
 | 
						||
  word len = 0;
 | 
						||
 | 
						||
  if (u && _back.items())
 | 
						||
  {
 | 
						||
    TPrint_section& graph = section('G', p);
 | 
						||
    graph.update();
 | 
						||
    len = printer().formlen();
 | 
						||
  }
 | 
						||
 | 
						||
  return len;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Effettua l'update della sezione header
 | 
						||
//
 | 
						||
// @rdesc Ritorna l'altezza dell'header settato
 | 
						||
word TForm::set_header(
 | 
						||
     word p,  // @parm Numero pagina
 | 
						||
     bool u)  // @parm Indica se cambiare l'eventuale header o solo ritornare l'altezza
 | 
						||
 | 
						||
// @xref <mf TForm::set_background> <mf TForm::set_body> <mf TForm::set_footer>
 | 
						||
{
 | 
						||
  TPrinter& pr = printer();
 | 
						||
  pr.resetheader();
 | 
						||
 | 
						||
  TPrint_section& head = section('H', p);
 | 
						||
 | 
						||
  if (u) head.update();
 | 
						||
  else
 | 
						||
  {
 | 
						||
    head.reset();
 | 
						||
    pr.headerlen(head.height());
 | 
						||
  }
 | 
						||
 | 
						||
  for (word j = 0; j < head.height(); j++)
 | 
						||
    pr.setheaderline(j, head.row(j));
 | 
						||
 | 
						||
  return head.height();
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Effettua l'update della sezione body e la sua stampa su Printer
 | 
						||
//
 | 
						||
// @rdesc Ritorna l'altezza del body settato
 | 
						||
word TForm::set_body(
 | 
						||
     word p,  // @parm Numero pagina
 | 
						||
     bool u)  // @parm Indica se effettuare l'update (TRUE) o fare il reset (FALSE)
 | 
						||
 | 
						||
// @xref <mf TForm::set_background> <mf TForm::set_header> <mf TForm::set_footer>
 | 
						||
 | 
						||
{
 | 
						||
  TPrint_section& body = section('B', p);
 | 
						||
 | 
						||
  if (u) body.update_and_print(printmode_normal);
 | 
						||
  else body.reset();
 | 
						||
 | 
						||
  return body.height();
 | 
						||
}
 | 
						||
 | 
						||
TPrint_section * TPrint_section::section_above() const 
 | 
						||
{ 
 | 
						||
  if (_upsection)
 | 
						||
    return &_upsection->section();
 | 
						||
  return NULL;    
 | 
						||
}
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Compone e stampa tutte le righe della sezione (valida in caso di BODY)
 | 
						||
// ritorna se c'e' stata una valutazione
 | 
						||
bool TPrint_section::update_and_print(const sec_print_mode show_fields, bool new_page)
 | 
						||
{
 | 
						||
  bool ok=FALSE;
 | 
						||
  TPrinter& pr = printer();
 | 
						||
  word last_printed_row=0;
 | 
						||
 | 
						||
  reset();
 | 
						||
    
 | 
						||
  if (show_fields == printmode_normal
 | 
						||
      && pr.current_row() > pr.headersize()+1
 | 
						||
        && new_page)
 | 
						||
  {       
 | 
						||
      pr.formfeed();
 | 
						||
  }
 | 
						||
 | 
						||
  int last_hpos=0;
 | 
						||
  for (word i = 0; i < fields(); i++)
 | 
						||
  {
 | 
						||
    TForm_item& fi = field(i);
 | 
						||
    if (!fi.is_section())
 | 
						||
    {
 | 
						||
      // compose rows using "simple" fields
 | 
						||
      fi.update();
 | 
						||
    } 
 | 
						||
    else 
 | 
						||
    { 
 | 
						||
      last_hpos=min(word(fi.y()-1), height());
 | 
						||
      // found a subsection
 | 
						||
      TForm_subsection & ss=(TForm_subsection & )fi;
 | 
						||
 | 
						||
      last_printed_row=print_rows(show_fields,last_printed_row,last_hpos);
 | 
						||
 | 
						||
      // process subsection
 | 
						||
      if (ss.enabled())
 | 
						||
        ok |= ss.print_body(show_fields) ;
 | 
						||
    } 
 | 
						||
  } // ... loop for each field
 | 
						||
 | 
						||
  const word hgt = height();
 | 
						||
  
 | 
						||
  if (print_rows(show_fields,last_printed_row,hgt) > 0 && show_fields==printmode_normal)
 | 
						||
    ok = TRUE;
 | 
						||
  // print footers
 | 
						||
  if (subsection_above()!=NULL && !subsection_above()->is_title() && ok)
 | 
						||
    subsection_above()->print_qtitle();
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
word TPrint_section::print_rows(const sec_print_mode show_fields, word from, word to)
 | 
						||
{
 | 
						||
  TPrinter& pr = printer();
 | 
						||
    if (show_fields!=printmode_noprint && to>from)
 | 
						||
    {
 | 
						||
      // print preceeding rows:are all those rows which have Y coord <= than subsection's Y
 | 
						||
      if (subsection_above()!=NULL && !subsection_above()->is_title())
 | 
						||
      {
 | 
						||
        // find some to print: print titles.....
 | 
						||
        if (show_fields == printmode_normal)
 | 
						||
          subsection_above()->print_titles();
 | 
						||
      }
 | 
						||
      if (pr.current_row() > pr.headersize()+1)
 | 
						||
        if ((to-from+1) > pr.rows_left()  && show_fields==printmode_normal )
 | 
						||
          pr.formfeed();
 | 
						||
      for (word j = from;  j < to ;j++)
 | 
						||
        switch (show_fields) 
 | 
						||
        {
 | 
						||
          case printmode_normal:
 | 
						||
            pr.print(row(j)); break; // print to printer
 | 
						||
          default:
 | 
						||
            _titlerows.add(row(j),j); break; // print to buffer
 | 
						||
        }
 | 
						||
      return to;
 | 
						||
    }
 | 
						||
    return from;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Effettua l'update della sezione footer
 | 
						||
//
 | 
						||
// @rdesc Ritorna l'altezza del footer settato
 | 
						||
word TForm::set_footer(
 | 
						||
     word p,  // @parm Numero pagina
 | 
						||
     bool u)  // @parm Indica se cambiare l'eventuale footer corrente!!!
 | 
						||
 | 
						||
// @xref <mf TForm::set_background> <mf TForm::set_header> <mf TForm::set_body>
 | 
						||
 | 
						||
{
 | 
						||
  TPrinter& pr = printer();
 | 
						||
  pr.resetfooter();
 | 
						||
 | 
						||
  TPrint_section& foot = section('F', p);
 | 
						||
 | 
						||
  if (u) foot.update();
 | 
						||
  else
 | 
						||
  {
 | 
						||
    foot.reset();
 | 
						||
    pr.footerlen(foot.height());
 | 
						||
  }
 | 
						||
 | 
						||
  for (word j = 0; j < foot.height(); j++)
 | 
						||
    pr.setfooterline(j, foot.row(j));
 | 
						||
 | 
						||
  return foot.height();
 | 
						||
}
 | 
						||
 | 
						||
void TForm::header_handler(TPrinter& p)
 | 
						||
{              
 | 
						||
  TForm& f = *_cur_form;
 | 
						||
  if (f.firstpage_is_lastpage()) 
 | 
						||
  {
 | 
						||
    f.set_background(1, TRUE);
 | 
						||
    f.set_header(1, TRUE);
 | 
						||
    f.set_footer(0, FALSE);
 | 
						||
  } 
 | 
						||
  else 
 | 
						||
  {
 | 
						||
    const word page = f.page(p);
 | 
						||
    f.set_background(page, TRUE);
 | 
						||
    f.set_header(page, TRUE);
 | 
						||
    f.set_footer(page, FALSE);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TForm::footer_handler(TPrinter& p)
 | 
						||
{
 | 
						||
  TForm& f = *_cur_form;
 | 
						||
  if (f.firstpage_is_lastpage()) 
 | 
						||
  {
 | 
						||
    f.set_footer(0, TRUE);
 | 
						||
  } 
 | 
						||
  else 
 | 
						||
  {
 | 
						||
    const word currp = f.page(p);
 | 
						||
    f.set_footer(currp, TRUE);
 | 
						||
    if (currp)
 | 
						||
      f.set_header(f.next_page(p), FALSE);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Ritorna se la prima pagina coincide conl'ultima
 | 
						||
bool TForm::firstpage_is_lastpage() const
 | 
						||
{
 | 
						||
  return _first_eq_last;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Ritorna il numero di pagina correntemente in stampa
 | 
						||
//
 | 
						||
// @rdesc Se <md _TForm::lastpage> e' TRUE (sta stampando l'ultima pagina)
 | 
						||
//    ritorna 0, altrimenti ritorna il numero della pagina corrente da stampare
 | 
						||
//    (chiam <mf TPrinter::getcurrentepage>).
 | 
						||
word TForm::page(
 | 
						||
     const TPrinter& p) const // @parm Operazione corrente di stampa
 | 
						||
{
 | 
						||
  return _lastpage || fixed_pages() && p.getcurrentpage()==_npages ? 0 : p.getcurrentpage();
 | 
						||
}
 | 
						||
 | 
						||
word TForm::next_page(
 | 
						||
     const TPrinter& p) const // @parm Operazione corrente di stampa
 | 
						||
{
 | 
						||
  return _lastpage || fixed_pages() && p.getcurrentpage()+1==_npages ? 0 : p.getcurrentpage()+1;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Effettua il posizionamento manuale del modulo
 | 
						||
void TForm::arrange_form()
 | 
						||
 | 
						||
// @comm Nota: siccome si scrive direttamente sulla porta, sarebbe necessario
 | 
						||
//   mandare una stringa di reset alla stampante, o per lo meno far si' che
 | 
						||
//   ogni volta che si fa il posizionamento il font col quale scrive sia sempre
 | 
						||
//   lo stesso. Tutto cio' non e' possibile con la generica solo testo, o meglio
 | 
						||
//   ad ogni stampa col posizionamento e' necessario che la stampante sia resettata.
 | 
						||
//   <nl>Riassumendo, come regola generale, i posizionamenti devono essere fatti con il
 | 
						||
//   font di default della stampante (tipicamente 10 cpi). Accade pero' (con la generica
 | 
						||
//   solo testo) che rimanga settato l'ultimo font, di conseguenza quando si effettua una
 | 
						||
//   seconda stampa con posizionamento, stampera' tali caratteri in 17"! Per questo
 | 
						||
//   motivo e' necessario settare a 17 cpi, almeno la prima volta, la stampante!.
 | 
						||
//   <nl>Quindi, per ovviare a tutto cio, visto che <mf TForm::arange_form> ha senso solo su
 | 
						||
//   stampanti ad aghi, che le stampanti ad aghi possono andare in emulazione EPSON o IBM,
 | 
						||
//   che il codice per settare il font draft 17cpi e' lo stesso sia per EPSON che IBM
 | 
						||
//   CHR(15), allora prima del posizionamento scrivo il chr(15) sulla stampante!
 | 
						||
 | 
						||
{
 | 
						||
/*
 | 
						||
  int i, x;
 | 
						||
  TString str_pos;
 | 
						||
  TMask m("ba2100c");
 | 
						||
 | 
						||
  // _ipy viene assunto uguale per entrambi i posizionamneti
 | 
						||
  str_pos = "\017";  // Questo e' 15 in ottale...
 | 
						||
  for (i=1; i < _ipy; i++) str_pos << "\n";
 | 
						||
  os_open_spool_row(printer().printername());
 | 
						||
  os_spool_row(str_pos);
 | 
						||
  os_close_spool_row();
 | 
						||
  str_pos = "";  //Azzera la stringa di posizionamento
 | 
						||
  for (i=1; i < _ipx; i++) str_pos << " "; //Aggiunge gli spazi necessari...
 | 
						||
  if (_ipx > 0)
 | 
						||
    str_pos << _char_to_pos;   // aggiunge il primo carattere di posizionamento...
 | 
						||
  x = _fpx - _ipx ;                 // calcola quanti spazi aggiungere...
 | 
						||
  for (i=1; i < x; i++) str_pos << " ";
 | 
						||
  if (_fpx > 0)
 | 
						||
    str_pos << _char_to_pos;  // aggiunge il secondo carattere di posizionamento
 | 
						||
  str_pos << '\r';
 | 
						||
//  TString bspc; bspc.fill('\b',str_pos.len()); // Questi servono per tornare indietro...
 | 
						||
  do
 | 
						||
  {
 | 
						||
    os_open_spool_row(printer().printername());
 | 
						||
    os_spool_row(str_pos);
 | 
						||
    os_close_spool_row();
 | 
						||
  } while (m.run() == K_ESC);     // cicla sulla stampa posizionamento...
 | 
						||
  printer().set_offset(-(_ipy-1), printer().get_column_offset());
 | 
						||
*/
 | 
						||
}
 | 
						||
long TForm::records() const
 | 
						||
{
 | 
						||
  TCursor* c = cursor();
 | 
						||
  const long r = c != NULL ? c->items() : 0;
 | 
						||
  return r;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Genera automaticamente la sezione grafica con colonne fincate
 | 
						||
//
 | 
						||
// @rdesc Ritorna FALSE se non c'e' il body per quella pagina
 | 
						||
bool TForm::genera_fincatura(
 | 
						||
     pagetype p,  // @parm Posizione della pagina (vedi <t pagetype>)
 | 
						||
     int y1,    // @parm Prima y per le righe verticali
 | 
						||
     int y2,    // @parm Ultima y per le righe verticali
 | 
						||
     const int* rows) // @parm Array di posizioni riga con 0 per finire
 | 
						||
 | 
						||
 | 
						||
{
 | 
						||
  TPrint_section* body = exist('B', p);
 | 
						||
  if (body == NULL) return FALSE;
 | 
						||
 | 
						||
  body->reset_tabs();
 | 
						||
 | 
						||
  bool istemp = exist('G', p) == NULL;
 | 
						||
 | 
						||
  TGraphic_section* grs = (TGraphic_section*)exist('G', p, TRUE);
 | 
						||
  grs->temp() = istemp;
 | 
						||
 | 
						||
  int j = 0, start = 999, end = 0, wlast = 0;
 | 
						||
  int cols[MAXCOLUMNS];
 | 
						||
 | 
						||
  for (word k = grs->fields(); k > 0; k--)
 | 
						||
    if (grs->field(k-1).temp())
 | 
						||
      grs->destroy_field(k-1);
 | 
						||
 | 
						||
  int i;
 | 
						||
  for (i = 0; i < (int)body->fields(); i++)
 | 
						||
  {
 | 
						||
    TForm_item& f = body->field(i);
 | 
						||
    if (!f.shown() || f.is_section()) 
 | 
						||
      continue;
 | 
						||
 | 
						||
    int x = f.x();
 | 
						||
 | 
						||
    if (x < start) start = x;
 | 
						||
    if (x > end)   { end = x; wlast = f.width(); }
 | 
						||
    cols[j++] = f.finkl() ? -x : x;
 | 
						||
  }
 | 
						||
 | 
						||
  // inner lines
 | 
						||
  for (i = 0; i < j; i++)
 | 
						||
  {
 | 
						||
    if (cols[i] != start && cols[i] > 0)
 | 
						||
    {
 | 
						||
      TForm_line* l = new TForm_line(grs);
 | 
						||
      l->set_x(cols[i]-1);
 | 
						||
      l->y()      = (word)y1;
 | 
						||
      l->id()     = -1;
 | 
						||
      l->width()  = 1;
 | 
						||
      l->height() = (int)(y2 - y1 + 1);
 | 
						||
      l->set("@R");
 | 
						||
      l->temp() = TRUE;
 | 
						||
      grs->add_field(l);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  // box around
 | 
						||
  if (start != 999 && end != 0)
 | 
						||
  {
 | 
						||
    TForm_box* l = new TForm_box(grs);
 | 
						||
    l->set_x(start-1);
 | 
						||
    l->y()      = (word)y1;
 | 
						||
    l->id()     = -1;
 | 
						||
    l->width()  = (int)(end + wlast - start + 2);
 | 
						||
    l->height() = (int)(y2 - y1 + 1);
 | 
						||
    l->set("@B@R");
 | 
						||
    l->temp() = TRUE;
 | 
						||
    grs->add_field(l);
 | 
						||
  }
 | 
						||
 | 
						||
  // horizontal lines
 | 
						||
  if (start != 999 && end != 0)
 | 
						||
    for (i = 0; rows[i]; i++)
 | 
						||
    {
 | 
						||
      TForm_line* l = new TForm_line(grs);
 | 
						||
      l->set_x(start-1);
 | 
						||
      l->y()      = (word)rows[i];
 | 
						||
      l->id()     = -1;
 | 
						||
      l->width()  = (int)(end + wlast - start + 2);
 | 
						||
      l->height() = 1;
 | 
						||
      l->set("@R");
 | 
						||
      l->temp() = TRUE;
 | 
						||
      grs->add_field(l);
 | 
						||
    }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Genera le righe di intestazione colonna alla riga indicata, vale per COLUMNWISE
 | 
						||
//
 | 
						||
// @rdesc Ritorna FALSE se non esiste body (o non e' COLUMNWISE) o se non esiste l'header
 | 
						||
bool TForm::genera_intestazioni(
 | 
						||
     pagetype p,  // @parm Posizione della pagina (vedi <t pagetype>)
 | 
						||
     short y)     // @parm Riga dell'header in cui vanno inserite
 | 
						||
 | 
						||
// @comm I form_items di intestazione vengono aggiunti alla sezione header di tipo <p p> con ID -1
 | 
						||
 | 
						||
{
 | 
						||
  TPrint_section* body = exist('B', p);
 | 
						||
  if (body == NULL || !body->columnwise()) 
 | 
						||
    return FALSE;
 | 
						||
 | 
						||
  TPrint_section* header = exist('H', p);
 | 
						||
  if (header == NULL) 
 | 
						||
    return FALSE;
 | 
						||
  body->reset_tabs();
 | 
						||
  
 | 
						||
  // Elimina eventuali campi temporanei precedenti
 | 
						||
  for (int k = header->fields()-1; k >= 0; k--)
 | 
						||
    if (header->field(k).temp())
 | 
						||
      header->destroy_field(k);
 | 
						||
 | 
						||
  const word items = body->fields();
 | 
						||
  TForm_string* s;
 | 
						||
  for (word j=0;j<items;j++)
 | 
						||
  {// Scans all body items to print, and append header items...
 | 
						||
    TForm_item& fi = body->field(j);
 | 
						||
    if (!fi.shown() || fi.is_section())
 | 
						||
      continue;
 | 
						||
    char align='\0';
 | 
						||
    if (fi.col_head()[0]=='@')
 | 
						||
    {
 | 
						||
      switch (fi.col_head()[1])
 | 
						||
      {
 | 
						||
        case 'C': // centered
 | 
						||
        case 'c':
 | 
						||
          align='c';
 | 
						||
          break;
 | 
						||
        case 'R': // right just
 | 
						||
        case 'r':
 | 
						||
          align='r';
 | 
						||
          break;
 | 
						||
        default: // left just
 | 
						||
          align='l';
 | 
						||
          break;
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    // Paragraph_string has as many items as lines needed...
 | 
						||
    TParagraph_string prompts(fi.col_head().mid(align ? 2:0),fi.width());
 | 
						||
    TString p;
 | 
						||
    for (int c=0;c < prompts.items(); c++)
 | 
						||
    {
 | 
						||
      p = prompts.get(c);
 | 
						||
      switch (align)
 | 
						||
      {
 | 
						||
      case 'c':
 | 
						||
        p.center_just(fi.width());
 | 
						||
        break;
 | 
						||
      case 'r':
 | 
						||
        p.right_just(fi.width());
 | 
						||
        break; 
 | 
						||
      default:
 | 
						||
        break;  
 | 
						||
      }
 | 
						||
      s = new TForm_string(header);
 | 
						||
      s->id() = -1;
 | 
						||
      s->set_x(fi.x());
 | 
						||
      s->y() = y+c;
 | 
						||
      s->set_prompt(p);
 | 
						||
      s->temp() = TRUE;
 | 
						||
      header->add_field(s);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
/*
 | 
						||
void TForm::remove_temp_items(char sec, pagetype p)
 | 
						||
{
 | 
						||
  TPrint_section* s = exist(sec,p);
 | 
						||
  if (s!=NULL)
 | 
						||
  {
 | 
						||
    const word items = s->fields();
 | 
						||
    for (word j=0;j<items; j++)
 | 
						||
    {
 | 
						||
      if  (s->field(j).temp())
 | 
						||
        s->destroy_field(j,FALSE);
 | 
						||
    }
 | 
						||
    s->field_array().pack();
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TForm::put_examples(char sez, pagetype p)
 | 
						||
{
 | 
						||
  TPrint_section* s = exist(sez,p);
 | 
						||
  if (s!=NULL)
 | 
						||
  {
 | 
						||
    const word items = s->fields();
 | 
						||
    for (word i=0;i<items;i++)
 | 
						||
    {
 | 
						||
      TForm_item& fi = s->field(i);
 | 
						||
      if (fi.fields()!=0) continue;
 | 
						||
      if (fi.memo())
 | 
						||
        fi.set(fi.memo_info());
 | 
						||
      else
 | 
						||
      if (fi.prompt().empty())
 | 
						||
      {
 | 
						||
        if (fi.class_name() == "DATA")
 | 
						||
        {
 | 
						||
          const TDate d(TODAY);
 | 
						||
          fi.set(d);
 | 
						||
        }
 | 
						||
        else
 | 
						||
          if (fi.class_name() == "NUMERO")
 | 
						||
          {
 | 
						||
            fi.set_prompt(fi.example());
 | 
						||
            fi.temp() = TRUE;
 | 
						||
          }
 | 
						||
          else
 | 
						||
            fi.set(fi.key());
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TForm::remove_examples(char sez, pagetype p)
 | 
						||
{
 | 
						||
  TPrint_section* s = exist(sez,p);
 | 
						||
  if (s!=NULL)
 | 
						||
  {
 | 
						||
    const word items = s->fields();
 | 
						||
    for (word i=0;i<items;i++)
 | 
						||
    {
 | 
						||
      TForm_item& fi = s->field(i);
 | 
						||
      if (fi.fields()!=0) continue;
 | 
						||
      if (fi.memo())
 | 
						||
        fi.set("");
 | 
						||
      else
 | 
						||
        if (fi.class_name() == "NUMERO" && fi.temp())
 | 
						||
        {
 | 
						||
          fi.set_prompt("");
 | 
						||
          fi.temp() = FALSE;
 | 
						||
        }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
*/
 | 
						||
 | 
						||
bool TForm::has_subsections()
 | 
						||
{
 | 
						||
  const TPrint_section&  b = section('B', odd_page);
 | 
						||
  return b.subsections() > 0 ;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Stampa gli items da <p form> a <p to>
 | 
						||
//
 | 
						||
// @rdesc Ritorna se ha effettuato correttamente la stampa
 | 
						||
bool TForm::print(
 | 
						||
     long from,   // @parm Primo item da stampare (default 0l)
 | 
						||
     long to)   // @parm Ultimo da stampare (se <lt>0 stampa fino alla fine del file, default -1l)
 | 
						||
 | 
						||
// @comm Se i parametri di posizionamento sono settati e cosi' pure gli offset genera un <f error_box>.
 | 
						||
{
 | 
						||
  _cur_form = this;
 | 
						||
 | 
						||
  if ((_char_to_pos != '\0' || ((_ipx +_ipy+_fpx) != 0)) &&  // Se i parametri di posizionamento sono settati e
 | 
						||
      (_x != 0 || _y != 0))                                      // cosi' pure gli offset genera un errore.
 | 
						||
  {
 | 
						||
    error_box(TR("Non e' possibile settare contemporaneamente gli offset"
 | 
						||
              " e i parametri di posizionamento del modulo."));
 | 
						||
    return FALSE;
 | 
						||
  }
 | 
						||
  TPrinter& pr = printer();
 | 
						||
  if (_frompage) pr.set_from_page(_frompage);
 | 
						||
  if (_topage) pr.set_to_page(_topage);
 | 
						||
 | 
						||
  if (_char_to_pos != '\0' || (_ipx +_ipy+_fpx) != 0)   // Effettua il posizionamento del form...
 | 
						||
  {
 | 
						||
    if (_arrange && pr.printtype() == winprinter)
 | 
						||
      arrange_form();
 | 
						||
  }
 | 
						||
  else
 | 
						||
    pr.set_offset(_y,_x);
 | 
						||
 | 
						||
  pr.setheaderhandler(header_handler); // Setta handlers
 | 
						||
  pr.setfooterhandler(footer_handler);
 | 
						||
  if (!pr.is_generic())
 | 
						||
  {
 | 
						||
    for (pagetype t = odd_page; t <= last_page; t = pagetype(t+1))
 | 
						||
    {
 | 
						||
      if (height(t)> (word)pr.formlen())
 | 
						||
      {
 | 
						||
        TString s(TR("La lunghezza totale della sezione "));
 | 
						||
        switch ( t )
 | 
						||
        {
 | 
						||
        case odd_page:
 | 
						||
          s << TR("standard"); break;
 | 
						||
        case even_page:
 | 
						||
          s << TR("pagine pari"); break;
 | 
						||
        case first_page:
 | 
						||
          s << TR("prima pagina"); break;
 | 
						||
        case last_page:
 | 
						||
          s << TR("ultima pagina"); break;
 | 
						||
        default:
 | 
						||
          break;
 | 
						||
        }
 | 
						||
        s << TR(" eccede la lunghezza reale del foglio.");
 | 
						||
        message_box(s);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    pr.formlen(height());
 | 
						||
  }
 | 
						||
  if (_fontsize != 0)
 | 
						||
    pr.set_char_size(_fontsize);                     // Set font name and size
 | 
						||
  if (_fontname.not_empty())
 | 
						||
    pr.set_fontname(_fontname);                      // according to current form
 | 
						||
  const bool was_open = pr.isopen();
 | 
						||
 | 
						||
  set_last_page(FALSE);                            // non e' l'ultima pagina
 | 
						||
 | 
						||
  set_background(1, TRUE);
 | 
						||
 | 
						||
  if (!was_open && !pr.open())
 | 
						||
    return FALSE;
 | 
						||
  do_events();
 | 
						||
 | 
						||
  long lastrec= records()-1;
 | 
						||
 | 
						||
  if (to < 0) to = lastrec;
 | 
						||
 | 
						||
  // controlla i casi di stampa
 | 
						||
  _first_eq_last=FALSE;
 | 
						||
  if (!fixed_pages() && !has_subsections() && set_body(1,FALSE) * word(to-from+1) <= pr.formlen()- set_header(1,FALSE) - set_footer(0,FALSE))
 | 
						||
    // tutta la stampa sta in una pagina
 | 
						||
    _first_eq_last=TRUE;
 | 
						||
//  if (to == lastrec) to--; // l'ultima pagina <20> gestita come caso particolare
 | 
						||
 | 
						||
  bool ok = TRUE;
 | 
						||
  TCursor* cur = cursor();
 | 
						||
 | 
						||
  for (long i = from; i <= to && ok;)
 | 
						||
  {
 | 
						||
    if (pr.frozen())
 | 
						||
      break;
 | 
						||
      
 | 
						||
    if (from < 0) 
 | 
						||
      to = from;
 | 
						||
    else if (cur != NULL)
 | 
						||
    { 
 | 
						||
      *cur = i;
 | 
						||
      match_result();
 | 
						||
    }  
 | 
						||
          
 | 
						||
    if (pr.current_row() > pr.headersize()+1)
 | 
						||
    {
 | 
						||
      const word h = set_body(page(pr), FALSE);
 | 
						||
      if (h > pr.rows_left()) 
 | 
						||
      {
 | 
						||
        pr.formfeed();
 | 
						||
        // quanto resta da stampare sta nell'ultima  pagina
 | 
						||
        if (!fixed_pages() && !has_subsections() && set_body(0,FALSE) * word(to-i+1) <= pr.formlen()- set_header(1,FALSE) - set_footer(0,FALSE))
 | 
						||
        {
 | 
						||
          while (i <= to && from >= 0) // stampa l'ultima pagina
 | 
						||
          {
 | 
						||
            set_last_page(TRUE);
 | 
						||
            set_background(0, TRUE);
 | 
						||
            set_header(0, TRUE);
 | 
						||
            if (cur != NULL)
 | 
						||
            {
 | 
						||
              *cur = i;
 | 
						||
              set_body(0, TRUE);
 | 
						||
            }     
 | 
						||
            i++;
 | 
						||
          }
 | 
						||
          break;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    
 | 
						||
    set_body(page(pr), TRUE);
 | 
						||
    if (cur != NULL) 
 | 
						||
    {
 | 
						||
      if (next_match_done()) 
 | 
						||
        i=cur->pos();
 | 
						||
      else  
 | 
						||
        i++;
 | 
						||
    }
 | 
						||
    else
 | 
						||
      i++;
 | 
						||
  } // fine ciclo di stampa
 | 
						||
 | 
						||
  while (fixed_pages() && page(pr) % _npages !=0)
 | 
						||
  {
 | 
						||
    pr.formfeed();
 | 
						||
/*    
 | 
						||
    static TPrintrow empty_line;
 | 
						||
    pr.print(empty_line);
 | 
						||
*/
 | 
						||
    pr.skip(1);  // No static when possible
 | 
						||
  }      
 | 
						||
  
 | 
						||
  if (from >= 0)
 | 
						||
  {
 | 
						||
    if (!_lastpage)
 | 
						||
    {                                 
 | 
						||
      TPrint_section* last_foot = exist('F', last_page, FALSE); 
 | 
						||
      if (last_foot != NULL)
 | 
						||
      {
 | 
						||
        const word lfh = last_foot->height();
 | 
						||
        const word left = pr.rows_left() + pr.footersize();
 | 
						||
        if (lfh > left) // Se l'ultimo footer e' troppo grande ...
 | 
						||
          pr.formfeed(); // Stampa il footer normale   
 | 
						||
        pr.footerlen(lfh); // Fondamentale!
 | 
						||
      }
 | 
						||
      set_last_page(TRUE);
 | 
						||
    }
 | 
						||
    pr.formfeed();
 | 
						||
  }
 | 
						||
  if (!was_open)
 | 
						||
    pr.close();
 | 
						||
 | 
						||
  pr.setheaderhandler(NULL);
 | 
						||
  pr.setfooterhandler(NULL);
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
/*bool TForm::print(
 | 
						||
     long from,   // @parm Primo item da stampare (default 0l)
 | 
						||
     long to)   // @parm Ultimo da stampare (se <lt>0 stampa fino alla fine del file, default -1l)
 | 
						||
 | 
						||
// @comm Se i parametri di posizionamento sono settati e cosi' pure gli offset genera un <f error_box>.
 | 
						||
{
 | 
						||
  _cur_form = this;
 | 
						||
 | 
						||
  if ((_char_to_pos != '\0' || ((_ipx +_ipy+_fpx) != 0)) &&  // Se i parametri di posizionamento sono settati e
 | 
						||
      (_x != 0 || _y != 0))                                      // cosi' pure gli offset genera un errore.
 | 
						||
  {
 | 
						||
    error_box("Non e' possibile settare contemporaneamente gli offset"
 | 
						||
              " e i parametri di posizionamento del modulo.");
 | 
						||
    return FALSE;
 | 
						||
  }
 | 
						||
  TPrinter& pr = printer();
 | 
						||
  if (_frompage) pr.set_from_page(_frompage);
 | 
						||
  if (_topage) pr.set_to_page(_topage);
 | 
						||
 | 
						||
  if (_char_to_pos != '\0' || (_ipx +_ipy+_fpx) != 0)   // Effettua il posizionamento del form...
 | 
						||
  {
 | 
						||
    if (_arrange && pr.printtype() == winprinter)
 | 
						||
      arrange_form();
 | 
						||
  }
 | 
						||
  else
 | 
						||
    pr.set_offset(_y,_x);
 | 
						||
 | 
						||
  pr.setheaderhandler(header_handler); // Setta handlers
 | 
						||
  pr.setfooterhandler(footer_handler);
 | 
						||
  if (!pr.is_generic())
 | 
						||
  {
 | 
						||
    for (pagetype t = odd_page; t <= last_page; t = pagetype(t+1))
 | 
						||
    {
 | 
						||
      if (height(t)> (word)pr.formlen())
 | 
						||
      {
 | 
						||
        TString s("La lunghezza totale della sezione ");
 | 
						||
        switch ( t )
 | 
						||
        {
 | 
						||
        case odd_page:
 | 
						||
          s << "standard"; break;
 | 
						||
        case even_page:
 | 
						||
          s << "pagine pari"; break;
 | 
						||
        case first_page:
 | 
						||
          s << "prima pagina"; break;
 | 
						||
        case last_page:
 | 
						||
          s << "ultima pagina"; break;
 | 
						||
        default:
 | 
						||
          break;
 | 
						||
        }
 | 
						||
        s << " eccede la lunghezza reale del foglio.";
 | 
						||
        message_box(s);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    pr.formlen(height());
 | 
						||
  }
 | 
						||
  pr.set_char_size(_fontsize);                     // Set font name and size
 | 
						||
  pr.set_fontname(_fontname);                      // according to current form
 | 
						||
  const bool was_open = pr.isopen();
 | 
						||
 | 
						||
  set_last_page(FALSE);                            // non e' l'ultima pagina
 | 
						||
 | 
						||
  set_background(1, TRUE);
 | 
						||
 | 
						||
  if (!was_open && !pr.open())
 | 
						||
    return FALSE;
 | 
						||
  do_events();
 | 
						||
 | 
						||
  long lastrec= records()-1;
 | 
						||
 | 
						||
  if (to < 0) to = lastrec;
 | 
						||
  if (to == lastrec) to--; // l'ultima pagina <20> gestita come caso particolare
 | 
						||
 | 
						||
  bool ok = TRUE;
 | 
						||
 | 
						||
  for (long i = from; i <= to && ok;)
 | 
						||
  {
 | 
						||
    if (from < 0) to = from;
 | 
						||
    else if (cursor()) 
 | 
						||
        *cursor()=i;
 | 
						||
    match_result();
 | 
						||
        
 | 
						||
    if (pr.current_row() > pr.headersize()+1)
 | 
						||
    {
 | 
						||
      const word h = set_body(page(pr), FALSE);
 | 
						||
      if (h > pr.rows_left()) {
 | 
						||
        pr.formfeed();
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    set_body(page(pr), TRUE);
 | 
						||
    if (cursor()) {
 | 
						||
      if (next_match_done()) 
 | 
						||
        i=cursor()->pos();
 | 
						||
      else  
 | 
						||
        i++;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (i >= lastrec && from >= 0) // stampa l'ultima pagina (garantisce il footer diverso)
 | 
						||
  {
 | 
						||
    set_last_page(TRUE);
 | 
						||
    set_background(0, TRUE);
 | 
						||
    set_header(0, TRUE);
 | 
						||
    if (cursor() && i == lastrec) {
 | 
						||
        *cursor() = i;
 | 
						||
        set_body(0, TRUE);
 | 
						||
    }     
 | 
						||
    pr.formfeed();
 | 
						||
  }
 | 
						||
 | 
						||
  if (!was_open)
 | 
						||
    pr.close();
 | 
						||
 | 
						||
  pr.setheaderhandler(NULL);
 | 
						||
  pr.setfooterhandler(NULL);
 | 
						||
 | 
						||
  return ok;
 | 
						||
} */
 | 
						||
 | 
						||
 | 
						||
void TForm::print_section(ostream& out, char s) const
 | 
						||
{
 | 
						||
  for (pagetype t = odd_page; t <= last_page; t = pagetype(t+1))
 | 
						||
  {
 | 
						||
    const TPrint_section* sec = ((TForm*)this)->exist(s, t);
 | 
						||
    if (sec && sec->ok() && !sec->temp())
 | 
						||
    {
 | 
						||
      const char* name;
 | 
						||
      switch (s)
 | 
						||
      {
 | 
						||
      case 'F':
 | 
						||
        name = "FOOTER"; break;
 | 
						||
      case 'G':
 | 
						||
        name = "GRAPHICS"; break;
 | 
						||
      case 'H':
 | 
						||
        name = "HEADER"; break;
 | 
						||
        default :
 | 
						||
        name = "BODY"; break;
 | 
						||
      }
 | 
						||
      out << "SECTION " << name;
 | 
						||
      out << *sec;
 | 
						||
      out << "END\n" << endl;
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// funzione di validazione delle macro
 | 
						||
bool TForm::validate(TForm_item &cf, TToken_string &s)
 | 
						||
{ 
 | 
						||
  const TString code(s.get(0)); // prende il primo parametro, il codice del messaggio
 | 
						||
  TString valore;
 | 
						||
 | 
						||
  if (code=="_ISAMREAD")
 | 
						||
  {
 | 
						||
    // lettura generica di un file del database
 | 
						||
    // sintassi: _ISAMREAD,<file>,<espressione input>[!<espressione input>!...],{<campo file>|<espressione output>[!<espressione output>!...]}
 | 
						||
    // dove: <file> <20> il numero logico del file o il nome della tabella
 | 
						||
    //       <espressione input> <20> un'espressione del tipo <campo file>=<espressione campi form>
 | 
						||
    //       <espressione campi form> <20> un'espressione di costanti numeriche, stringhe e valori di campi della form (indicati con il loro numero preceduto da #)
 | 
						||
    //       <espressione output> <20> un'espressione del tipo <campo form o gruppo>=<campo file> (se <20> un gruppo deve essere seguito da @) oppure solo <campo file> (il campo della form <20> quello corrente)
 | 
						||
    int i, j, poseq, posrv = 0, itms;
 | 
						||
    pagetype pt;
 | 
						||
    char sec;
 | 
						||
    TLocalisamfile *file;
 | 
						||
    const TString f_code(s.get()); // prende il codice del file da leggere
 | 
						||
    if (atoi(f_code) != 0) 
 | 
						||
      file= new TLocalisamfile(atoi(f_code)); // se il codice <20> numerico allora <20> un file
 | 
						||
    else 
 | 
						||
      file= new TTable(f_code); // altrimenti <20> una tabella
 | 
						||
    file->zero(); // vuota il record corrente del file
 | 
						||
    TToken_string in(s.get(), '!');
 | 
						||
    for (i=0; i<in.items(); i++)
 | 
						||
    { // scansione sugli elementi dell'input
 | 
						||
      const TString& curr = in.get(i);
 | 
						||
      poseq= curr.find('='); // divide la stringa corrente in lvalue e rvalue
 | 
						||
      posrv = poseq+1;
 | 
						||
      if (curr[posrv] == '=')
 | 
						||
        posrv++;
 | 
						||
      
 | 
						||
      const TString16 fld(curr.left(poseq)); // preleva il nome del campo del file alla sinistra dell'uguale
 | 
						||
      TExpression rval(curr.mid(posrv), _strexpr); // preleva l'espressione di assegnamento alla destra dell'uguale
 | 
						||
      TString16 var;
 | 
						||
      for (j=0; j<rval.numvar(); j++)
 | 
						||
      { // scansione delle variabili dell'espressione di rvalue
 | 
						||
        var = rval.varname(j);
 | 
						||
        const bool is_form_field = var[0]=='#' ||                             // #3  
 | 
						||
                                   (isdigit(var[0]) && var.find("->")<0) ||   // 3
 | 
						||
                                   (isalpha(var[0]) && var.find("->")>0);     // BO->3
 | 
						||
        if (is_form_field) // E' un campo del form
 | 
						||
        {
 | 
						||
          if (var[0] == '#')
 | 
						||
            var.ltrim(1);
 | 
						||
          TForm_item &fi= cf.find_field(var);
 | 
						||
          rval.setvar(j, fi.get()); // il valore corrente del campo viene settato nell'espressione
 | 
						||
        }
 | 
						||
        else // E' un campo della relazione
 | 
						||
        {
 | 
						||
          TFieldref fr(var, 0);                 // CODCF oppure 33->CODCF
 | 
						||
          rval.setvar(j, fr.read(*relation())); // il valore corrente del campo viene settato nell'espressione
 | 
						||
        }
 | 
						||
      }
 | 
						||
      file->put(fld, rval.as_string()); // scrive il risultato dell'espressione nel campo del file
 | 
						||
    }
 | 
						||
    if (file->read()== NOERR)
 | 
						||
    { // tenta una lettura del file
 | 
						||
      TToken_string out(s.get(), '!');
 | 
						||
      for (i=0; i<out.items(); i++)
 | 
						||
      { // scansione sugli elementi dell'output
 | 
						||
        TString curr(out.get(i));
 | 
						||
        poseq= curr.find("=="); // divide la stringa corrente in lvalue e rvalue
 | 
						||
        if (poseq== -1)
 | 
						||
        {
 | 
						||
          poseq= curr.find('=');
 | 
						||
          if (poseq != -1) posrv= poseq+1;
 | 
						||
        }
 | 
						||
        else
 | 
						||
          posrv= poseq+2;
 | 
						||
        if (poseq== -1)
 | 
						||
        {
 | 
						||
          const TString &dat= file->get(curr); // preleva il nome del campo del file e lo legge dal record
 | 
						||
          cf.set(dat);
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          TString fld(curr.left(poseq)); // preleva il nome del campo del form alla sinistra dell'uguale
 | 
						||
          const TString &dat= file->get(curr.mid(posrv)); // preleva il nome del campo del file alla destra dell'uguale e lo legge dal record
 | 
						||
          if (fld[0]=='#') fld.ltrim(1);
 | 
						||
          if (fld.right(1)== "@")
 | 
						||
          { // se c'<27> la a-commerciale <20> un gruppo
 | 
						||
            if (fld.find("->") != -1)
 | 
						||
            { // se nel gruppo c'<27> la freccia si riferisce ad un'altra sezione
 | 
						||
              sec= fld[0];
 | 
						||
              if (fld[1] != '-') pt= char2page(fld[1]);
 | 
						||
              else pt= even_page;
 | 
						||
              itms= section(sec, pt).fields();
 | 
						||
            }
 | 
						||
            else
 | 
						||
            { // altrimenti si riferisce alla sezione corrente
 | 
						||
              sec= cf.section().section_type();
 | 
						||
              pt= cf.section().page_type();
 | 
						||
              itms= cf.section().fields();
 | 
						||
            }
 | 
						||
            for (j=0; j<itms; j++)
 | 
						||
            { // per ogni campo della sezione specificata (o sottointesa)...
 | 
						||
              TForm_item &fi= section(sec, pt).field(j);
 | 
						||
              fi.set(dat);
 | 
						||
            }
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            TForm_item &fi= cf.find_field(fld);
 | 
						||
            fi.set(dat);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    delete file;
 | 
						||
    return TRUE;
 | 
						||
  // fine _ISAMREAD
 | 
						||
  }
 | 
						||
 | 
						||
  if (code== "_TABLEREAD")
 | 
						||
  {
 | 
						||
  // lettura generica di un campo di una tabella
 | 
						||
  // sintassi: _TABLEREAD,<tabella>,<chiave>,<campo file>
 | 
						||
  // dove: <tabella> nome tabella da leggere
 | 
						||
  //       <chiave> costante stringa o riferimento a campo della form (preceduto da '#') da usare come chiave di ricerca
 | 
						||
  //       <campo file> identificativo del campo da leggere dalla tabella
 | 
						||
    const TString4 cod = s.get(); // Codice tabella
 | 
						||
    valore = s.get(); // prende il valore o il campo da usare come codice di ricerca
 | 
						||
    if (valore[0]== '#')
 | 
						||
    {
 | 
						||
     valore.ltrim(1);
 | 
						||
     TForm_item &fi= cf.find_field(valore);
 | 
						||
     valore = fi.get();
 | 
						||
    }
 | 
						||
    const TRectype& tab = cache().get(cod, valore);
 | 
						||
    if (!tab.empty())
 | 
						||
    {
 | 
						||
      const TString &fld = s.get(); // prende il nome del campo da leggere...
 | 
						||
      valore = tab.get(fld);
 | 
						||
      cf.set(valore);
 | 
						||
    }
 | 
						||
    return TRUE;
 | 
						||
  } // fine _TABLEREAD
 | 
						||
 | 
						||
  if (code== "_ALIGN")
 | 
						||
  {
 | 
						||
    // allineamento della posizione di un campo rispetto ad un altro
 | 
						||
    // sintassi: _ALIGN,<campo form>[,<allineamento>][,<allineamento>...]
 | 
						||
    // dove: <campo form> <20> il campo della form (preceduto da '#') da cui prendere l'allineamento
 | 
						||
    //       <allineamento> <20> uno dei seguenti valori:
 | 
						||
    //        TOP    allinea sulla riga d'inizio
 | 
						||
    //        MIDDLE allinea al centro (effettivo)
 | 
						||
    //        BOTTOM allinea sulla riga di fine (effettiva, non preimpostata)
 | 
						||
    //        LEFT   allinea sulla colonna d'inizio
 | 
						||
    //        RIGHT  allinea sulla colonna di fine
 | 
						||
    TString in(s.get());
 | 
						||
    if (in[0]== '#') in.ltrim(1);
 | 
						||
    TForm_item &fi= cf.find_field(in);
 | 
						||
 | 
						||
    for (const char * cmd = s.get(); cmd != NULL; cmd = s.get())
 | 
						||
    { // Calcola la nuova posizione
 | 
						||
      TString align(cmd);
 | 
						||
      if (align[0]=='!')
 | 
						||
        align.ltrim(1);
 | 
						||
        
 | 
						||
      if (align== "TOP") cf.y()= fi.y();
 | 
						||
      else
 | 
						||
        if (align== "MIDDLE") cf.y()= fi.y()+ fi.effective_height()/2;
 | 
						||
        else
 | 
						||
          if (align== "BOTTOM") cf.y()= fi.y()+ (fi.effective_height() ? fi.effective_height()-1 : 0);
 | 
						||
          else
 | 
						||
            if (align== "LEFT") cf.set_x(fi.x());
 | 
						||
            else
 | 
						||
              if (align== "RIGHT") cf.set_x(fi.x()+ fi.width());
 | 
						||
    }
 | 
						||
    // altrimenti stampa la stringa cosi' com'e'
 | 
						||
    return TRUE;
 | 
						||
  } // fine _ALIGN
 | 
						||
 | 
						||
  if (code== "_PAGENO") // Messaggio per stampare il numero di pagina corrente
 | 
						||
  {
 | 
						||
    TString16 pg; pg << int(printer().getcurrentpage() );
 | 
						||
    cf.set(pg);
 | 
						||
    return TRUE;
 | 
						||
  } 
 | 
						||
 | 
						||
  if (code== "_TODAY")// Messaggio per stampare la data di oggi
 | 
						||
  {
 | 
						||
    const TDate oggi(TODAY);
 | 
						||
    cf.set(oggi.string());
 | 
						||
    return TRUE;
 | 
						||
  } 
 | 
						||
 | 
						||
  if (code== "_NUMEXPR" || code== "_STREXPR")
 | 
						||
  {
 | 
						||
  // Messaggio per la valutazione di espressioni numeriche e stringhe
 | 
						||
    int comma = s.find(',');
 | 
						||
    TExpression rval(s.mid(comma+1),code[1]=='N' ? _numexpr:_strexpr,TRUE);
 | 
						||
    cf.section().eval_expr(rval);
 | 
						||
    if (!rval.error())
 | 
						||
      cf.set(rval.as_string());
 | 
						||
    return TRUE;
 | 
						||
  } 
 | 
						||
 | 
						||
  if (code== "_DITTA")
 | 
						||
  {
 | 
						||
    // lettura dei dati della ditta
 | 
						||
    // sintassi: _DITTA,{<campo relazione>|<macro>}
 | 
						||
    // dove: <campo relazione> <20> un riferimento alla relazione di gestione dei dati della ditta (es. 113@->DENCOM <20> la denominazione del comune di residenza della ditta)
 | 
						||
    //       <macro> <20> uno delle macro seguenti:
 | 
						||
    //         !RAGSOC  ragione sociale
 | 
						||
    //         !IND     indirizzo (fiscale se c'<27>, oppure di residenza)
 | 
						||
    //         !NUM     numero civico (fiscale se c'<27>, oppure di residenza)
 | 
						||
    //         !CAP     CAP (fiscale se c'<27>, oppure di residenza)
 | 
						||
    //         !COM     comune (fiscale se c'<27>, oppure di residenza)
 | 
						||
    //         !PROV    provincia (fiscale se c'<27>, oppure di residenza)
 | 
						||
    //         !IVA     partita iva
 | 
						||
    //         !CF      codice fiscale
 | 
						||
    //         !TEL     numero di telefono (con prefisso)
 | 
						||
    //         !FAX     numero di fax (con prefisso)
 | 
						||
    //         !REGSOC  numero di registrazione presso il Tribunale
 | 
						||
    //         !CCIAA   numero di registrazione presso la camera di commercio
 | 
						||
    // nota: la relazione della ditta <20> cos<6F> strutturata:
 | 
						||
    //       %NDITTE (9) Dati ditte
 | 
						||
    //       + %ANAGR (6) Anagrafica generale (indirizzo, ecc.)
 | 
						||
    //          + %COMUNI (113@) Comune di residenza
 | 
						||
    //          + %COMUNI (213@) Comune di residenza fiscale
 | 
						||
    const TRectype& firm = cache().get(LF_NDITTE, main_app().get_firm());
 | 
						||
    
 | 
						||
    TString16 codanag; codanag.format("%c|%ld", firm.get_char("TIPOA"), firm.get_long("CODANAGR"));
 | 
						||
    const TRectype& anag = cache().get(LF_ANAG, codanag);
 | 
						||
    
 | 
						||
    TString in(s.get());
 | 
						||
    if (in[0]=='!') 
 | 
						||
    {
 | 
						||
      in.ltrim(1);
 | 
						||
      const bool _fisc= anag.get("INDRF").not_empty();
 | 
						||
      if (in=="CODDITTA") 
 | 
						||
        valore =firm.get("CODDITTA");
 | 
						||
      if (in=="RAGSOC") 
 | 
						||
        valore = anag.get("RAGSOC");
 | 
						||
      if (in=="IND") {
 | 
						||
        if (_fisc) 
 | 
						||
          valore = anag.get("INDRF");
 | 
						||
        else 
 | 
						||
          valore = anag.get("INDRES");
 | 
						||
      }
 | 
						||
      if (in=="NUM") {
 | 
						||
        if (_fisc)
 | 
						||
          valore = anag.get("CIVRF");
 | 
						||
        else 
 | 
						||
          valore = anag.get("CIVRES");
 | 
						||
      }
 | 
						||
      if (in=="CAP") {
 | 
						||
        if (_fisc) 
 | 
						||
          valore = anag.get("CAPRF");
 | 
						||
        else 
 | 
						||
          valore  = anag.get("CAPRES");
 | 
						||
      }
 | 
						||
      /*if (in=="COM") {
 | 
						||
        if (_fisc)
 | 
						||
          valore = _firmrel.lfile(-213).get("DENCOM");
 | 
						||
        else 
 | 
						||
          valore = _firmrel.lfile(-113).get("DENCOM");
 | 
						||
      }
 | 
						||
      if (in=="PROV") {
 | 
						||
        if (_fisc)
 | 
						||
          valore = _firmrel.lfile(-213).get("PROVCOM");
 | 
						||
        else 
 | 
						||
          valore = _firmrel.lfile(-113).get("PROVCOM");
 | 
						||
      }*/
 | 
						||
      if (in=="IVA")
 | 
						||
        valore = anag.get("PAIV");
 | 
						||
      if (in=="CF") 
 | 
						||
        valore = anag.get("COFI");
 | 
						||
      if (in=="TEL") {
 | 
						||
        valore = anag.get("PTEL");
 | 
						||
        valore << "/" << anag.get("TEL");
 | 
						||
      }
 | 
						||
      if (in=="FAX") {
 | 
						||
        valore = anag.get("PFAX");
 | 
						||
        valore << "/" << anag.get("FAX");
 | 
						||
      }
 | 
						||
      /*if (in=="REGSOC") {
 | 
						||
        valore = _firmrel[LF_UNLOC].get("REGTRIB");
 | 
						||
        valore << " Vol. " << _firmrel[LF_UNLOC].get("VOLTRIB");
 | 
						||
        valore << " Fasc. " << _firmrel[LF_UNLOC].get("FASCTRIB");
 | 
						||
      }
 | 
						||
      if (in=="CCIAA") {
 | 
						||
        valore = _firmrel[LF_UNLOC].get("NUMCCIAA");
 | 
						||
        valore << " del " << _firmrel[LF_UNLOC].get("DATAICCIAA");
 | 
						||
      } */
 | 
						||
    } 
 | 
						||
    else 
 | 
						||
    {
 | 
						||
      TFieldref fref(s.get(), 0);
 | 
						||
      valore = fref.read(anag);
 | 
						||
    }
 | 
						||
    cf.set(valore);
 | 
						||
    return TRUE; 
 | 
						||
  }
 | 
						||
  
 | 
						||
  return TRUE; 
 | 
						||
}
 | 
						||
 | 
						||
void TForm::print_on(ostream& out) const
 | 
						||
{
 | 
						||
  if (relation())
 | 
						||
  {
 | 
						||
    out << *relation() << "\nEND" << endl;
 | 
						||
    print_description(out);
 | 
						||
  }
 | 
						||
 | 
						||
  print_general(out);
 | 
						||
 | 
						||
  print_section(out, 'G');
 | 
						||
  print_section(out, 'H');
 | 
						||
  print_section(out, 'B');
 | 
						||
  print_section(out, 'F');
 | 
						||
 | 
						||
  out << "END" << endl;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
word TForm::height(word page)
 | 
						||
{
 | 
						||
  const pagetype t = (page == 1) ? first_page : ((page & 0x1) ? odd_page : even_page);
 | 
						||
 | 
						||
  word h = 0;
 | 
						||
  if (_back.items() == 0)
 | 
						||
  {
 | 
						||
    if (_head.items() && exist('H', t) != NULL)
 | 
						||
      h += section('H', page).height();
 | 
						||
    if (_body.items() && exist('B', t) != NULL)
 | 
						||
      h += section('B', page).height();
 | 
						||
    if (_foot.items() && exist('F', t) != NULL)
 | 
						||
      h += section('F', page).height();
 | 
						||
  }
 | 
						||
  else
 | 
						||
    h = printer().formlen();
 | 
						||
 | 
						||
  return h;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Legge un profilo
 | 
						||
//
 | 
						||
// @rdesc Ritorna se e' riuscito nell'operazione:
 | 
						||
// @flag TRUE | E' riuscito a leggere il prfilo
 | 
						||
// @flag FALSE | Non ha letto il profilo
 | 
						||
bool TForm::read_profile()
 | 
						||
// @comm Per la lettura del profilo procede leggendo prima la definizione del
 | 
						||
//   profilo base e successivamente le modifiche relative.
 | 
						||
{
 | 
						||
  TLocalisamfile prof(LF_FORM);
 | 
						||
  TLocalisamfile rprof(LF_RFORM);
 | 
						||
 | 
						||
  prof.zero();
 | 
						||
  prof.put("TIPOPROF",_name);
 | 
						||
  prof.put("CODPROF",_code);
 | 
						||
  if (prof.read(_isequal) == NOERR)
 | 
						||
  {
 | 
						||
    rprof.zero();
 | 
						||
    rprof.put("TIPOPROF", _name);
 | 
						||
    rprof.put("CODPROF", _code);
 | 
						||
    const TRectype filter(rprof.curr());
 | 
						||
    TString set("HGBF");
 | 
						||
 | 
						||
    for (int err = rprof.read(_isgteq); err == NOERR && rprof.curr() == filter; err = rprof.next())
 | 
						||
    {
 | 
						||
      // controllo lingua per codici profilo
 | 
						||
      char cl = rprof.curr().get("CODPROF").right(1)[0];
 | 
						||
      char cp = _code.right(1)[0];
 | 
						||
 | 
						||
      // stop se il codice letto e' di un profilo EC in lingua e
 | 
						||
      // il corrente e' ec non in lingua
 | 
						||
      if (!isdigit(cl) && cl != cp) break;
 | 
						||
 | 
						||
      const TString& s = rprof.get("SEZ");
 | 
						||
      const char sec = s[0];
 | 
						||
      if (set.find(sec)<0) continue; // Se non fa parte di una sezione standard la salta
 | 
						||
      const pagetype pt = char2page(s[1]);
 | 
						||
      const short id = rprof.get_int("ID");
 | 
						||
 | 
						||
      if (id == 0)
 | 
						||
      {
 | 
						||
        TPrint_section& se = section(sec, pt);
 | 
						||
        se.read_from(rprof.curr());
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        TForm_item& item = find_field(sec, pt, id);
 | 
						||
        item.read_from(rprof.curr());
 | 
						||
      }
 | 
						||
    }
 | 
						||
    if (_code.not_empty()&& !_isnew)
 | 
						||
    {
 | 
						||
      _x = prof.get_int("OFFX");
 | 
						||
      _y = prof.get_int("OFFY");
 | 
						||
      _fontname = prof.get("FONTNAME");
 | 
						||
      _fontsize = prof.get_int("FONTSIZE");
 | 
						||
      _char_to_pos = prof.get("CTP")[0];
 | 
						||
      _ipx = prof.get_int("IPX");
 | 
						||
      _ipy = prof.get_int("IPY");
 | 
						||
      _fpx = prof.get_int("FPX");
 | 
						||
      set_fincatura(prof.get("GRID"));
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm::write_profile()
 | 
						||
{
 | 
						||
  const char sechar[4] = { 'B', 'F', 'G',  'H' };
 | 
						||
 | 
						||
  get_compulsory_specials();
 | 
						||
  TLocalisamfile form(LF_FORM);
 | 
						||
  form.zero();
 | 
						||
  form.put("TIPOPROF",_name);
 | 
						||
  form.put("CODPROF",_code);
 | 
						||
  if (form.read(_isequal,_lock) == NOERR)
 | 
						||
  {
 | 
						||
    if (_dirty)
 | 
						||
    {
 | 
						||
      form.put("OFFY",_y);
 | 
						||
      form.put("OFFX",_x);
 | 
						||
      form.put("FONTNAME",_fontname);
 | 
						||
      form.put("FONTSIZE",_fontsize);
 | 
						||
      form.put("CTP",_char_to_pos);
 | 
						||
      form.put("IPX", _ipx);
 | 
						||
      form.put("IPY", _ipy);
 | 
						||
      form.put("FPX", _fpx);
 | 
						||
      form.put("GRID", _fink);
 | 
						||
      form.rewrite();
 | 
						||
      _dirty=FALSE;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  TLocalisamfile rform(LF_RFORM);
 | 
						||
  TRectype& cur = rform.curr();
 | 
						||
 | 
						||
  int err = NOERR;
 | 
						||
  for (int sn = 0; sn < 4 && err == NOERR; sn++)                        // For each section
 | 
						||
  {
 | 
						||
    const char sc = sechar[sn];
 | 
						||
    for (pagetype pt = odd_page; pt <= last_page; pt = pagetype(pt+1))  // For each section type
 | 
						||
    {
 | 
						||
      TPrint_section* sec = exist(sc, pt);
 | 
						||
      if (sec != NULL && sec->dirty())
 | 
						||
      {
 | 
						||
        const char codsez[3] = { sc, pt+'0', '\0' };
 | 
						||
        cur.zero();
 | 
						||
        cur.put("TIPOPROF", name());
 | 
						||
        cur.put("CODPROF", code());
 | 
						||
        cur.put("SEZ", codsez);
 | 
						||
        sec->print_on(cur);
 | 
						||
        sec->set_dirty(FALSE);
 | 
						||
 | 
						||
        err = _isnew ? rform.write() : rform.rewrite();
 | 
						||
        if (err != NOERR)
 | 
						||
          err = _isnew ? rform.rewrite() : rform.write();
 | 
						||
 | 
						||
        for (word i = 0; i < sec->fields() && err == NOERR; i++)
 | 
						||
        {
 | 
						||
          TForm_item& fi = sec->field(i);
 | 
						||
          if (fi.dirty())
 | 
						||
          {
 | 
						||
            fi.print_on(cur);
 | 
						||
            err = _isnew ? rform.write() : rform.rewrite();
 | 
						||
            if (err != NOERR)
 | 
						||
              err = _isnew ? rform.rewrite() : rform.write();
 | 
						||
            fi.set_dirty(FALSE);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  form.reread(_unlock);
 | 
						||
  if (err != NOERR)
 | 
						||
    return error_box(FR("Errore di salvataggio profilo: %d"), err);
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
void TForm::init()
 | 
						||
{
 | 
						||
  _npages=0;
 | 
						||
  _relation= NULL;
 | 
						||
  _cursor= NULL;
 | 
						||
  _rel_desc= NULL;
 | 
						||
  _isnew= FALSE;
 | 
						||
  _fontname= "";
 | 
						||
  _fontsize= 0;
 | 
						||
  _x= 0;
 | 
						||
  _y= 0;
 | 
						||
  _char_to_pos= '\0';
 | 
						||
  _ipx= 0;
 | 
						||
  _ipy= 0;
 | 
						||
  _fpx= 0;
 | 
						||
  _arrange= TRUE;
 | 
						||
  set_fincatura("+++++++++-|");
 | 
						||
  set_fink_mode(TRUE);
 | 
						||
  _dirty= FALSE;
 | 
						||
  _msg_add_enabled = TRUE;
 | 
						||
  _magic_currency = FALSE;
 | 
						||
  _exchange = NULL;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @mfunc Carica il form dal file specificato
 | 
						||
void TForm::read(
 | 
						||
     const char* name,  // @parm Nome del profilo di stampa da leggere
 | 
						||
     const char* code,  // @parm Codice del profilo di stampa da leggere
 | 
						||
     int lev,           // @parm Permessi di stampa
 | 
						||
     const char* desc)  // @parm Descrizione del formato da leggere
 | 
						||
{
 | 
						||
  _name= name;
 | 
						||
 | 
						||
  _code= code;
 | 
						||
  _editlevel= lev;
 | 
						||
  _desc= desc;
 | 
						||
 | 
						||
  if (_code.not_empty())
 | 
						||
  {
 | 
						||
    // extract base form name
 | 
						||
    TLocalisamfile forms(LF_FORM);
 | 
						||
    forms.zero();
 | 
						||
 | 
						||
    forms.put("TIPOPROF", _name);
 | 
						||
    forms.put("CODPROF", _code);
 | 
						||
    _isnew = forms.read() != NOERR;
 | 
						||
    if (_isnew)
 | 
						||
    {
 | 
						||
      // create new form
 | 
						||
      forms.put("TIPOPROF", _name);
 | 
						||
      forms.put("CODPROF", _code);
 | 
						||
      forms.put("DESC",    _desc);
 | 
						||
      forms.put("OFFY",_y);
 | 
						||
      forms.put("OFFX",_x);
 | 
						||
      forms.put("FONTNAME",_fontname);
 | 
						||
      forms.put("FONTSIZE",_fontsize);
 | 
						||
      forms.put("CTP", _char_to_pos);
 | 
						||
      forms.put("IPX", _ipx);
 | 
						||
      forms.put("IPY", _ipy);
 | 
						||
      forms.put("FPX", _fpx);
 | 
						||
      forms.put("GRID", _fink);
 | 
						||
      forms.write();
 | 
						||
    }
 | 
						||
    else
 | 
						||
      if (forms.status() == NOERR)
 | 
						||
      {
 | 
						||
        _desc = forms.get("DESC");
 | 
						||
        if (desc && *desc && _desc != desc ) // Controlla se la descrizione e' diversa, in questo caso l'aggiorna
 | 
						||
        {
 | 
						||
          forms.reread(_lock);
 | 
						||
          forms.put("DESC",desc);
 | 
						||
          forms.rewrite();
 | 
						||
        }
 | 
						||
      }
 | 
						||
  }
 | 
						||
 | 
						||
  // read base form
 | 
						||
  TFilename n(_name); n.ext("frm");
 | 
						||
	
 | 
						||
  if (n.custom_path()) 
 | 
						||
  {
 | 
						||
    _filename = n;
 | 
						||
    printer().set_form_name(n);
 | 
						||
  }
 | 
						||
  else
 | 
						||
		fatal_box(FR("Il form '%s' non esiste."),(const char*)n);
 | 
						||
  TScanner scanner(n);
 | 
						||
 | 
						||
  bool ok = TRUE;
 | 
						||
  if (scanner.popkey() == "US")                         // Parse relation
 | 
						||
  {
 | 
						||
		TString filter(80);
 | 
						||
 | 
						||
    ok = parse_use(scanner, filter);
 | 
						||
    while (ok)
 | 
						||
    {
 | 
						||
      const TString& k = scanner.popkey();
 | 
						||
      if (k == "JO") ok = parse_join(scanner); else
 | 
						||
      if (k == "SO") ok = parse_sortedjoin(scanner);
 | 
						||
      else
 | 
						||
        break;
 | 
						||
    }
 | 
						||
		if (filter.full())
 | 
						||
			_cursor->setfilter(filter);
 | 
						||
    parse_description(scanner);                         // Parse description
 | 
						||
  }
 | 
						||
  else scanner.push();
 | 
						||
 | 
						||
  if (ok) parse_general(scanner);                       // Parse general
 | 
						||
 | 
						||
  while (ok)
 | 
						||
  {
 | 
						||
    if (scanner.popkey() != "SE")                       // SECTION or END
 | 
						||
      break;
 | 
						||
    const char sec = scanner.popkey()[0];               // Section name (GRAPH, HEAD, BODY, FOOT)
 | 
						||
    const pagetype p = char2page(scanner.popkey()[0]);  // Section type (odd, even, first, last)
 | 
						||
    TPrint_section* ps = exist(sec, p, TRUE);           // Create section
 | 
						||
    ok = ps->parse(scanner);                            // Parse section
 | 
						||
  }
 | 
						||
 | 
						||
  if (_code.not_empty())
 | 
						||
    read_profile();    // read from LF_RFORM file
 | 
						||
 | 
						||
  set_compulsory_specials();
 | 
						||
  TPrinter& pr = printer();
 | 
						||
  pr.set_offset(_y,_x);
 | 
						||
  if (_fontname.not_empty())
 | 
						||
  {
 | 
						||
    pr.set_char_size(_fontsize);
 | 
						||
    pr.set_fontname(_fontname);
 | 
						||
  } 
 | 
						||
  set_fink_mode(TRUE);
 | 
						||
}
 | 
						||
 | 
						||
void TForm::set_compulsory_specials()
 | 
						||
{
 | 
						||
  const char sechar[3] = { 'B', 'F', 'H' };
 | 
						||
 | 
						||
  for (int sn = 0; sn < 3; sn++)
 | 
						||
  {
 | 
						||
    const char sc = sechar[sn];
 | 
						||
    for (pagetype pt = odd_page; pt <= last_page; pt = pagetype(pt+1))
 | 
						||
    {
 | 
						||
      const TPrint_section* sec = exist(sc, pt);
 | 
						||
      if (sec != NULL && sec->columnwise())
 | 
						||
      {
 | 
						||
        const word fields = sec->fields();
 | 
						||
        for (word i = 0; i < fields; i++)
 | 
						||
        {
 | 
						||
          TForm_item& fi = sec->field(i);
 | 
						||
          if (fi.special_items() > 0)
 | 
						||
          {
 | 
						||
            fi.set_col_head(fi.get_special_value("INTESTAZIONE"));
 | 
						||
            fi.ofs() = (short)atoi(fi.get_special_value("OFFSET"));
 | 
						||
            const TString& fnk = fi.get_special_value("FINCATURA");
 | 
						||
            if (fnk.not_empty())
 | 
						||
            {
 | 
						||
              fi.set_finkl(fnk[0]!='X'); // !finkl significa fincatura abilitata
 | 
						||
              fi.set_finkr(fnk[1]!='X'); // !finkr significa fincatura abilitata
 | 
						||
            }  
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TForm::get_compulsory_specials()
 | 
						||
{
 | 
						||
  const char sechar[3] = { 'B', 'F', 'H' };
 | 
						||
 | 
						||
  for (int sn = 0; sn < 3; sn++)
 | 
						||
  {
 | 
						||
    const char sc = sechar[sn];
 | 
						||
    for (pagetype pt = odd_page; pt <= last_page; pt = pagetype(pt+1))
 | 
						||
    {
 | 
						||
      TPrint_section* sec = exist(sc, pt);
 | 
						||
      if (sec != NULL)
 | 
						||
      {
 | 
						||
        const word fields = sec->fields();
 | 
						||
        const bool col_wise = sec->columnwise();
 | 
						||
        for (word i = 0; col_wise && i < fields; i++)
 | 
						||
        {
 | 
						||
          TForm_item& fi = sec->field(i);
 | 
						||
          if (fi.special_items()>0)
 | 
						||
          {
 | 
						||
            fi.set_special_value("INTESTAZIONE", fi.col_head());
 | 
						||
            fi.set_special_value("OFFSET", format("%d",fi.ofs()));
 | 
						||
            TString fnk(fi.finkl()? " " : "X");
 | 
						||
            fnk << (fi.finkr() ? " " : "X");
 | 
						||
            fi.set_special_value("FINCATURA",fnk);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TForm::set_fincatura(const char* s)
 | 
						||
{
 | 
						||
  _fink = s; _fink.cut(11);
 | 
						||
  printer().set_fincatura(_fink);
 | 
						||
}
 | 
						||
 | 
						||
void TForm::set_fink_mode(bool f)
 | 
						||
{   
 | 
						||
  printer().set_fink_mode(f);
 | 
						||
}
 | 
						||
 | 
						||
bool TForm::get_fink_mode()
 | 
						||
{
 | 
						||
  return printer().get_fink_mode();
 | 
						||
}
 | 
						||
 | 
						||
// @cmember Indica se ignorare il prossimo skip del ciclo sul file 
 | 
						||
void TForm::match_result(int file,int val)
 | 
						||
{
 | 
						||
  if (file==0)
 | 
						||
    file=cursor()->file().num();
 | 
						||
  if (val <0)
 | 
						||
    _skip_info.destroy(file);
 | 
						||
  else 
 | 
						||
  {
 | 
						||
    TForm_skip_info info;
 | 
						||
    if (next_match_done(file))
 | 
						||
      info._match_number=((TForm_skip_info &)_skip_info[file])._match_number;
 | 
						||
    if (val) 
 | 
						||
      info._match_number++;
 | 
						||
    info._match_result= val != 0;
 | 
						||
    _skip_info.add(info,file);
 | 
						||
  }
 | 
						||
}
 | 
						||
// @cmember Indica se ignorare (default) o non ignorare il prossimo skip del ciclo sul file
 | 
						||
bool TForm::last_match_result(int file)
 | 
						||
{
 | 
						||
  if (file==0)
 | 
						||
    file=cursor()->file().num();
 | 
						||
  if (next_match_done(file))
 | 
						||
    return ((TForm_skip_info &)_skip_info[file])._match_result;
 | 
						||
  return fatal_box("Tryed to get result of a never executed skip in file %d",file); 
 | 
						||
}
 | 
						||
 | 
						||
// @mfunc Memorizza l'avvenuto next_match  sul file passato 
 | 
						||
bool TForm::next_match_done(int file)
 | 
						||
{
 | 
						||
  if (file==0)
 | 
						||
    file=cursor()->file().num();
 | 
						||
  return _skip_info.objptr(file)!=NULL;
 | 
						||
}
 | 
						||
 | 
						||
// @mfunc Indica l'avvenuto next_match  sul file passato
 | 
						||
int TForm::matches_done(int file)
 | 
						||
{
 | 
						||
  if (file==0)
 | 
						||
    file=cursor()->file().num();
 | 
						||
  if (next_match_done(file))
 | 
						||
    return ((TForm_skip_info &)_skip_info[file])._match_number;
 | 
						||
  return 0;
 | 
						||
}
 | 
						||
 | 
						||
void TForm::set_output_exchange(const char* codval, real exchange, exchange_type et)
 | 
						||
{
 | 
						||
  if (_exchange == NULL) 
 | 
						||
    _exchange = new TExchange;
 | 
						||
  _exchange->set(codval, exchange, et);
 | 
						||
}
 | 
						||
 | 
						||
TForm::TForm()
 | 
						||
{
 | 
						||
  init();
 | 
						||
  _frompage=_topage=0;
 | 
						||
  _magic_currency = FALSE;
 | 
						||
}
 | 
						||
 | 
						||
TForm::TForm(const char* name, const char* code, int lev, const char* desc)
 | 
						||
{
 | 
						||
  init();
 | 
						||
  read(name, code, lev, desc);
 | 
						||
  _frompage=_topage=0;
 | 
						||
  _magic_currency = FALSE;
 | 
						||
}
 | 
						||
 | 
						||
TForm::~TForm()
 | 
						||
{
 | 
						||
  if (_cursor)
 | 
						||
  {
 | 
						||
    delete _cursor;
 | 
						||
    delete _relation;
 | 
						||
    if (_rel_desc)
 | 
						||
      delete _rel_desc;
 | 
						||
  }
 | 
						||
  if (_exchange)
 | 
						||
    delete _exchange;
 | 
						||
}
 |