// Stampa base
#include "77stba.h"
const int _RIGHE_N = 6;
const int _RIGHE_R = 4;
const int _RIGHE_P = 4;
const int _RIGHE_Q = 4;
const int _RIGHE_S = 5;
const int _RIGHE_T = 4;
const int _RIGHE_NA = 8;
const int _RIGHE_RA = 6;
const int _RIGHE_PA = 11;
const int _RIGHE_QA = 4;
const int _RIGHE_SA = 7;
const int _RIGHE_TA = 4; 

const int _NUM_L_AGG = 679; 
const int _NUM_N_AGG = 680;     

const int _NUM_FOGLIO_QL = 4;
const int _NUM_FOGLIO_QN = 4;  

const int _START_AGG_L=16;
const int _REC_PRIMA_AGG_L=13;
const int _REC_SECONDA_AGG_L=14;
const int _RIGA_TOTALI_AGG_L=59; 

const int _BASE_FIRMA_DICH=685;

int TBase1::dic_form_len() const
{
  if (curr_page()==PRIMA && _PaginaPosizionamento)
    return BASE_FORMLEN-HEADER_PRIMA_NOPOS_BASE;
  else
    return BASE_FORMLEN;
}

int TBase1::prima_riga(PaginaQuadro p) const
{
  if (p==PRIMA && _PaginaPosizionamento)
    return 12;
  else
    return 12+HEADER_PRIMA_NOPOS_BASE;
}

TBase1::TBase1(const char* sNomeForm, const char* quadro)  : TDicForm(sNomeForm, quadro) 
{
  r = new TRelation(LF_SOCI);
  r->add(LF_ANAG,    "TIPOA=TIPOASOC|CODANAGR=CODANAGRSO");
  r->add(LF_ANAGFIS, "CODANAGR=CODANAGR",1, LF_ANAG);    
  r->add(LF_COMUNI,  "COM=COMNASC",1,LF_ANAGFIS);
  c = new TCursor(r);       
  _bAllegSoci=FALSE;
  _base_formlen = BASE_FORMLEN;
  _GiaMessoStartDoc=FALSE;
}

TBase1::~TBase1()
{
  delete r;
  delete c;
}

void TBase1::stampa_corpo(TPrinter& pr)
{
  TPrint_section& body = section('B', first_page);
  body.reset();
  body.update();       

  const int body_righe = body.height();
  for (int i = 0; i < body_righe; i++)
  {
    pr.print(body.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

// accetta solo quelli con qualifica=A,B o C, ATTUALI E FISICI
bool bFiltraSoci(const TRelation* rel)
{ 
  TString sQual(3);               
  TString sTipo;
  sTipo = rel->lfile().get("TIPOASOC"); 
  sQual = rel->lfile().get("RICQUAL"); 
  TString dep;                                       
  dep = rel->lfile().get("ATTPREC");   
  const bool bAttuale = dep == "A"; 
  return sTipo=="F" && bAttuale && (sQual=="A" || sQual=="B" || sQual=="C");
}

long TBase1::iContaSoci()
{                  
  TString filtro(20);
  filtro.format("CODDITTA=%d",_codditta);
  c->setfilter(filtro);
  c->set_filterfunction(bFiltraSoci);
  (*c)=0L;
  return c->items();
}

void TBase1::stampa_soci(TPrinter& pr)
{                                  
  TPrint_section& fut = section('F', first_page);
  fut.reset();
  
  const long iSoci = iContaSoci();
  if (iSoci > 12)
  {
    _bAllegSoci=TRUE;
    TPrintrow& rg=fut.row(0);    
    rg.put("VEDERE ALLEGATO", 25);
    pr.print(rg);      
    _RigaCorr++;
    if (usa_progind()) progind()->addstatus(1);
  }
  else
  {    
    int i=0;                             
    TString sRagsoc,sSesso,sComuneNa,sProvNa,sDataNa,sCodFis,sCodQua;
    for ((*c)=0L; c->pos() < c->items(); ++(*c))
    {                         
      TString sNome,sCognome;
      TPrintrow& rg=fut.row(i++);
      sCodQua=c->file().get("RICQUAL");       
      sRagsoc=c->file(LF_ANAG).get("RAGSOC");
      sCodFis=c->file(LF_ANAG).get("COFI");       
      sDataNa=c->file(LF_ANAGFIS).get("DATANASC"); 
      sSesso=c->file(LF_ANAGFIS).get("SESSO");
      sComuneNa=c->file(LF_COMUNI).get("DENCOM");      
      sComuneNa.cut(23);
      sProvNa=c->file(LF_COMUNI).get("PROVCOM");      
      if (sRagsoc.len() > 30 && sRagsoc[30] != ' ')
      {
        sCognome=sRagsoc.left(30);
        sCognome.trim();
        sNome=sRagsoc.right(20);
        sNome.trim();
        sRagsoc = sCognome;
        sRagsoc << " " << sNome;
      }
      sRagsoc.cut(28);
      rg.put(sRagsoc,fut.field(0).x()-1);
      fut.field(1).set(sSesso);          
      rg.put(sSesso,fut.field(1).x()-1);      
      fut.field(2).set(sComuneNa);       
      rg.put(sComuneNa,fut.field(2).x()-1);      
      fut.field(3).set(sProvNa);         
      rg.put(sProvNa,fut.field(3).x()-1);      
      fut.field(4).set(sDataNa);         
      rg.put(sDataNa,fut.field(4).x()-1);      
      fut.field(5).set(sCodFis);         
      rg.put(sCodFis,fut.field(5).x()-1);      
      fut.field(6).set(sCodQua);         
      rg.put(sCodQua,fut.field(6).x()-1);      
      pr.print(rg);      
      _RigaCorr++;
      if (usa_progind()) progind()->addstatus(1);
    }
  }
}

bool TBase1::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _codditta=codditta;  
// Usata per modulaser in fill_page()
  set_curr_page(PRIMA);        

  if (!InitPrint(codditta))
    return FALSE;                        
    
  pr.formlen(_base_formlen);             
  _PaginaPosizionamento = _base_formlen != BASE_FORMLEN;
  
  // se il dispositivo scelto non � una winprinter
  // non � mai eseguito il posizionamento
  if (pr.printtype() != winprinter)
    _PaginaPosizionamento = FALSE;    
  
  (*cur)=0L;  
  if (_modulaser) 
  {
    ClearFlagModulaser();
    TPrintrow r;
    if (!_GiaMessoStartDoc)           
    {
      put_modulaser(r, VEGASTARTDOC);     
      _GiaMessoStartDoc=TRUE;
    }
    put_modulaser(r, VEGASTARTDITTA);
    put_modulaser(r, VEGASTARTPAGE, 1);
    pr.print(r);
    _RigaCorr++;
  }
  jump_to_line(pr, prima_riga(PRIMA));
  stampa_corpo(pr);       
  stampa_soci(pr);
  next_page(pr);
  close_print();
  return TRUE;
}

void TBase2::stampa_corpo(TPrinter& pr)
{
  TPrint_section& body = section('B', even_page);
  body.reset();
  body.update();       
  const int body_righe = body.height();
  for (int i = 0; i < body_righe; i++)
  {
    pr.print(body.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

bool TBase2::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  if (_modulaser) 
  {  
    ClearFlagModulaser();
    set_curr_page(SECONDA);            
  }
  _codditta=codditta;
  filtra(codditta);      
  _RigaCorr=0;
  (*cur)=0L;  
  jump_to_line(pr, prima_riga(PRIMA));
  stampa_corpo(pr);       
  next_page(pr);
  close_print();                                      
  return TRUE;
}

long TBase3::filtra(const long codditta)
{
  TString filtr(24); 
  _codditta=codditta;
  filtr.format("(CODDITTA==%ld)&&(QLAP==%d)", codditta, anno_770());
  cursor()->setfilter(filtr, TRUE);   
  const long items = cursor()->items();
  return items;
}

void TBase3::stampa_testata(TPrinter& pr)
{
  TPrint_section& hh = section('H', first_page);
  hh.reset();
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

int TBase3::stampa_L(TPrinter& pr)
{
  long codit=0L;
  TPrint_section& body = section('B', odd_page);
  body.reset();               
  
  TCursor& cur = *cursor();

  bool finito=FALSE;
  int righe=0;
  while (!finito)
  {
    // compilo da programma il mese pagamento
    TForm_item& meserif = body.find_field(1);
    TString sMeserif = cur.file().get("QLMP");
    TString sAnnorif = cur.file().get("QLAP");
    TString sTributo = cur.file().get("QLCT");
    // se tributo 4730 o 4731 compilo il mese pagamento uguale all'anno
    if (sTributo == "4730" || sTributo == "4731")
      meserif.set(sAnnorif.right(2));
    // altrimenti ci metto il suo
    else                              
      meserif.set(sMeserif);
    
    body.update();    
    
    const int body_righe = body.height();
    for (int i = 0; i < body_righe; i++)
    {
      TPrintrow& rr=body.row(i);
      pr.print(rr);
      rr.reset();
      _RigaCorr++;
    }
    if (usa_progind())
      progind()->addstatus(1);
    righe++;                           
    ++cur;
    codit=cur.file().get_long("CODDITTA");
    bool buono=codit==_codditta;
// Guarda se e' necessario stampare l'aggiuntivo
    _bAggiuntivoL = buono && righe>14;
    finito=righe>14 || codit!=_codditta;
  }
  return righe;
}

void TBase3::reset_totali_L()
{
  TPrint_section& hh = section('F', last_page);
  TForm_item& t1 = hh.find_field(1);
  TForm_item& t2 = hh.find_field(2);  
  t1.set("");
  t2.set("");
}

void TBase3::stampa_totali_L(TPrinter& pr)
{ 
// La sezione f last contiene solo due totali aggiornati con add nel form
  TPrint_section& hh = section('F', last_page);
//  hh.reset();
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

bool TBase3::print(const long codditta, const long NumFis, const long NumNoFis)
{                          
  _bAggiuntivoL=TRUE;
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _codditta=codditta;
  reset_totali_L();
  if (_modulaser) 
  {  
    ClearFlagModulaser();
    set_curr_page(TERZA);        
  }
  _RigaCorr=0;               
  
// Legge dai par.studio l'ordinamento da usare per L
  TConfig conf(CONFIG_STUDIO);
  const int iChiaveL = (int)conf.get_long("FlStQl", "77"); 
// Le chiavi nel file e nel .ini sono saggiamente scambiate  
  if (iChiaveL==2) 
    cur->setkey(1);
  else 
    cur->setkey(2);

// ! posizionare il cursore prima di stampa_testata() !
  filtra(_codditta);
  (*cur)=0L;  

  jump_to_line(pr, prima_riga(PRIMA));
// Stampa i codici concessione e tesoreria
  stampa_testata(pr);         

  const int righe_stampate=stampa_L(pr);                 
// Se la stampa prosegue i totali vanno sull'aggiuntivo NON qui
  if (!_bAggiuntivoL)                            
  {
    jump_to_line(pr,_RIGA_TOTALI_L);
    stampa_totali_L(pr);
  }
  next_page(pr);
  close_print();  
  return TRUE;
}

const char* TRigaN::sMeseRif() const
{           
  __dep16="";
  __dep16 << _MeseRif;
  return __dep16;
}

const char* TRigaN::sAnnoRif() const
{           
  __dep16="";
  __dep16 << _AnnoRif;
  return __dep16;
}

// Ordina le righe N per periodo di riferimento
int TRigaN::compare(const TSortable& s) const
{
  const TRigaN& rec = (const TRigaN&)s;
  const int da = _AnnoRif - rec._AnnoRif;
  const int dm = _MeseRif - rec._MeseRif;
  if (da==0)
    return dm;
  else
    return da;                                           
}

TRigaN::TRigaN(const TLocalisamfile& qn)
{                   
  _pos = qn.recno();
  
  const TRectype& rec = qn.curr();
  
  _MeseRif = rec.get_int("MESERIF"); 
  _AnnoRif = rec.get_int("ANNORIF");  
// Nel quadro R si chiama diversamente @!#@!!!  
  if (qn.num() == LF_QUAN)
    _ImpRimb = rec.get_real("IMPOSTA");
  else                               
    _ImpRimb = rec.get_real("IMPRIMB");  
  _CompAss = rec.get_real("COMPENSI"); 
  
  // tipo rimborso solo su quadro R
  if (qn.num() == LF_QUAR)
    _TipoRimb = rec.get("TIPORIMB");
}

int TRigheNR::fill(const long codditta,TLocalisamfile& qnr)
{
  long ditta=0L;  
  _data.destroy();
// Si posiziona sul primo della ditta corrente
  qnr.zero();
  qnr.put("CODDITTA",codditta);
  qnr.read();
  ditta=qnr.get_long("CODDITTA");
  if (ditta!=codditta) return 0;

// Legge tutti quelli della ditta corrente
  for (; !qnr.eof(); qnr.next())
  {                          
    ditta=qnr.get_long("CODDITTA");
    if (ditta!=codditta) break;
    
    TRigaN* n = new TRigaN(qnr);
    _data.add(n);
  } 
  _data.sort();
  const int i = _data.items();
  return i;
}

const char* TRigaQT::sMesePag() const
{           
  __dep16="";
  __dep16 << _MesePag;
  return __dep16;
}

const char* TRigaQT::sAnnoPag() const
{           
  __dep16="";
  __dep16 << _AnnoPag;
  return __dep16;
}

// Ordina le righe N per periodo di riferimento
int TRigaQT::compare(const TSortable& s) const
{
  const TRigaQT& rec = (const TRigaQT&)s;
  const int da = _AnnoPag - rec._AnnoPag;
  const int dm = _MesePag - rec._MesePag;
  if (da==0)
    return dm;
  else
    return da;                                           
}

TRigaQT::TRigaQT(const TLocalisamfile& qt)
{                   
  const TRectype& rec = qt.curr();
  
  _MesePag = rec.get_int("MESEPAG"); 
  _AnnoPag = rec.get_int("ANNOPAG");  
  _ContVers = rec.get_real("CONTVERS");
  _ContRimb = rec.get_real("CONTRIMB");
  _Interessi=rec.get_real("INTERESSI");
  _sCodReg=rec.get("CODREG");
}

int TRigheQT::fill(const long codditta,TLocalisamfile& qt)
{
  long ditta=0L;
// Si posiziona sul primo della ditta corrente
  _data.destroy();
  qt.zero();
  qt.put("CODDITTA",codditta);
  qt.read();
  ditta=qt.get_long("CODDITTA");
  if (ditta!=codditta) return 0;

// Legge tutti quelli della ditta corrente
  for (; !qt.eof(); qt.next())
  {                          
    ditta=qt.get_long("CODDITTA");
    if (ditta!=codditta) break;
    
    TRigaQT* n = new TRigaQT(qt);
    _data.add(n);
  } 
  _data.sort();
  const int i = _data.items();
  return i;
}

// Ordina le righe N per periodo di riferimento
int TRigaPS::compare(const TSortable& s) const
{
  const TRigaPS& rec = (const TRigaPS&)s;
  const long diff = _dDv-rec.dDataVers();
  return (int)diff;
}

TRigaPS::TRigaPS(const TLocalisamfile& qt)
{                   
  const TRectype& rec = qt.curr();
  
  _dDv     = rec.get_date("DATAVERS"); 
  _rImp    = rec.get_real("IMPOSTA");  
  _rIntDip = rec.get_real("INTERDIP");
  _rIntDat = rec.get_real("INTERDAT");           
  _sTipoV  = rec.get("TIPOVERS");
  _sCodTrib= rec.get("CODTRIB");
  _sSerie  = rec.get("SERIE");
  _sNumero = rec.get("NUMERO");   
  _dMeseCong = rec.get_date("MESECONG");  
}

int TRighePS::fill(const long codditta,TLocalisamfile& ps)
{
  long ditta=0L;
// Si posiziona sul primo della ditta corrente
  _data.destroy();
  ps.zero();
  ps.put("CODDITTA",codditta);
  ps.read();
  ditta=ps.get_long("CODDITTA");
  if (ditta!=codditta) return 0;

// Legge tutti quelli della ditta corrente
  for (; !ps.eof(); ps.next())
  {                          
    ditta=ps.get_long("CODDITTA");
    if (ditta!=codditta) break;
    
    TRigaPS* n = new TRigaPS(ps);
    _data.add(n);
  } 
  _data.sort();
  const int i = _data.items();
  return i;
}

int TBase4::calcola_firma(int id, int maxlen)
{
  TPrint_section& totali = section('F', first_page);
  TForm_item& signature = totali.find_field(id);
  const int y = signature.y();
  TString spazi(50); spazi.fill(' ');  
  TString cognome = signature.get();   
  
  // compress cognome und nome
  if (cognome.len() > 30 && cognome[29] == ' ')
  {
    TString nome = cognome.mid(30, -1);
    cognome.cut(30); cognome.trim();
    cognome << ' ' << nome;    
  }                        
  
  // limite firma's length 
  if (maxlen != -1 && cognome.len() > maxlen)
    cognome.cut(maxlen);
    
  signature.set(cognome);
  totali.row(y-1).put(spazi, signature.x()-1);
  totali.row(y-1).put(cognome, signature.x()-1);
  return y;
}

void TBase4::stampa_testata(TPrinter& pr)
{
  TPrint_section& hh = section('H', first_page);
  hh.reset();
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}                                  

void TBase4::fill_riga_QT(TPrint_section& sec,const int num,const char quadro)
{              
  TString sVal;
  int start=1,end=6; 
  const int items = quadro=='Q' ? _righeQ.items() : _righeT.items();
  for (int i = start; i <= end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < items)
    {
      const TRigaQT& rN = quadro=='Q' ? _righeQ[num] : _righeT[num];      
      if (i==start)
        sVal=rN.sMesePag();
      else if (i==start+1)
        sVal=rN.sAnnoPag();
      else if (i==start+2)  
        sVal=rN.ContVers(fi.picture());
      else if (i==start+3)
        sVal=rN.ContRimb(fi.picture());
      else if (i==start+4)
        sVal=rN.Interessi(fi.picture());
      else if (i==start+5)
        sVal=rN.CodReg();
    }  
    else 
      sVal="";
    fi.set(sVal); 
    TPrintrow& row=sec.row(0);
    row.put(sVal,fi.x()-1);
  }       
} 

void TBase4::stampa_Q(TPrinter& pr)
{
  TPrint_section& body = section('F', even_page);
  body.reset();                                     
  TLocalisamfile qq(LF_QUAQ);
  _righeQ.fill(_codditta,qq);    
  if (_righeQ.items()==0) return;  
  _bAggQ = _righeQ.items() > _RIGHE_Q;

  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    TPrintrow& rr=body.row(0);
    rr.reset();    
    fill_riga_QT(body,riga,'Q');                   
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_Q-1;
  }
}

void TBase4::stampa_T(TPrinter& pr)
{
  TPrint_section& body = section('F', odd_page);
  body.reset();                                     
  TLocalisamfile qp(LF_QUAT);
  _righeT.fill(_codditta,qp);
  if (_righeT.items()==0) return;
  _bAggT = _righeT.items() > _RIGHE_T;

  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    TPrintrow& rr=body.row(0);
    rr.reset();    
    fill_riga_QT(body,riga,'T'); 
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_T-1;
  }
}

void TBase4::fill_riga_PS(TPrint_section& sec,const int num,const char quadro)
{              
  TString sVal,sDep;
  int start=1,end=9;
  const int items = quadro=='P' ? _righeP.items() : _righeS.items();
  for (int i = start; i <= end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < items)
    {
      const TRigaPS& rN = quadro=='P' ? _righeP[num] : _righeS[num];      
      if (i==start)
      {      
        sVal = "";
        if (rN.MeseCong())  
          sVal << rN.MeseCong(); 
      }   
      else if (i==start+1)
        sVal=rN.sImposta(fi.picture());
      else if (i==start+2)
        sVal=rN.sIntDip(fi.picture());
      else if (i==start+3)  
        sVal=rN.sIntDat(fi.picture());
      else if (i==start+4)
        sVal=rN.sTipoVers();
      else if (i==start+5)
        sVal=rN.sCodTrib();
      else if (i==start+6)  
      {
        sDep=rN.sDataVers();
        sVal.picture(fi.picture(),sDep);
      }
      else if (i==start+7)
        sVal=rN.sSerie();
      else if (i==start+8)
        sVal=rN.sNumero();
    }  
    else 
      sVal="";
    fi.set(sVal); 
    TPrintrow& row=sec.row(0);
    row.put(sVal,fi.x()-1);
  }       
} 

void TBase4::stampa_P(TPrinter& pr)
{
  TPrint_section& body = section('H', even_page);
  body.reset();                                     
  TLocalisamfile qp(LF_QUAP);
  _righeP.fill(_codditta,qp);    
  if (_righeP.items()==0) return;  
  const int items=_righeP.items();
  _bAggP = items > _RIGHE_P;

  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    TPrintrow& rr=body.row(0);
    rr.reset();    
    fill_riga_PS(body,riga,'P');
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_P-1;
  }
}

void TBase4::stampa_S(TPrinter& pr)
{
  TPrint_section& body = section('H', even_page);
  body.reset();                                     
  TLocalisamfile qp(LF_QUAS);
  _righeS.fill(_codditta,qp);      
  if (_righeS.items()==0) return;    
  _bAggS = _righeS.items() > _RIGHE_S;

  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    TPrintrow& rr=body.row(0);
    rr.reset();
    fill_riga_PS(body,riga,'S');
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione = riga > _RIGHE_S -1 ;
  }
}

void TBase4::stampa_R(TPrinter& pr)
{
  TPrint_section& body = section('B', even_page);
  body.reset();                                     
  TLocalisamfile qr(LF_QUAR);
  _righeR.fill(_codditta,qr);      
  if (_righeR.items()==0) return;    
  const int items=_righeR.items();   
  
  _bAggR = items > _RIGHE_R;
  
  int num=0;                
  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {  
    fill_riga_R(body,num,0);
    num+=2;
    fill_riga_R(body,num,1); 
    TPrintrow& rr=body.row(0);
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);     
    num-=1;
    FinitaSezione=riga>1;               
  }  
}

void TBase4::fill_riga_N(TPrint_section& sec,const int num, const int side)
{              
  TString sVal;
  int start,end;
  if (side==0)
  {
    start=1;
    end=5;
  }
  else
  {
    start=5;
    end=9;
  }
  const int items = _righeN.items();
  for (int i = start; i < end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < items)
    {
      const TRigaN& rN = _righeN[num];     
      if (i==start)
        sVal=rN.sMeseRif();
      else if (i==start+1)
        sVal=rN.sAnnoRif();
      else if (i==start+2)  
        sVal=rN.ImpRimb(fi.picture());
      else if (i==start+3)
        sVal=rN.CompAss(fi.picture());
    }  
    else 
      sVal="";
    fi.set(sVal); 
    TPrintrow& row=sec.row(0);
    row.put(sVal,fi.x()-1);
  }       
} 

void TBase4::fill_riga_R(TPrint_section& sec,const int num, const int side)
{              
  TString sVal;
  int start,end;
  if (side==0)
  {
    start=1;
    end=6;
  }
  else
  {
    start=6;
    end=11;
  }
  const int items = _righeR.items();
  for (int i = start; i < end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < items)
    {
      const TRigaN& rN = _righeR[num];     
      if (i==start)
        sVal=rN.sMeseRif();
      else if (i==start+1)
        sVal=rN.sAnnoRif(); 
      else if (i==start+2)
        sVal=rN.TipoRimb();  
      else if (i==start+3)  
        sVal=rN.ImpRimb(fi.picture());
      else if (i==start+4)
        sVal=rN.CompAss(fi.picture());
    }  
    else 
      sVal="";
    fi.set(sVal); 
    TPrintrow& row=sec.row(0);
    row.put(sVal,fi.x()-1);
  }       
} 

void TBase4::stampa_N(TPrinter& pr)
{ 
  TPrint_section& body = section('B', odd_page);
  body.reset();                                     
  TLocalisamfile qn(LF_QUAN);
  _righeN.fill(_codditta,qn);        
  if (_righeN.items()==0) return; 
  
  _bAggN = _righeN.items() > _RIGHE_N;

  int num=0;                
  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    fill_riga_N(body,num,0); 
    num+=3;
    fill_riga_N(body,num,1); 
    TPrintrow& rr=body.row(0);
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    num-=2;
    FinitaSezione=riga>2;               
  }
}

void TBase4::stampa_fine(TPrinter& pr)
{
  TPrint_section& sec = section('F', first_page);
  const int hhr = sec.height();
  sec.reset();                  
  
  // imposto numero quadri L aggiuntivi
  TForm_item& L_agg = sec.find_field(_NUM_L_AGG);  
  TString val;
  long num = num_quadri_L_agg(_codditta);
  if (num) val << num;
  L_agg.set(val);                   
     
  // imposto numero quadri N/P/Q/R/S/T aggiuntivi
  TForm_item& N_agg = sec.find_field(_NUM_N_AGG);  
  val = "";
  num = num_quadri_N_agg(_codditta);
  if (num) val << num;
  N_agg.set(val);
  
  sec.update();      
  
  // compress firma dichiarante
  int lasty = calcola_firma(_BASE_FIRMA_DICH, 40);     
  // compress firma direttore tecnico           
  lasty = calcola_firma(_IdFirma);                    
  
  for (int i = 0; i < hhr; i++)
  {
    pr.print(sec.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

bool TBase4::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  _bAggN=_bAggP=_bAggR=_bAggQ=_bAggS=_bAggT=FALSE;
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  // per modulaser end-doc (v.fill_page())  
  _EndPrintDitta=TRUE;
  _codditta=codditta;
  filtra(codditta);      
  if (_modulaser) 
  {  
    ClearFlagModulaser();
    set_curr_page(QUARTA);        
  }
  _RigaCorr=0;
  (*cur)=0L;                              
  jump_to_line(pr, prima_riga(PRIMA));
  // Stampa da M1 a M7  
  stampa_testata(pr);
  stampa_N(pr);   
  jump_to_line(pr,18);       
  stampa_P(pr);             
  jump_to_line(pr,24);         
  stampa_Q(pr);            
  jump_to_line(pr,30);         
  stampa_R(pr);            
  jump_to_line(pr,34);         
  stampa_S(pr);            
  jump_to_line(pr,41);         
  stampa_T(pr);        
  jump_to_line(pr,45);           
  stampa_fine(pr);
  next_page(pr);
  close_print();
  return TRUE;
}

bool TStampaBase::user_create()
{
  _fBase1 = new TBase1("77base1", "Base");
  _fBase2 = new TBase2("77base2", "Base");   
  _fBase3 = new TBase3("77base3", "Base");     
  _fBase4 = new TBase4("77base4", "Base");      
// Adesso bisogna chiamare set_cursor per impostare il cursore dentro
// al form. Sarebbe meglio fare in modo che il form usi sempre il cursore
// letto dal .frm, senza bisogno di passarglielo dall'applicazione
  _fBase1->set_cursor(_fBase1->TForm::cursor());         
  _fBase2->set_cursor(_fBase2->TForm::cursor());    
  _fBase3->set_cursor(_fBase3->TForm::cursor());    
  _fBase4->set_cursor(_fBase4->TForm::cursor());    
  return TRUE;
}

bool TStampaBase::user_destroy()
{
  delete _fBase1; 
  delete _fBase2;  
  delete _fBase3;  
  delete _fBase4;      
  return TRUE;
}          

bool TStampaBase::print_quadro(const int OffsetDitta, const bool modulaser)
{
  int start=0, last=0;                
// Flag per distinguere la prima pagina con posizionamento da quelle successive senza
  bool GiaPosizionato=FALSE;
// Setta formlen prima di printer.open per avere la lunghezza giusta nel caso di 
// stampa a video
  printer().formlen(BASE_FORMLEN);               
  bool ok = printer().open();

  _fBase1->set_modulaser(modulaser);
  _fBase2->set_modulaser(modulaser);      
  _fBase3->set_modulaser(modulaser);      
  _fBase4->set_modulaser(modulaser);      
      
// Dice se deve eseguire il posizionamento del foglio.
// Se stampa piu' ditte va eseguito solo sulla prima
// Occhio a non spostarlo nel ciclo.
  _fBase1->set_posiziona(TRUE);
    
  if (OffsetDitta >= 0)
  {
    start = OffsetDitta;
    last = OffsetDitta;  
  }
  else
    last = ditte().items() - 1;
    
  for (int i = start; i <= last; i++)
  {
    TString CoFiDic(20);
    TToken_string riga(ditte()[i]);
    const long codditta = atol(riga.get(0));
    const TipoDitta  tipo = (TipoDitta)riga.get_int(1);
    const long fis      = riga.get_long(2);
    const long nofis    = riga.get_long(3);
    const bool LastFis  = riga.get_int(4) != 0;
    const bool LastNoFis = riga.get_int(5) != 0;

// I gruppi dich-estinti hanno totali comuni  
// Si presume che nell'array vengano messi nell'ordine dich-estinti
    if (tipo == normale || tipo == dichiarante)
      _fBase1->azzera_totali();

    if (tipo == estinto)
      CoFiDic = riga.get(6);
      
// Dice al form che tipo di ditta si stampa
    _fBase1->set_tipo_ditta(tipo);

// Numera i fogli a partire da 1 per ogni ditta normale e da 1 e di seguito negli estinti
// per i sogg. dichiaranti
    if (tipo == normale || tipo == dichiarante)
      _fBase1->set_num_foglio(1);
      
// Se la ditta e' estinta dice al form il cod.fis. del dichiarante
    if (tipo == estinto)
      _fBase1->set_cofi_dic(CoFiDic);

// Dice al form che e' l'ultima ditta
    if (i == last)
      _fBase1->set_last_ditta(TRUE);

    if (GiaPosizionato)
      _fBase1->set_formlen(BASE_FORMLEN);
    else                                 
      _fBase1->set_formlen(BASE_FORMLEN-HEADER_PRIMA_NOPOS_BASE);    
    _fBase1->print(codditta, fis, nofis); 
    GiaPosizionato=TRUE;                                

    _fBase2->print(codditta, fis, nofis);    
    _fBase3->print(codditta, fis, nofis);
    _fBase4->set_last_ditta(i==last);
    _fBase4->print(codditta, fis, nofis);            
  }    
                     
  printer().close();
  return ok;
}

int TQuadroL::dic_form_len() const
{
  if (curr_page()==PRIMA && _PaginaPosizionamento)
    return QL_FORMLEN-HEADER_PRIMA_NOPOS_QL;
  else
    return QL_FORMLEN;
}

int TQuadroL::prima_riga(PaginaQuadro p) const
{
  if (p==PRIMA)
  {
    if (_PaginaPosizionamento)
      return 1;
    else
      return 1+HEADER_PRIMA_NOPOS_QL;
  }
  else
    return 3;
}


long TQuadroL::filtra(const long codditta)
{
  TString filtr(24); 
  _codditta=codditta;
  filtr.format("(CODDITTA==%ld)&&(QLAP==%d)", _codditta,anno_770());
  cursor()->setfilter(filtr, TRUE);   
  const long items = cursor()->items();
  return items;
}

void TQuadroL::stampa_testata(TPrinter& pr)
{
  TPrint_section& hh = section('H', first_page);
  hh.reset();

  TForm_item& nf=hh.find_field(_NUM_FOGLIO_QL);
  _num_foglio++;
  TString fstr(10); fstr << _num_foglio;
  nf.set(fstr);      
  
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

// Stampa fino a iRecL record del quadro L. 
// Incrementa lStartRec per ogni incremento del cursore
bool TQuadroL::stampa_L(TPrinter& pr,long& lStartRec,const int iRecL)
{
  long codit=0L;
  bool eof=FALSE;
  TPrint_section& body = section('B', odd_page);
  body.reset();               
  TCursor& cur = *cursor();
  if (lStartRec > cur.items())
    return TRUE;
  else
    cur=lStartRec;
  bool bFinitaPagina=FALSE;
  int righe=0;
  const long items = cur.items();

  while ( (cur.pos() < items) && !bFinitaPagina )
  {
    // compilo da programma il mese pagamento
    TForm_item& meserif = body.find_field(1);
    TString sMeserif = cur.file().get("QLMP");
    TString sAnnorif = cur.file().get("QLAP");
    TString sTributo = cur.file().get("QLCT");
    // se tributo 4730 o 4731 compilo il mese pagamento uguale all'anno
    if (sTributo == "4730" || sTributo == "4731")
      meserif.set(sAnnorif.right(2));
    // altrimenti ci metto il suo
    else                              
      meserif.set(sMeserif);   
      
    body.update();
    const int body_righe = body.height();
    for (int i = 0; i < body_righe; i++)
    {
      TPrintrow& rr=body.row(i);
      pr.print(rr);
      rr.reset();
      _RigaCorr++;
    }
    if (usa_progind())
      progind()->addstatus(1);
    righe++;                           
    ++cur;                           
    lStartRec++;
    bFinitaPagina = (righe==iRecL);
  }                              
  eof=cur.pos() >= items;  
  return eof;
}

int TQuadroL::calcola_firma()
{
  TPrint_section& totali = section('F', last_page);
  TForm_item& signature = totali.find_field(4);
  const int y = signature.y();
  TString spazi(50); spazi.fill(' ');  
  TString cognome = signature.get();
  if (cognome.len() > 30 && cognome[29] == ' ')
  {
    TString nome = cognome.mid(30, -1);
    cognome.cut(30); cognome.trim();
    cognome << ' ' << nome;
    signature.set(cognome);
  }   
  totali.row(y-1).put(spazi, signature.x()-1);
  totali.row(y-1).put(cognome, signature.x()-1);
  return y;
}

void TQuadroL::stampa_totali_L(TPrinter& pr, bool finito)
{
  TPrint_section& hh = section('F', last_page);
  TForm_item& totEff = hh.find_field(1); 
  TForm_item& totVer = hh.find_field(2);                    
  
  // nascondo i totali che vanno stampati sull'ultimo modulo
  totEff.hide();
  totVer.hide();  
  
  hh.update();                                
    
  // se ultima pagina stampo anche i totali
  if (finito)
  {
    totEff.show();
    totVer.show();
    real rTotEff(totEff.get()); 
    real rTotVer(totVer.get()); 
    rTotEff += _rTotEff;
    rTotVer += _rTotVer;
    totEff.set(rTotEff.string());
    totVer.set(rTotVer.string()); 
    totEff.update();
    totVer.update();
  }

  const int lasty = calcola_firma();
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

void TQuadroL::calcola_totali_precedenti()
{                         
  TCursor* cur = cursor();             
  _rTotEff = _rTotVer = ZERO;
  for ((*cur)=0L;  cur->pos() < _START_AGG_L-1; ++(*cur) )
  {
    _rTotEff += cur->curr().get_real("QLRITEFF");
    _rTotVer += cur->curr().get_real("QLRITVER");
  }    
}

void TQuadroL::reset_totali_L()
{
  TPrint_section& hh = section('F', last_page);
  hh.reset();
}

bool TQuadroL::print(const long codditta, const long NumFis, const long NumNoFis)
{                          
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _num_foglio=0;
  if (!InitPrint(codditta))
    return FALSE;

  // Non stampare se non ci sono record
  if (cur->items() < _START_AGG_L)                
  {  
    close_print();  
    return FALSE;   
  }  

  // Legge dai par.studio l'ordinamento da usare per L
  TConfig conf(CONFIG_STUDIO);
  const int iChiaveL = (int)conf.get_long("FlStQl", "77"); 
  if (iChiaveL==2) 
    cur->setkey(1);
  else 
    cur->setkey(2);

  calcola_totali_precedenti();
      
  // se il dispositivo scelto non � una winprinter
  // non � mai eseguito il posizionamento
  if (pr.printtype() != winprinter)
    _PaginaPosizionamento = FALSE;    

  pr.formlen(dic_form_len());
  long lOffsetL=_START_AGG_L-1; 
  (*cur)=lOffsetL;        
  
  if (_modulaser) 
  {
    TPrintrow r;
    put_modulaser(r, VEGASTARTDOC);
    put_modulaser(r, VEGASTARTDITTA);
    put_modulaser(r, VEGASTARTPAGE, PRIMA);
    pr.print(r);
    _RigaCorr++;
  }
  
  bool finito=FALSE;
  while (!finito)
  {  
    // prima pagina
    set_curr_page(PRIMA);
    jump_to_line(pr, prima_riga(PRIMA));
    stampa_testata(pr);         
    finito=stampa_L(pr,lOffsetL,_REC_PRIMA_AGG_L);
    next_page(pr); 
      
    // secona pagina
    set_curr_page(SECONDA);
    _PaginaPosizionamento=FALSE;
    pr.formlen(dic_form_len());
    if (!finito)         
    {
      jump_to_line(pr, prima_riga(SECONDA));
      finito=stampa_L(pr,lOffsetL,_REC_SECONDA_AGG_L);
    }    
    jump_to_line(pr,_RIGA_TOTALI_AGG_L);
    stampa_totali_L(pr, finito);
    _EndPrintDitta = finito;
    next_page(pr); 
    
    if (_modulaser)        
      ClearFlagModulaser();
  }
  close_print();  
  return TRUE;
}

bool TStampaQuadroAggL::user_create()
{   
  _form = new TQuadroL("77QL", quadro());
  _form->set_cursor(_form->TForm::cursor());
// init anche di _cur nell'applicazione  
  _cur = _form->cursor();
  return TRUE;  
}

bool TStampaQuadroAggL::user_destroy()
{
  delete _form;
  return TRUE;
}

void TQuadroN::stampa_fine(TPrinter& pr)
{
  TPrint_section& sec = section('F', first_page);
  const int hhr = sec.height();
  sec.reset();                  
  sec.update();                   
  const int lasty = calcola_firma(_IdFirma);
  for (int i = 0; i < hhr; i++)
  {
    pr.print(sec.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

void TQuadroN::stampa_testata(TPrinter& pr)
{
  TPrint_section& hh = section('H', first_page);
  hh.reset();
  
  TForm_item& nf=hh.find_field(_NUM_FOGLIO_QN);
  _num_foglio++;
  TString fstr(10); fstr << _num_foglio;
  nf.set(fstr);      
  
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

int TQuadroN::prima_riga(PaginaQuadro p) const
{
  if (_PaginaPosizionamento)
    return 1;
  else
    return 1+HEADER_PRIMA_NOPOS_QN;
}

int TQuadroN::stampa_N(TPrinter& pr,const int ptrN)
{ 
  TPrint_section& body = section('B', odd_page);
  body.reset();
  int num=ptrN;
  int riga=0;               
  int LastUsed=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    fill_riga_N(body,num,0);
    num+=4;      
    LastUsed=num+1;
    fill_riga_N(body,num,1); 
    TPrintrow& rr=body.row(0);
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    num-=3;
    FinitaSezione=riga>3;  
  }              
  return LastUsed;
}

int TQuadroN::stampa_P(TPrinter& pr,const int ptrP)
{
  TPrint_section& body = section('H', even_page);
  body.reset();                                     
  const int items=_righeP.items();
  int riga=ptrP;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    fill_riga_PS(body,riga,'P');
    TPrintrow& rr=body.row(0);
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione= riga-ptrP > _RIGHE_PA-1;
  }
  return riga;
}               

int TQuadroN::stampa_Q(TPrinter& pr,const int ptrQ)
{
  TPrint_section& body = section('F', even_page);
  body.reset();                                     

  int riga=ptrQ;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    fill_riga_QT(body,riga,'Q');
    TPrintrow& rr=body.row(0);
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione= riga-ptrQ > _RIGHE_QA-1;
  }
  return riga;
}

int TQuadroN::stampa_R(TPrinter& pr,const int ptrR)
{
  TPrint_section& body = section('B', even_page);
  body.reset();                                     
  const int items=_righeR.items();
  int RecNum=ptrR;
  int RigheStampate=0;
  int LastUsed=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    fill_riga_R(body,RecNum,0);
    RecNum+=3;    
    LastUsed=RecNum+1;
    fill_riga_R(body,RecNum,1);
    TPrintrow& rr=body.row(0);
    pr.print(rr);
    rr.reset();
    RigheStampate++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1); 
    RecNum-=2;    
    FinitaSezione=RigheStampate>2;      
  }
  return LastUsed;
}

int TQuadroN::stampa_S(TPrinter& pr,const int ptrS)
{
  TPrint_section& body = section('H', even_page);
  body.reset();
  int riga=ptrS;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    fill_riga_PS(body,riga,'S');
    TPrintrow& rr=body.row(0);
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione= riga-ptrS > _RIGHE_SA-1;
  }
  return riga;
}

int TQuadroN::stampa_T(TPrinter& pr,const int ptrT)
{
  TPrint_section& body = section('F', odd_page);
  body.reset();
  int riga=ptrT;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
    fill_riga_QT(body,riga,'T');
    TPrintrow& rr=body.row(0);
    pr.print(rr);
    rr.reset();
    riga++;
    _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione= riga-ptrT > _RIGHE_TA-1;
  } 
  return riga;
}

int TQuadroN::dic_form_len() const
{
  if (_PaginaPosizionamento)
    return 72-HEADER_PRIMA_NOPOS_QN;
  else
    return 72;
}

bool TQuadroN::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _num_foglio=0;
  _codditta=codditta;
  if (!InitPrint(codditta))
    return FALSE;
  
  TLocalisamfile qn(LF_QUAN);
  _righeN.fill(_codditta,qn);
  bool stampoN=_righeN.items() > _RIGHE_N;
  TLocalisamfile qp(LF_QUAP);
  _righeP.fill(_codditta,qp);      
  bool stampoP=_righeP.items() > _RIGHE_P;  
  TLocalisamfile qq(LF_QUAQ);
  _righeQ.fill(_codditta,qq);        
  bool stampoQ=_righeQ.items() > _RIGHE_Q;    
  TLocalisamfile qr(LF_QUAR);
  _righeR.fill(_codditta,qr);
  bool stampoR=_righeR.items() > _RIGHE_R;    
  TLocalisamfile qs(LF_QUAS);
  _righeS.fill(_codditta,qs);     
  bool stampoS=_righeS.items() > _RIGHE_S;    
  TLocalisamfile qt(LF_QUAT);
  _righeT.fill(_codditta,qt);
  bool stampoT=_righeT.items() > _RIGHE_T;  

  int ptrN=_RIGHE_N;
  int ptrP=_RIGHE_P;
  int ptrQ=_RIGHE_Q;
  int ptrR=_RIGHE_R;
  int ptrS=_RIGHE_S;
  int ptrT=_RIGHE_T;
  
  // Se non c'e' niente da stampare esce
  if (!stampoN && !stampoP && !stampoQ && !stampoR && !stampoS
      && !stampoT) 
  {    
    close_print();
    return FALSE;
  }  
  
  _PaginaPosizionamento=pr.getcurrentpage()==1;
  
  // se il dispositivo scelto non � una winprinter
  // non � mai eseguito il posizionamento
  if (pr.printtype() != winprinter)
    _PaginaPosizionamento = FALSE;    
  
  pr.formlen(dic_form_len());
  _RigaCorr=0;
  (*cur)=0L;  
  
  if (_modulaser) 
  {
    TPrintrow r;
    put_modulaser(r, VEGASTARTDOC);
    put_modulaser(r, VEGASTARTDITTA);
    put_modulaser(r, VEGASTARTPAGE, PRIMA);
    pr.print(r);
    _RigaCorr++;
  }
  
  bool done=FALSE;
  while (!done)
  {
    // prima pagina
    set_curr_page(PRIMA);
    jump_to_line(pr, prima_riga(PRIMA));             
    int skip=HEADER_PRIMA_NOPOS_QN;
    stampa_testata(pr);
    jump_to_line(pr, _PaginaPosizionamento ? 15-skip : 15);
    ptrN=stampa_N(pr,ptrN); 
    jump_to_line(pr, _PaginaPosizionamento ? 21-skip : 21);
    ptrP=stampa_P(pr,ptrP); 
    jump_to_line(pr, _PaginaPosizionamento ? 34-skip : 34);
    ptrQ=stampa_Q(pr,ptrQ);
    jump_to_line(pr, _PaginaPosizionamento ? 40-skip : 40);
    ptrR=stampa_R(pr,ptrR);
    jump_to_line(pr, _PaginaPosizionamento ? 45-skip : 45);
    ptrS=stampa_S(pr,ptrS);
    jump_to_line(pr, _PaginaPosizionamento ? 54-skip : 54);
    ptrT=stampa_T(pr,ptrT);   
    jump_to_line(pr, _PaginaPosizionamento ? 58-skip : 58);
    stampa_fine(pr);
    bool FinitoN = ptrN >= _righeN.items(); 
    bool FinitoP = ptrP >= _righeP.items();
    bool FinitoQ = ptrQ >= _righeQ.items();
    bool FinitoR = ptrR >= _righeR.items();
    bool FinitoS = ptrS >= _righeS.items();                
    bool FinitoT = ptrT >= _righeT.items();    
    done = FinitoN && FinitoP && FinitoQ && FinitoR  && FinitoS && FinitoT;
    _EndPrintDitta = done; 
    next_page(pr);           
    _PaginaPosizionamento=FALSE;
    pr.formlen(dic_form_len());   
  
    if (_modulaser)        
      ClearFlagModulaser();
  }
  close_print();
  return TRUE;
}

bool TStampaQuadroAggN::user_create()
{   
  _form = new TQuadroN("77QN", quadro());
  _form->set_cursor(_form->TForm::cursor());
  _cur = _form->cursor();
  return TRUE;  
}

bool TStampaQuadroAggN::user_destroy()
{
  delete _form;
  return TRUE;
}