429 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			429 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| //  ab1100    Stampa tabelle
 | |
| //
 | |
| // legge un file con estenzione .rpt che descrive la stampa.
 | |
| // Vedi file leggimi.txt per il formato del file
 | |
| //
 | |
|   
 | |
| #include <mask.h>
 | |
| #include <printapp.h>
 | |
| #include <recarray.h>
 | |
| #include <utility.h>
 | |
| 
 | |
| #include <nditte.h>
 | |
| 
 | |
| #include "ab1.h"
 | |
| #include "ab1100.h"
 | |
| 
 | |
| #define FOOTER_LEN 4  // se non ridefinito nel .rpt
 | |
| 
 | |
| class AB1100_application : public TPrintapp
 | |
| {
 | |
|   TString       _tabname;
 | |
|   TFilename     _rptname;
 | |
|   TRelation*    _rel;
 | |
|   TCursor      *_cur;
 | |
|   TMask*        _msk;
 | |
|   TString       _maskname;
 | |
|   int           _logicnum;
 | |
|   TString_array _string_roman, _string_compound; 
 | |
|   TString_array _field_roman, _field_compound; 
 | |
| //  bool          _stampa_registri;
 | |
| //  bool          _stampa_ca7; //tabella causali 770
 | |
|   bool          _tabella_comune;
 | |
|   
 | |
| public:
 | |
| 
 | |
|   virtual bool user_create() ;
 | |
|   virtual bool user_destroy() ;
 | |
|   virtual bool set_print(int) ;
 | |
| 
 | |
|   virtual void set_page(int, int);
 | |
|   virtual bool preprocess_page (int, int);
 | |
|   virtual bool preprocess_print(int file, int counter);
 | |
| 
 | |
|   void set_headers();
 | |
|   void set_rows();
 | |
|   void set_footers();
 | |
|   void set_translations();
 | |
|   void set_relations();
 | |
|   AB1100_application() {}
 | |
|   virtual ~AB1100_application() {}
 | |
| };
 | |
| 
 | |
| 
 | |
| bool AB1100_application::set_print(int)
 | |
| {
 | |
|   TRectype from(_rel->lfile().curr()); from.zero();
 | |
|   TRectype to  (from);
 | |
|   
 | |
|   if (_msk->run() == K_ENTER)
 | |
|   {
 | |
|     const int campi_maschera = _msk->fields(); 
 | |
|     for (int i = 0; i < campi_maschera; i++)
 | |
|     {
 | |
|       const TMask_field& campo_maschera = _msk->fld(i);
 | |
|       const char* val = campo_maschera.get();
 | |
|       if (*val)
 | |
|       {
 | |
|         const TFieldref* campo_ref = campo_maschera.field();  
 | |
| 
 | |
|         if (campo_ref != NULL && campo_ref->ok())
 | |
|         {                                                   
 | |
|           TDate d;    
 | |
|           const bool is_date_field = campo_maschera.class_id() == CLASS_DATE_FIELD;
 | |
|           if (is_date_field) 
 | |
|             d=val;
 | |
|           if (campo_maschera.in_group(1)) campo_ref->write(is_date_field ? d.string(ANSI) : val, from);
 | |
|           else
 | |
|             if (campo_maschera.in_group(2)) campo_ref->write(is_date_field ? d.string(ANSI) : val, to);
 | |
|         }  
 | |
|       }
 | |
|     }
 | |
|     _cur->setregion (from, to);
 | |
| 
 | |
|     set_headers();
 | |
|     return TRUE;
 | |
|   }
 | |
|   return FALSE;  
 | |
| }
 | |
| 
 | |
| void AB1100_application::set_page (int , int )
 | |
| {
 | |
|   _string_roman.destroy();
 | |
|   _field_roman.destroy();
 | |
|   _string_compound.destroy();
 | |
|   _field_compound.destroy();
 | |
|   set_rows();
 | |
| }
 | |
| 
 | |
| bool AB1100_application::preprocess_page(int , int)
 | |
| {
 | |
|   const int items = _field_roman.items();
 | |
| 
 | |
|   if (items > 0)
 | |
|   {
 | |
|     for (int i = 0; i < items; i++)
 | |
|     {
 | |
|       TString& fn = _field_roman.row(i);
 | |
|       TFieldref fld(fn, 0);
 | |
|       TString& s = _string_roman.row(i);
 | |
|       
 | |
|       const int n = atoi(fld.read(*_rel));
 | |
|       s = itor(n);
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   const int compound = _field_compound.items();
 | |
|   if (compound > 0)
 | |
|     // Scorre le righe settate
 | |
|     for (int i = 0; i < compound; i++)
 | |
|     {
 | |
|       TToken_string f(_field_compound.row(i),'+'); // campo composto
 | |
|       TString& s = _string_compound.row(i); // riga da stampare
 | |
|       s.cut(0); // Reset the row...
 | |
|       bool compile_row = TRUE;
 | |
|       const int cmp_items = f.items(); 
 | |
|       // Scorre gli elementi della riga
 | |
|       for (int j = 0; j < cmp_items; j++)
 | |
|       {
 | |
|         // compone la stringa totale
 | |
|         TString xx(f.get(j));
 | |
|         if (xx[0] != '"') // se non e' una costante stringa legge il valore
 | |
|         {
 | |
|           TFieldref fld(xx,0);
 | |
|           xx = fld.read(*_rel);
 | |
|           if (xx.empty()) compile_row = FALSE;
 | |
|           else compile_row = TRUE;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           xx.ltrim(1);xx.rtrim(1);
 | |
|         }
 | |
|         if (compile_row)
 | |
|           s << xx; // appende alla stringa il valore ricavato (se il campo e' vuoto non appende nemmeno la stringa fissa)
 | |
|       }
 | |
|     }
 | |
|   // Stampa tabella registri. Calcolo: pagine residue = pagine - stampate
 | |
| 
 | |
| 		return TRUE;
 | |
| }
 | |
| 
 | |
| void AB1100_application::set_headers()
 | |
| {
 | |
|   TString        NomeTabella, sep, formato_intesta, testo_intesta;
 | |
|   int            LungRiga, riga_intesta=0, last_riga=1;
 | |
|   TToken_string  line;
 | |
|   TString256     riga;
 | |
|   
 | |
|   reset_header ();
 | |
| 
 | |
|   TScanner rpt(_rptname);
 | |
|   rpt.paragraph("Headers");
 | |
| 
 | |
|   // Leggo la lunghezza della riga (usata per centrare l'intestazione)
 | |
|   line = rpt.line();
 | |
|   LungRiga    = line.get_int();
 | |
| 
 | |
|   riga.spaces(LungRiga);
 | |
|   // Senno' nella stampa a 80 non ci sta ditta e data
 | |
| 
 | |
|   // Leggo il nome della tabella
 | |
|   line = rpt.line();
 | |
|   NomeTabella = line.get();
 | |
| 
 | |
|   // Sulla prima riga di intestazione metto la ditta, la data e la pagina
 | |
|   if (!_tabella_comune)
 | |
|   {
 | |
|     const long     codditta = get_firm();
 | |
|     TString80      ragsoc;
 | |
|     const TRectype & nditta = cache().get(LF_NDITTE, codditta);
 | |
| 
 | |
|     ragsoc = nditta.get(NDT_RAGSOC);
 | |
|     if (LungRiga < 100) ragsoc.cut(40);
 | |
|     riga.overwrite(format(FR("Ditta %4ld %s"), codditta,(const char *)ragsoc));
 | |
|   }
 | |
|   
 | |
|   riga.overwrite (FR("Data @< Pag. @#"), riga.len()-22);
 | |
| 
 | |
|   set_header (last_riga++, "%s", (const char *)riga);
 | |
|   
 | |
|   // Centro il nome della tabella
 | |
|   // Per la stampa registri non va centrato. 
 | |
|   // Lo lascio anche per le altre stampe 
 | |
|   //  if (_stampa_registri)
 | |
|   NomeTabella.left_just (LungRiga);
 | |
| 
 | |
|   set_header (last_riga++, "@b%s", (const char *)NomeTabella);
 | |
| 
 | |
|   line = rpt.line();
 | |
|   while ( (line != "") && (line[0] != '[') )
 | |
|   {
 | |
|     riga_intesta    = atoi (line.get());        
 | |
|     formato_intesta = line.get();
 | |
|     testo_intesta   = (const char *) line.get();
 | |
|     if (riga_intesta)
 | |
|       set_header (last_riga+riga_intesta, (const char *)formato_intesta, 
 | |
|                   (const char *)testo_intesta);
 | |
|     line = rpt.line();
 | |
|   }
 | |
| 
 | |
|   if (riga_intesta) last_riga += riga_intesta;
 | |
|   last_riga++;
 | |
|   
 | |
|   //set_header (last_riga, (const char *)sep);
 | |
|   sep.fill(' ');
 | |
|   set_header (last_riga, (const char *)sep); 
 | |
|   set_background(format("W2l{1,3,%d,3}l{1,%d,%d,%d}", LungRiga, last_riga, LungRiga, last_riga));
 | |
| }
 | |
| 
 | |
| void AB1100_application::set_rows()
 | |
| {
 | |
|   TToken_string  line;
 | |
|   TFieldref     campo;
 | |
|   int           from = 0, to = 0, riga_record;
 | |
|   TString       formato_campo, picture;
 | |
|   const char *          name = NULL;
 | |
| 
 | |
|   TScanner rpt(_rptname);
 | |
|   rpt.paragraph("Rows");
 | |
| 
 | |
|   line = rpt.line();
 | |
|   while ( (line != "") && (line[0] != '[') )
 | |
|   {
 | |
|     riga_record = line.get_int();
 | |
| 
 | |
|     
 | |
|     TString s(line.get());
 | |
|     int logicnum = _logicnum;
 | |
|     const bool is_compound = s.find('+') >= 0; // Controlla se e' una stringa composta (usare #t nel formato)
 | |
|     if (!is_compound)
 | |
|     {
 | |
|       campo = s;
 | |
|       from = campo.from();
 | |
|       to = campo.to();
 | |
|       name = campo.name();
 | |
|       if (campo.file() != 0)
 | |
|         logicnum = campo.file();
 | |
|     }
 | |
|       
 | |
|     formato_campo = line.get();
 | |
|     formato_campo.trim();
 | |
|     formato_campo.lower();
 | |
|     const int p = formato_campo.find("@m");
 | |
|       
 | |
|     if (p != -1 && !is_compound)
 | |
|     {
 | |
|       formato_campo.cut(p);
 | |
|       formato_campo << "#t";
 | |
|       _string_roman.add("");
 | |
|       _field_roman.add(s);
 | |
|       const int last = _string_roman.items() - 1;
 | |
|   
 | |
|       set_row (riga_record, formato_campo, _string_roman.objptr(last));
 | |
|     }
 | |
|     else if (!is_compound)
 | |
|     {
 | |
|       if (formato_campo.find("@pn"))
 | |
|         picture = line.get();
 | |
|       else
 | |
|         picture = "";
 | |
|         
 | |
|       if (to == -1)
 | |
|         if (picture != "")
 | |
|           set_row (riga_record, formato_campo, FLD(logicnum,name,picture) );
 | |
|         else
 | |
|           set_row (riga_record, formato_campo, FLD(logicnum,name) );
 | |
|       else
 | |
|         set_row (riga_record, formato_campo, FLD(logicnum,name,from,to) );
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       _string_compound.add("");
 | |
|       _field_compound.add(s);
 | |
|       const int last = _string_compound.items() - 1;
 | |
|   
 | |
|       set_row (riga_record, formato_campo, _string_compound.objptr(last));
 | |
|     }
 | |
|     line = (const char *) rpt.line();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void AB1100_application::set_footers()
 | |
| {
 | |
|   TToken_string line;
 | |
|   int     footer_len, riga;
 | |
|   TString formato, testo;
 | |
| 
 | |
|   reset_footer();
 | |
| 
 | |
|   TScanner rpt(_rptname);
 | |
|   rpt.paragraph("Footers");
 | |
| 
 | |
|   line = rpt.line();
 | |
|   footer_len = line.get_int(); 
 | |
|   if (footer_len != 0) 
 | |
|   {
 | |
|     printer().footerlen(footer_len);
 | |
|     line = rpt.line();
 | |
|   }  
 | |
|   while ( (line != "") && (line[0] != '[') )
 | |
|   {
 | |
|     riga = line.get_int();
 | |
|     formato = line.get();
 | |
|     testo   = line.get();
 | |
|     set_footer (riga, (const char *)formato, (const char*)testo);
 | |
|     line = rpt.line();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void AB1100_application::set_translations()
 | |
| {
 | |
|   TString campo, from, to;
 | |
|   TToken_string line;
 | |
|   int   logicnum;
 | |
| 
 | |
|   TScanner rpt(_rptname);
 | |
|   rpt.paragraph("Translations");
 | |
| 
 | |
|   line = rpt.line();
 | |
|   while ( (line != "") && (line[0] != '[') )
 | |
|   {
 | |
|     logicnum = line.get_int();
 | |
|     campo    = line.get();
 | |
|     from     = line.get();
 | |
|     to       = line.get();
 | |
|     set_translation (logicnum, (char*)(const char *)campo, (char*)(const char *)from, (char*)(const char *)to);
 | |
|     line = rpt.line();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void AB1100_application::set_relations()
 | |
| {
 | |
|   TToken_string line("", ';');
 | |
|   TString tab(16), expr(40);
 | |
|   int key, linkto, alias, logicnum;
 | |
| 
 | |
|   TScanner rpt(_rptname);
 | |
|   rpt.paragraph("Relations");
 | |
| 
 | |
|   line = rpt.line();
 | |
|   while ( (line != "") && (line[0] != '[') )
 | |
|   {
 | |
|     tab = line.get();
 | |
|     logicnum = atoi(tab);
 | |
|     expr = line.get();
 | |
|     key = line.get_int();
 | |
|     if (key == 0) key = 1;
 | |
|     linkto = line.get_int();
 | |
|     alias = line.get_int();
 | |
|     if (logicnum > 0)
 | |
|       _rel->add(logicnum, expr, key, linkto, alias);
 | |
|     else
 | |
|       _rel->add(tab, expr, key, linkto, alias);
 | |
|     
 | |
|     line = rpt.line();
 | |
|   }
 | |
| }
 | |
| bool AB1100_application::user_create()
 | |
| {
 | |
|   _tabname = argv(2);
 | |
| 
 | |
|   TString16 t(_tabname);
 | |
| 
 | |
|   _tabella_comune = (t[0] == '%');
 | |
|   if (_tabella_comune)
 | |
|     t.ltrim(1);
 | |
|   
 | |
|   _rptname  << "batb" << t << ".rpt" ;
 | |
|   if (!fexist(_rptname)) 
 | |
|     return error_box("Impossibile aprire il file '%s'", (const char*)_rptname);
 | |
| 
 | |
|   // Flag per la stampa tabella registri
 | |
|   _tabname.upper();
 | |
|   
 | |
|   _rel = new TRelation (_tabname);
 | |
|   _cur = new TCursor (_rel);
 | |
| 
 | |
|   _maskname << "bast" << t;
 | |
|   _msk = new TMask (_maskname) ;
 | |
| 
 | |
|   add_cursor (_cur);
 | |
|   add_file (_tabname);
 | |
| 
 | |
|   _logicnum = _cur->file().num();
 | |
| 
 | |
|   reset_print ();
 | |
| 
 | |
|   printer().footerlen (FOOTER_LEN);
 | |
|   for (int i=1; i <= FOOTER_LEN; i++) set_footer(i, "%s", "  ");
 | |
| 
 | |
| #ifdef DBG1
 | |
|   set_fillchar ('.');
 | |
| #endif
 | |
|   set_relations();
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool AB1100_application::preprocess_print(int file, int counter)
 | |
| {
 | |
|   set_headers();
 | |
|   set_footers();
 | |
|   set_translations();
 | |
|   return TRUE;
 | |
| }                            
 | |
| 
 | |
| bool AB1100_application::user_destroy() 
 | |
| {
 | |
|   delete _msk;
 | |
|   delete _cur;
 | |
|   delete _rel;
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| int ab1100(int argc, char** argv)
 | |
| {
 | |
|   AB1100_application a;
 | |
|   a.run(argc, argv, TR("Stampa tabella"));
 | |
|   return 0;
 | |
| }
 |