gestione posizionamenti e altre modifiche minori.
  printer.h : aggiunto metodo TPrinter.is_generic(), ritorna TRUE se
			  la stampante e' generico/solo testo
  printwin.h,
  printwin.cpp: aggiunto membro TPrintwin._realformlen, modificato il
				costruttore e metodo TPrintwin::paint_row(), per
				correggere il buco di TTY.DRV (mangia una riga...)
  form.h,
  form.cpp : aggiunto metodo TForm::arrange_form() per gestire i
			 posizionamenti; aggiunti i membri _ipy, _ipx, _fpx e _char_to_pos
             aggiunto metodo TForm_string::edit() per disabilitare la gestione
			 del testo fisso. Modificata la TForm_number::update() aggiungendo
			 la possibilita' di specificare la lunghezza della picture in
			 lettere. Rimosso il controllo sulla lunghezza del foglio fisico.
			 Aggiunta la gestione dei nuovi membri su file e su maschera.
git-svn-id: svn://10.65.10.50/trunk@2028 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
	
			
		
			
				
	
	
		
			2733 lines
		
	
	
		
			65 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2733 lines
		
	
	
		
			65 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <ctype.h>
 | 
						||
#include <stdlib.h>     
 | 
						||
 | 
						||
#if XVT_OS == XVT_OS_WIN
 | 
						||
#define STRICT
 | 
						||
#include <windows.h>
 | 
						||
#endif
 | 
						||
 | 
						||
#include <applicat.h>
 | 
						||
#include <form.h>
 | 
						||
#include <msksheet.h>
 | 
						||
#include <printer.h>
 | 
						||
#include <relation.h>
 | 
						||
#include <sheet.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include "../ba/ba2100.h"
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Utility functions
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
// Current form (edit, print)                           
 | 
						||
HIDDEN TForm* _cur_form = NULL;
 | 
						||
 | 
						||
HIDDEN TForm& form()
 | 
						||
{
 | 
						||
  CHECK(_cur_form, "Can't print NULL form");
 | 
						||
  return *_cur_form;
 | 
						||
}
 | 
						||
 | 
						||
// Translate char to pagetype (visible outside here, no more HIDDEN)
 | 
						||
pagetype char2page(char c)
 | 
						||
{  
 | 
						||
  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;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Gestione TFieldref su maschera
 | 
						||
// ID   CAMPO                                       ATTIVO  
 | 
						||
// xx0  Stringa completa del TFieldref                 
 | 
						||
// xx1  Descrizione file 
 | 
						||
// xx2  Bottone selezione file                         X
 | 
						||
// xx3  Descrizione campo
 | 
						||
// xx4  Bottone selezione campo                        X
 | 
						||
// xx5  Primo carattere campo                          X
 | 
						||
// xx6  Ultimo carattere campo                         X
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
HIDDEN void put_fieldref(const TFieldref& fr, TMask_field& f)
 | 
						||
{             
 | 
						||
  TRelation_description& rd = form().rel_desc();
 | 
						||
  rd.set_cur_file(fr.file());
 | 
						||
 | 
						||
  TString80 desc; desc << fr;
 | 
						||
  f.set(desc);
 | 
						||
  
 | 
						||
  TMask& m = f.mask();
 | 
						||
  const short id = f.dlg(); // Campo contenente il TFieldref
 | 
						||
 | 
						||
  m.set(id+1, rd.file_desc());
 | 
						||
  m.set(id+3, rd.get_field_description(fr.name()));
 | 
						||
  m.set(id+5, (fr.from() > 0 || fr.to() > 0) ? fr.from()+1 : 0);
 | 
						||
  m.set(id+6, fr.to() > fr.from() ? fr.to() : 0);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler of F_BUT_FILE field on mask
 | 
						||
HIDDEN bool but_file_handler(TMask_field& f, KEY k)                      
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {                          
 | 
						||
    TRelation_description& r = form().rel_desc();                                   
 | 
						||
    
 | 
						||
    TEdit_field& e = f.mask().efield(f.dlg()-2);
 | 
						||
    TFieldref ref; ref = e.get();
 | 
						||
    if (r.choose_file(ref.file()))
 | 
						||
    {
 | 
						||
      ref.set_file(r.file_num());
 | 
						||
      put_fieldref(ref, e);
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}                      
 | 
						||
 | 
						||
HIDDEN bool but_file_handler_sub(TMask_field& f, KEY k)                      
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {                          
 | 
						||
    TRelation_description& r = form().rel_desc();                                   
 | 
						||
    
 | 
						||
    TEdit_field& e = f.mask().efield(f.dlg()-2);
 | 
						||
    TFieldref ref; ref = e.get();
 | 
						||
    if (r.choose_file(ref.file()))
 | 
						||
    {
 | 
						||
      ref.set_file(r.file_num());
 | 
						||
      f.mask().set(F_FILE1,r.file_desc());  
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}                      
 | 
						||
 | 
						||
 | 
						||
// Handler of F_BUT_FIELD field on mask
 | 
						||
HIDDEN bool but_field_handler(TMask_field& f, KEY k)                      
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {                          
 | 
						||
    TRelation_description& r = form().rel_desc();                                   
 | 
						||
    TEdit_field& e = f.mask().efield(f.dlg()-4);
 | 
						||
    TFieldref ref; ref = e.get();
 | 
						||
    if (r.choose_field(ref.name()))
 | 
						||
    {
 | 
						||
      ref.set_name(r.field_name());
 | 
						||
      put_fieldref(ref, e);
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}                      
 | 
						||
 | 
						||
// Handler of F_FROM field on mask
 | 
						||
HIDDEN bool from_handler(TMask_field& f, KEY k)                      
 | 
						||
{
 | 
						||
  if (f.to_check(k))
 | 
						||
  {
 | 
						||
    TEdit_field& e = f.mask().efield(f.dlg()-5);
 | 
						||
    TFieldref ref; ref = e.get();
 | 
						||
    ref.set_from(atoi(f.get()));
 | 
						||
    put_fieldref(ref, e);
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
// Handler of F_TO field on mask
 | 
						||
HIDDEN bool to_handler(TMask_field& f, KEY k)                      
 | 
						||
{
 | 
						||
  if (f.to_check(k))
 | 
						||
  {
 | 
						||
    TEdit_field& e = f.mask().efield(f.dlg()-6);
 | 
						||
    TFieldref ref; ref = e.get();
 | 
						||
    ref.set_to(atoi(f.get()));
 | 
						||
    put_fieldref(ref, e);
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
HIDDEN bool dateformat_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_SPACE) 
 | 
						||
  {
 | 
						||
    TMask& m = f.mask();
 | 
						||
    
 | 
						||
    char fmt[8]; 
 | 
						||
    fmt[0] = m.get(F_DFORMAT)[0];
 | 
						||
    fmt[1] = m.get(F_DDAY)[0];
 | 
						||
    fmt[2] = m.get(F_DMONTH)[0];
 | 
						||
    fmt[3] = m.get(F_DYEAR)[0];
 | 
						||
    fmt[4] = m.get(F_DSEP)[0];
 | 
						||
    fmt[5] = '\0';
 | 
						||
    
 | 
						||
    const TFormatted_date ex(TODAY, 0, 0, fmt);
 | 
						||
    m.set(F_DEXAMPLE, ex.string());
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_flags
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TForm_flags::TForm_flags()
 | 
						||
{
 | 
						||
  automagic = dirty = 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;
 | 
						||
    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 (s.not_empty()) 
 | 
						||
    out << " FLAGS \"" << s << '"' << endl;
 | 
						||
}
 | 
						||
 | 
						||
// Set mask fields
 | 
						||
// Certified 100%
 | 
						||
void TForm_flags::print_on(TMask& m)
 | 
						||
{
 | 
						||
  m.set(F_DISABLED,  enabled   ? " " : "X");
 | 
						||
  m.set(F_HIDDEN,    shown     ? " " : "X");
 | 
						||
  m.set(F_AUTOMAGIC, automagic ? "X" : " ");
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Get mask fields
 | 
						||
// Certified 100%
 | 
						||
void TForm_flags::read_from(const TMask& m)
 | 
						||
{
 | 
						||
  shown     = !m.get_bool(F_HIDDEN);
 | 
						||
  enabled   = !m.get_bool(F_DISABLED);
 | 
						||
  automagic = m.get_bool(F_AUTOMAGIC);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_item
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
 | 
						||
TForm_item::TForm_item(TPrint_section* section)
 | 
						||
: _section(section), _x(-1), _y(-1), _width(0), _height(0), _id(0)
 | 
						||
{}
 | 
						||
 | 
						||
 | 
						||
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;
 | 
						||
  } 
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
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();
 | 
						||
    if (!m.blank())
 | 
						||
      message(0).add(m);
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (scanner.key() == "KE")
 | 
						||
  {                    
 | 
						||
    _desc = scanner.string();
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  if (scanner.key() == "GR")
 | 
						||
  {
 | 
						||
    _group.set(scanner.line());
 | 
						||
    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;
 | 
						||
  }
 | 
						||
 | 
						||
  const bool s = prof.get_bool("ATTIVO");
 | 
						||
  if (_flag.shown != s)
 | 
						||
  {
 | 
						||
    _flag.shown = s;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
  
 | 
						||
  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());
 | 
						||
  prof.put("ATTIVO", shown() ? "X" : " ");
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::enable(bool on)
 | 
						||
{
 | 
						||
  _flag.enabled = on;
 | 
						||
  show(on);
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::string_at(int x, int y, const char* s)
 | 
						||
{
 | 
						||
  if (shown())
 | 
						||
  {
 | 
						||
    section().offset(x, y);
 | 
						||
    TPrintrow& row = section().row(y-1);         // Seleziona riga di stampa
 | 
						||
 | 
						||
    if (_width > 0 && strlen(s) > (word)_width)  // Tronca testo se necessario
 | 
						||
    {
 | 
						||
      strncpy(__tmp_string, s, width());
 | 
						||
      __tmp_string[_width] = '\0';
 | 
						||
      s = __tmp_string;
 | 
						||
    }
 | 
						||
    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;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TForm_item::send_message(const TString& cmd, TForm_item& des) const
 | 
						||
{
 | 
						||
  if (cmd == "ADD" || cmd == "INC")
 | 
						||
  {
 | 
						||
    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 == "DISABLE")
 | 
						||
        {
 | 
						||
          des.disable();
 | 
						||
        } else
 | 
						||
          if (cmd == "ENABLE")
 | 
						||
          {
 | 
						||
            des.enable();
 | 
						||
          } else
 | 
						||
            if (cmd == "HIDE")
 | 
						||
            {
 | 
						||
              des.hide();
 | 
						||
            } else
 | 
						||
              if (cmd == "RESET")
 | 
						||
              {
 | 
						||
                des.set("");
 | 
						||
              } else        
 | 
						||
                if (cmd == "SHOW")
 | 
						||
                {
 | 
						||
                  des.show();
 | 
						||
                } 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 pagetype pt = (id[1] == '-') ? section().page_type() : char2page(id[1]);
 | 
						||
  const int freccia = id.find("->");
 | 
						||
  CHECKS(freccia > 0, "Non trovo la freccia nel campo ", (const char*)id);
 | 
						||
  TForm_item& des = form().find_field(id[0], pt, atoi(id.mid(freccia+2)));
 | 
						||
  return des;
 | 
						||
}
 | 
						||
 | 
						||
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 TString16 cmd(msg.get());      // Get command
 | 
						||
      const TString16 id = msg.get();      // Get destination
 | 
						||
 | 
						||
      if (id.right(1) == "@")
 | 
						||
      {
 | 
						||
        const word group = atoi(id);
 | 
						||
        // Send the message to all fields with the given group
 | 
						||
        for (word i = 0; i < section().fields(); i++)
 | 
						||
        {
 | 
						||
          TForm_item& des = section().field(i);
 | 
						||
          if (des.in_group(group))
 | 
						||
            send_message(cmd, des);
 | 
						||
        }
 | 
						||
      }  
 | 
						||
      else
 | 
						||
      {                  
 | 
						||
        TForm_item& des = find_field(id);
 | 
						||
        send_message(cmd, des);
 | 
						||
      }
 | 
						||
    }  
 | 
						||
  }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_item::update()
 | 
						||
{ 
 | 
						||
  if (_prompt.right(1) == "#")
 | 
						||
  {   
 | 
						||
    TString prompt(_prompt);
 | 
						||
    for (int 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);
 | 
						||
  
 | 
						||
  do_message();
 | 
						||
  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(" ");
 | 
						||
  }  
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::print_on(TMask& m)
 | 
						||
{
 | 
						||
  m.set(F_CLASS, class_name());
 | 
						||
  m.set(F_ID, id());
 | 
						||
  m.set(F_KEY, key());
 | 
						||
  m.set(F_X, _x);
 | 
						||
  m.set(F_Y, _y);
 | 
						||
  m.set(F_PROMPT, _prompt);
 | 
						||
  m.set(F_WIDTH, _width);
 | 
						||
  m.set(F_HEIGHT, _height);  
 | 
						||
  
 | 
						||
  _flag.print_on(m);
 | 
						||
  
 | 
						||
  for (int g = 1; g <= 24; g++)      
 | 
						||
    m.set(F_GROUP+g, _group[g] ? "X" : " ");
 | 
						||
}
 | 
						||
 | 
						||
void TForm_item::read_from(const TMask& m)
 | 
						||
{
 | 
						||
  _desc = m.get(F_KEY);
 | 
						||
  _x = atoi(m.get(F_X));
 | 
						||
  _y = atoi(m.get(F_Y));
 | 
						||
  _prompt = m.get(F_PROMPT);
 | 
						||
  _width = atoi(m.get(F_WIDTH));
 | 
						||
  _height = atoi(m.get(F_HEIGHT));
 | 
						||
  _id     = atoi(m.get(F_ID)); 
 | 
						||
 | 
						||
  _flag.read_from(m);
 | 
						||
  
 | 
						||
  _group.reset();
 | 
						||
  for (int g = 1; g <= 24; g++)      
 | 
						||
    _group.set(g, m.get_bool(F_GROUP+g));
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_item::edit(TMask& m)
 | 
						||
{
 | 
						||
  m.enable(F_CLASS, m.insert_mode()); 
 | 
						||
  
 | 
						||
  m.reset();  
 | 
						||
 | 
						||
  if (m.insert_mode())
 | 
						||
  {   
 | 
						||
    short id = 0;
 | 
						||
    for (word i = 0; i < section().fields(); i++)
 | 
						||
    {            
 | 
						||
      const TForm_item& f = section().field(i);
 | 
						||
      if (f.id() > id) id = f.id();
 | 
						||
    }                              
 | 
						||
    _id = id+1;
 | 
						||
  }
 | 
						||
  
 | 
						||
  print_on(m);
 | 
						||
  
 | 
						||
  const bool godmode = form().edit_level() > 1;
 | 
						||
  m.enable_page(1, godmode);
 | 
						||
  m.enable(-7, godmode);
 | 
						||
  m.enable(F_ID, godmode);
 | 
						||
  
 | 
						||
  const bool dirty = m.run() == K_ENTER; 
 | 
						||
  if (dirty) 
 | 
						||
  {
 | 
						||
    read_from(m);
 | 
						||
    set_dirty();
 | 
						||
  }
 | 
						||
  return dirty;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_subsection
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TForm_subsection : public TForm_item
 | 
						||
{  
 | 
						||
  TPrint_section _ssec;
 | 
						||
  TString _name;
 | 
						||
 | 
						||
  int _file_id;      // ID del file su cui iterare in stampa se previsto
 | 
						||
 | 
						||
protected:
 | 
						||
  virtual void print_on(ostream& out) const; 
 | 
						||
 | 
						||
public:
 | 
						||
 | 
						||
  virtual bool parse(TScanner& s);
 | 
						||
  virtual bool update();  
 | 
						||
  virtual bool edit(TMask& m);
 | 
						||
  
 | 
						||
  virtual const char* class_name() const { return "SEZIONE"; }
 | 
						||
  
 | 
						||
  TPrint_section& subsection()  { return _ssec; }
 | 
						||
 | 
						||
  virtual void show(bool on = TRUE);
 | 
						||
  virtual void enable(bool on = TRUE);
 | 
						||
  void hide()    { show(FALSE);   }
 | 
						||
  void disable() { enable(FALSE); }
 | 
						||
 | 
						||
  void name(const char* s) { _name = s; _desc << "Sottosezione " << s; }
 | 
						||
  const char* name() const { return _name; }
 | 
						||
 | 
						||
  TForm_subsection(TPrint_section* section, const char* name = "");
 | 
						||
  virtual ~TForm_subsection() {}
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
TForm_subsection::TForm_subsection(TPrint_section* s, const char* nm) :
 | 
						||
TForm_item(s), _ssec(&(s->form()), s->section_type(), s->page_type(), TRUE), _file_id(-1), _name(nm)
 | 
						||
{}
 | 
						||
 | 
						||
 | 
						||
bool TForm_subsection::parse(TScanner& s)
 | 
						||
{ 
 | 
						||
  name(s.pop()); 
 | 
						||
  _width  = s.integer();
 | 
						||
  _height = s.integer();
 | 
						||
  _x      = s.integer();    
 | 
						||
  _y      = s.integer();    
 | 
						||
  
 | 
						||
  if (s.popkey() == "FI")     // FILE su cui iterare con next_match
 | 
						||
    _file_id = s.integer();   // TBI controllo alias
 | 
						||
  else s.push();
 | 
						||
  
 | 
						||
  return _ssec.parse(s); 
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_subsection::update()
 | 
						||
{    
 | 
						||
  bool ok = FALSE;
 | 
						||
  TRelation* rel = form().relation();
 | 
						||
  
 | 
						||
  if (rel == NULL || _file_id == -1)
 | 
						||
    ok = _ssec.update();
 | 
						||
  else
 | 
						||
  { 
 | 
						||
    int i = 0; 
 | 
						||
    if (rel->is_first_match(_file_id)) 
 | 
						||
      do {
 | 
						||
        if (!(ok = _ssec.update()))
 | 
						||
          break;   
 | 
						||
        _ssec.set_repeat_count(++i);
 | 
						||
      } 
 | 
						||
    while (rel->next_match(_file_id));
 | 
						||
    _ssec.set_repeat_count(0);
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
bool TForm_subsection::edit(TMask& m)
 | 
						||
{             
 | 
						||
  // mask con nome e bottone edit contents / annulla
 | 
						||
  TMask mu("ba2100u");     
 | 
						||
  mu.set(F_CAPTION, _name);
 | 
						||
  mu.set(F_WIDTH,   _width);
 | 
						||
  mu.set(F_HEIGHT,  _height); 
 | 
						||
  mu.set(F_X,       _x);
 | 
						||
  mu.set(F_Y,       _y);
 | 
						||
  
 | 
						||
  mu.set_handler(F_BUT_FILE1, but_file_handler_sub);
 | 
						||
  
 | 
						||
  if (_file_id != -1)
 | 
						||
  {
 | 
						||
    // set file description  
 | 
						||
    form().rel_desc().set_cur_file(_file_id);
 | 
						||
    TString80 desc; desc << form().rel_desc().file_desc();
 | 
						||
    mu.set(F_FILE1, desc);
 | 
						||
  }
 | 
						||
  
 | 
						||
  KEY k; 
 | 
						||
  
 | 
						||
  // vedere se e' nuova etc. 
 | 
						||
  // gestire aggiunta / modifica menu    
 | 
						||
  
 | 
						||
  while ((k = mu.run()) != K_ESC)
 | 
						||
  {  
 | 
						||
    if (mu.field(F_CAPTION).dirty())
 | 
						||
      _name = mu.get(F_CAPTION);
 | 
						||
    
 | 
						||
    if (mu.field(F_WIDTH).dirty())
 | 
						||
      _width = mu.get_int(F_WIDTH);
 | 
						||
    
 | 
						||
    if (mu.field(F_HEIGHT).dirty())
 | 
						||
      _height = mu.get_int(F_HEIGHT);
 | 
						||
    
 | 
						||
    if (mu.field(F_X).dirty())
 | 
						||
      _x = mu.get_int(F_X);
 | 
						||
    
 | 
						||
    if (mu.field(F_Y).dirty())
 | 
						||
      _y = mu.get_int(F_Y);
 | 
						||
    
 | 
						||
    if (mu.field(F_FILE1).dirty())
 | 
						||
    {
 | 
						||
      if (mu.get(F_FILE1).empty())
 | 
						||
        _file_id = -1;
 | 
						||
      else
 | 
						||
        _file_id = form().rel_desc().file_num();
 | 
						||
    }
 | 
						||
    
 | 
						||
    if (k == K_INS)
 | 
						||
      _ssec.edit(_name); 
 | 
						||
    else if (k == K_DEL)
 | 
						||
    { 
 | 
						||
      // remove myself
 | 
						||
      
 | 
						||
    }
 | 
						||
    else if (k == K_ENTER)
 | 
						||
      break;    
 | 
						||
  }
 | 
						||
 | 
						||
  return k != K_ESC;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TForm_subsection::print_on(ostream& out) const 
 | 
						||
{ 
 | 
						||
  out << "SEZIONE " << _name << ' ' << _width << ' ' << _height 
 | 
						||
    << ' ' << _x << ' ' << _y;
 | 
						||
  
 | 
						||
  if (_file_id != -1)
 | 
						||
    out << " FILE " << _file_id;
 | 
						||
  out << "\n";
 | 
						||
 | 
						||
  for (word i = 0; i < _ssec.fields(); i++)
 | 
						||
    out << _ssec.field(i);
 | 
						||
  out << "\nEND" << "\n";
 | 
						||
}
 | 
						||
 | 
						||
// ???
 | 
						||
void TForm_subsection::show(bool on)
 | 
						||
{
 | 
						||
  for (unsigned int i = 0; i < _ssec.fields(); i++)
 | 
						||
    _ssec.field(i).show(on);
 | 
						||
}
 | 
						||
 | 
						||
// ???
 | 
						||
void TForm_subsection::enable(bool on)
 | 
						||
{
 | 
						||
  for (unsigned int i = 0; i < _ssec.fields(); i++)
 | 
						||
    _ssec.field(i).enable(on);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm_string
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TForm_string : public TForm_item
 | 
						||
{
 | 
						||
  TString _str, _picture;
 | 
						||
  TArray _field;
 | 
						||
 | 
						||
protected:
 | 
						||
  virtual const char* class_name() const { return "STRINGA"; }
 | 
						||
  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);
 | 
						||
 | 
						||
  virtual void print_on(TToken_string& row) const;
 | 
						||
 | 
						||
  virtual bool parse_item(TScanner&);
 | 
						||
  virtual bool read();
 | 
						||
  virtual bool update();
 | 
						||
 | 
						||
  virtual const char* get() const;
 | 
						||
  bool set(const char*);
 | 
						||
 | 
						||
  const TString& picture() const { return _picture; }
 | 
						||
 | 
						||
  TFieldref& field(int i) const { return (TFieldref&)_field[i]; }
 | 
						||
  void put_paragraph(const char* s);
 | 
						||
 | 
						||
public:
 | 
						||
  virtual bool edit(TMask& m); 
 | 
						||
  TForm_string(TPrint_section* section) : TForm_item(section) {}
 | 
						||
  virtual ~TForm_string() {}
 | 
						||
};
 | 
						||
 | 
						||
bool TForm_string::edit(TMask& m)
 | 
						||
{ 
 | 
						||
  const bool godmode = form().edit_level() > 1;
 | 
						||
  m.enable(F_PROMPT, godmode ? TRUE : (_field.items()==0));
 | 
						||
  return TForm_item::edit(m);
 | 
						||
}                                 
 | 
						||
 | 
						||
bool TForm_string::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (scanner.key() == "FI")
 | 
						||
  {
 | 
						||
    TFieldref* fr = new TFieldref(scanner.line(), 0);
 | 
						||
    _field.add(fr);        
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  if (scanner.key() == "PI")
 | 
						||
  {
 | 
						||
    _picture = scanner.string();
 | 
						||
    return TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  return TForm_item::parse_item(scanner);
 | 
						||
}
 | 
						||
 | 
						||
void TForm_string::print_body(ostream& out) const
 | 
						||
{
 | 
						||
  TForm_item::print_body(out);
 | 
						||
  if (_picture.not_empty())
 | 
						||
    out << " PICTURE \"" << _picture << "\"" << endl;
 | 
						||
  for (int i = 0; i < _field.items(); i++)
 | 
						||
    out << " FIELD " << field(i) << endl;
 | 
						||
}  
 | 
						||
 | 
						||
bool TForm_string::read_from(const TRectype& prof)
 | 
						||
{ 
 | 
						||
  bool changed = TForm_item::read_from(prof);
 | 
						||
 | 
						||
  const TString& pict = prof.get("PICT");
 | 
						||
  if (_picture != pict)
 | 
						||
  {
 | 
						||
    _picture = pict;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
 | 
						||
  return changed;
 | 
						||
}
 | 
						||
 | 
						||
void TForm_string::print_on(TToken_string& row) const
 | 
						||
{
 | 
						||
  TForm_item::print_on(row);  
 | 
						||
  if (_field.items() && form().edit_level() > 1)
 | 
						||
    row << '|' << field(0);
 | 
						||
}
 | 
						||
 | 
						||
void TForm_string::print_on(TRectype& prof)
 | 
						||
{
 | 
						||
  TForm_item::print_on(prof);
 | 
						||
  prof.put("PICT", _picture);
 | 
						||
}
 | 
						||
 | 
						||
void TForm_string::print_on(TMask& m)
 | 
						||
{
 | 
						||
  TForm_item::print_on(m);
 | 
						||
  for (int i = 0; i < _field.items(); i++)
 | 
						||
    put_fieldref(field(i), m.field(i == 0 ? F_FIELDREF1 : F_FIELDREF2));
 | 
						||
  
 | 
						||
  m.set(F_PICTURE, _picture);
 | 
						||
  
 | 
						||
  TSheet_field& s = (TSheet_field&)m.field(F_ITEMS);
 | 
						||
  s.reset();
 | 
						||
  if (_message.items() > 0)
 | 
						||
  {
 | 
						||
    TToken_string& row = s.row(0);
 | 
						||
    row = " | ";
 | 
						||
    row.add(message(0));
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TForm_string::read_from(const TMask& m)
 | 
						||
{
 | 
						||
  TForm_item::read_from(m);
 | 
						||
  _picture = m.get(F_PICTURE);
 | 
						||
  
 | 
						||
  for (int i = 0; i < 2; i++)
 | 
						||
  {
 | 
						||
    const TString& f = m.get(i == 0 ? F_FIELDREF1 : F_FIELDREF2);
 | 
						||
    if (f.not_empty())
 | 
						||
    {
 | 
						||
      TFieldref* fr = (TFieldref*)_field.objptr(i);
 | 
						||
      if (fr == NULL) 
 | 
						||
      {
 | 
						||
        fr = new TFieldref(f, 0);
 | 
						||
        _field.add(fr, i);
 | 
						||
      }
 | 
						||
      *fr = f;
 | 
						||
    }  
 | 
						||
    else
 | 
						||
      _field.destroy(i);                  
 | 
						||
  }  
 | 
						||
  
 | 
						||
  TSheet_field& f = (TSheet_field&)m.field(F_ITEMS);
 | 
						||
  TToken_string& msg = f.row(0);
 | 
						||
  if (msg.empty_items())
 | 
						||
    _message.destroy(0);
 | 
						||
  else
 | 
						||
    _message.add(msg.get(2), 0);
 | 
						||
}
 | 
						||
 | 
						||
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 = form().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;
 | 
						||
 | 
						||
  if (height() > 1)
 | 
						||
  {
 | 
						||
    TParagraph_string p(s, width());
 | 
						||
    int i = _prompt.not_empty() ? 1 : 0;
 | 
						||
    for (; (s = p.get()) != NULL && i < height(); i++)
 | 
						||
      string_at(_x, _y+i, s);
 | 
						||
  }
 | 
						||
  else string_at(-1, _y, s);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_string::update()
 | 
						||
{
 | 
						||
  if (read())
 | 
						||
  {
 | 
						||
    TForm_item::update();
 | 
						||
    if (!picture().blank())
 | 
						||
    {           
 | 
						||
      TToken_string delim(4, ',');         // Stringa con i due delimitatori
 | 
						||
      const char* pic = picture();         // Picture senza delimitatori
 | 
						||
      
 | 
						||
      if (pic[0] == '(')                   // Se ci sono i delimitatori ...
 | 
						||
      {
 | 
						||
        const int bra = picture().find(')'); 
 | 
						||
        if (bra > 0)                       // ... cerca la parentesi chiusa
 | 
						||
        {
 | 
						||
          delim = picture().sub(1, bra);   // memorizza delimitatori
 | 
						||
          pic += bra+1;                    // toglili dalla picture
 | 
						||
        }  
 | 
						||
      }
 | 
						||
      
 | 
						||
      TString80 s;
 | 
						||
      s.picture(pic, get());               // riempi la stringa col valore pitturato
 | 
						||
 | 
						||
      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 ...
 | 
						||
        {
 | 
						||
          for (int 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
 | 
						||
      }  
 | 
						||
      put_paragraph(s);
 | 
						||
    } 
 | 
						||
    else 
 | 
						||
      put_paragraph(get());                // Stampa immediata senza picture
 | 
						||
  }        
 | 
						||
  
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// 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();
 | 
						||
  virtual int height() const { return 0; }
 | 
						||
 | 
						||
protected:  
 | 
						||
  int decimals() const { return _height; }
 | 
						||
 | 
						||
public:
 | 
						||
  TForm_number(TPrint_section* section) : TForm_string(section) {}
 | 
						||
  virtual ~TForm_number() {}
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
bool TForm_number::parse_head(TScanner& scanner)
 | 
						||
{                         
 | 
						||
  TForm_item::parse_head(scanner);
 | 
						||
  _height = _width;                      // Decimals
 | 
						||
  _width  = 0;
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm_number::update()
 | 
						||
{
 | 
						||
  if (read())
 | 
						||
  {
 | 
						||
    TForm_item::update();
 | 
						||
 | 
						||
    real n(get());
 | 
						||
    n.round(decimals());
 | 
						||
    
 | 
						||
    if (!n.is_zero())
 | 
						||
    {
 | 
						||
      if (!picture().blank())
 | 
						||
      {           
 | 
						||
        TToken_string delim(4, ',');         // Stringa con i due delimitatori
 | 
						||
        TString pic(picture());              // Picture senza delimitatori
 | 
						||
        int maxlen = -1;                     
 | 
						||
        int at = pic.find('@');
 | 
						||
        if (at >= 0)       
 | 
						||
        {
 | 
						||
          maxlen = atoi(&pic[at+1]);
 | 
						||
          pic.cut(at);
 | 
						||
        }
 | 
						||
        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
 | 
						||
          }  
 | 
						||
        }
 | 
						||
        
 | 
						||
        TString80 s(n.string(pic));          // riempi la stringa col valore pitturato
 | 
						||
        
 | 
						||
        if (maxlen >= 0)
 | 
						||
          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 ...
 | 
						||
          {
 | 
						||
            for (int 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
 | 
						||
        }  
 | 
						||
        put_paragraph(s);
 | 
						||
      } 
 | 
						||
      else 
 | 
						||
        put_paragraph(n.string());
 | 
						||
    }    
 | 
						||
  }
 | 
						||
  
 | 
						||
  return TRUE;  
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// 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 bool edit(TMask& m);
 | 
						||
  TForm_date(TPrint_section* section);
 | 
						||
  virtual ~TForm_date() {}
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
TForm_date::TForm_date(TPrint_section* section) 
 | 
						||
: TForm_string(section), _format("1444-")
 | 
						||
{}
 | 
						||
 | 
						||
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::read_from(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 TFormatted_date d(TODAY, 0, 0, _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);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// 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:
 | 
						||
  TForm_list(TPrint_section* section);
 | 
						||
  virtual ~TForm_list() {}
 | 
						||
};
 | 
						||
 | 
						||
TForm_list::TForm_list(TPrint_section* section)
 | 
						||
: TForm_string(section)
 | 
						||
{}
 | 
						||
 | 
						||
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("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() {}
 | 
						||
};
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TPrint_section
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
HIDDEN bool font_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_SPACE)
 | 
						||
  {                
 | 
						||
    main_app().begin_wait();           
 | 
						||
 | 
						||
    const char* family = f.get();
 | 
						||
    const int MAXSIZES = 16;
 | 
						||
    long sizes[MAXSIZES]; 
 | 
						||
    BOOLEAN scalable;
 | 
						||
    const int num_sizes = (int)xvt_fmap_get_family_sizes(printer().get_printrcd(), 
 | 
						||
                                                         (char*)family, sizes, &scalable, MAXSIZES);
 | 
						||
    
 | 
						||
    TToken_string pn1(80), pn2(80);                                                    
 | 
						||
    if (scalable)
 | 
						||
    {
 | 
						||
      for (int i = 4; i <= 32; i++)
 | 
						||
      {
 | 
						||
        pn1.add(i);
 | 
						||
        pn2.add(i);
 | 
						||
      }               
 | 
						||
    }  
 | 
						||
    else                           
 | 
						||
    {
 | 
						||
      if (num_sizes > 0)
 | 
						||
      {
 | 
						||
        for (int i = 0; i < num_sizes; i++)
 | 
						||
          pn1.add(sizes[i]);
 | 
						||
      }
 | 
						||
      else pn1.add(printer().get_char_size());
 | 
						||
      pn2 = pn1;
 | 
						||
    }
 | 
						||
    TList_field& lst = (TList_field&)f.mask().field(F_SIZE);
 | 
						||
    lst.replace_items(pn1, pn2);
 | 
						||
    lst.set(format("%d",printer().get_char_size()));
 | 
						||
    
 | 
						||
    main_app().end_wait();           
 | 
						||
  }   
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
TMask* TPrint_section::_msk = NULL;
 | 
						||
 | 
						||
TPrint_section::TPrint_section(TForm* f, char st, pagetype pt, bool sub) 
 | 
						||
: _height(0), _form(f), _sec_type(st), _page_type(pt), _dirty(FALSE),
 | 
						||
  _subsection(sub), _repeat_count(0)
 | 
						||
{}
 | 
						||
 | 
						||
TPrint_section::~TPrint_section()
 | 
						||
{
 | 
						||
  if (_msk) 
 | 
						||
  {
 | 
						||
    delete _msk;
 | 
						||
    _msk = NULL;
 | 
						||
  }  
 | 
						||
}
 | 
						||
 | 
						||
const TPrint_section& TPrint_section::copy(const TPrint_section& ps)
 | 
						||
{
 | 
						||
  _item = ps._item;
 | 
						||
  _height = ps._height;
 | 
						||
  return ps;
 | 
						||
}
 | 
						||
 | 
						||
TPrintrow& TPrint_section::row(int num)
 | 
						||
{
 | 
						||
  TPrintrow* pr = (TPrintrow*)objptr(num);
 | 
						||
  if (pr == NULL)
 | 
						||
  {
 | 
						||
    pr = new TPrintrow;
 | 
						||
    add(pr, num);
 | 
						||
  }
 | 
						||
  return *pr;
 | 
						||
}
 | 
						||
 | 
						||
void TPrint_section::offset(int& x, int& y) const
 | 
						||
{                          
 | 
						||
  if (x >= 0) x += form().offset_x();
 | 
						||
  if (y >= 0) y += form().offset_y() + (_height * _repeat_count);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TForm_item* TPrint_section::parse_item(const TString& s)
 | 
						||
{
 | 
						||
  if (s == "ST")
 | 
						||
    return new TForm_string(this);
 | 
						||
  if (s == "NU")
 | 
						||
    return new TForm_number(this);
 | 
						||
  if (s == "DA")
 | 
						||
    return new TForm_date(this);
 | 
						||
  if (s == "LI")
 | 
						||
    return new TForm_list(this);
 | 
						||
  if (s == "GR")
 | 
						||
    return new TForm_group(this);
 | 
						||
  if (s == "SE")
 | 
						||
    return new TForm_subsection(this); 
 | 
						||
  
 | 
						||
  yesnofatal_box("Campo di stampa non ammesso per la sezione di stampa: %s", (const char*)s);
 | 
						||
  return NULL;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TForm_item* TPrint_section::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  return parse_item(scanner.key());
 | 
						||
}
 | 
						||
 | 
						||
bool TPrint_section::parse(TScanner& scanner)
 | 
						||
{
 | 
						||
  _height = scanner.integer();  
 | 
						||
  scanner.integer();scanner.integer(); // Eat offset X and Y of Print_section if present
 | 
						||
 | 
						||
  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;
 | 
						||
}
 | 
						||
 | 
						||
// Azzera tutte le righe della sezione di stampa
 | 
						||
void TPrint_section::reset()
 | 
						||
{
 | 
						||
  for (word i = 0; i < height(); i++)
 | 
						||
    row(i).reset();
 | 
						||
}
 | 
						||
 | 
						||
// Aggiorna tutti i campi e li stampa
 | 
						||
bool TPrint_section::update()
 | 
						||
{
 | 
						||
  bool ok = TRUE;
 | 
						||
  
 | 
						||
  reset();
 | 
						||
  for (word i = 0; i < fields(); i++)
 | 
						||
  {
 | 
						||
    const bool esito = field(i).update();
 | 
						||
    if (!esito) ok = FALSE;
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
} 
 | 
						||
 | 
						||
bool TPrint_section::read_from(const TRectype& prof)
 | 
						||
{
 | 
						||
  CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
 | 
						||
  
 | 
						||
  bool changed = FALSE;
 | 
						||
  const word h = (word)prof.get_int("HGT");
 | 
						||
  if (_height != h) 
 | 
						||
  {
 | 
						||
    _height = h;
 | 
						||
    changed = TRUE;
 | 
						||
  }
 | 
						||
  return changed;
 | 
						||
}
 | 
						||
 | 
						||
void TPrint_section::print_on(TRectype& prof)
 | 
						||
{
 | 
						||
  CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
 | 
						||
  prof.put("ID", 0);
 | 
						||
  prof.put("X", 0);
 | 
						||
  prof.put("Y", 0);
 | 
						||
  prof.put("HGT", _height);
 | 
						||
}
 | 
						||
 | 
						||
typedef struct {
 | 
						||
  char name_1[80];  // Fontname old
 | 
						||
  char name_2[80];  // Fontname new
 | 
						||
  int  size_1;      // size (height) of old font
 | 
						||
  int  size_2;      // size (height) of new font
 | 
						||
  double ratio;     // ratio (width_old_font/width_new_font)
 | 
						||
} s_data;                
 | 
						||
 | 
						||
BOOLEAN XVT_CALLCONV1 wpr (long data)
 | 
						||
{                        
 | 
						||
  s_data* st =(s_data*)data;
 | 
						||
  WINDOW prwin = xvt_print_create_win(printer().get_printrcd(),"");
 | 
						||
  long width_old,width_new;
 | 
						||
  TString spc(100);
 | 
						||
  spc.fill('m');
 | 
						||
  xvt_set_font(prwin,st->name_1, XVT_FS_NONE, st->size_1);  
 | 
						||
  width_old = xvt_dwin_get_text_width(prwin,(char*)(const char*)spc, 100);
 | 
						||
  xvt_set_font(prwin,st->name_2, XVT_FS_NONE, st->size_2);  
 | 
						||
  width_new = xvt_dwin_get_text_width(prwin,(char*)(const char*)spc, 100);
 | 
						||
  st->ratio = (double)width_old / (double)width_new;
 | 
						||
  xvt_vobj_destroy(prwin);
 | 
						||
 | 
						||
  return FALSE;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrint_section::edit(const char* title)
 | 
						||
{                        
 | 
						||
  _cur_form = _form;
 | 
						||
 | 
						||
  if (!_subsection)
 | 
						||
  {
 | 
						||
    TMask m("ba2100s");  
 | 
						||
    m.set_caption(title);
 | 
						||
    m.set(F_HEIGHT, _height);
 | 
						||
    m.set(F_X, form().offset_x());
 | 
						||
    m.set(F_Y, form().offset_y());
 | 
						||
    m.set(F_CTP, format("%c",form().char_to_pos()));
 | 
						||
    m.set(F_IPX, form().ipx());
 | 
						||
    m.set(F_IPY, form().ipy());
 | 
						||
    m.set(F_FPX, form().fpx());
 | 
						||
    m.set(F_FLEN, printer().formlen());
 | 
						||
    
 | 
						||
  {
 | 
						||
    const int MAX_FAMILIES = 128;
 | 
						||
    char* family[MAX_FAMILIES];
 | 
						||
    const int num_families = (int)xvt_fmap_get_families(printer().get_printrcd(), family, MAX_FAMILIES);
 | 
						||
    bool  font_found = FALSE;
 | 
						||
    TToken_string pn1(256), pn2(256);                                                    
 | 
						||
 | 
						||
    for (int i = 0; i < num_families; i++)
 | 
						||
    {
 | 
						||
      pn1.add(family[i]);
 | 
						||
      pn2.add(family[i]);
 | 
						||
      if (!font_found) 
 | 
						||
        if (form().fontname() == family[i]) font_found = TRUE;
 | 
						||
      xvt_mem_free(family[i]);
 | 
						||
    }  
 | 
						||
    TList_field& lst = (TList_field&)m.field(F_FONT);
 | 
						||
    lst.replace_items(pn1, pn2);
 | 
						||
    if (!font_found) warning_box("Il font %s non esiste per la stampante di default.",(const char*) form().fontname());  
 | 
						||
    lst.set(form().fontname());
 | 
						||
  }
 | 
						||
    printer().set_char_size(form().fontsize());
 | 
						||
    m.set_handler(F_FONT,font_handler);
 | 
						||
    if (m.run() == K_ESC)
 | 
						||
      return FALSE;
 | 
						||
 | 
						||
    bool dirty = m.dirty() != 0; 
 | 
						||
    
 | 
						||
    if (dirty)
 | 
						||
    {
 | 
						||
      if (_height != (word)m.get_int(F_HEIGHT) )
 | 
						||
      {
 | 
						||
        _height = m.get_int(F_HEIGHT);
 | 
						||
        _dirty=TRUE;
 | 
						||
      }
 | 
						||
      if (m.get_int(F_X) != form().offset_x() || m.get_int(F_Y) != form().offset_y())
 | 
						||
      {
 | 
						||
        form().offset_x() = m.get_int(F_X);
 | 
						||
        form().offset_y() = m.get_int(F_Y);
 | 
						||
        form().set_dirty();
 | 
						||
        _dirty = TRUE;
 | 
						||
      }                                         
 | 
						||
      if (m.get(F_CTP)[0] != form().char_to_pos())
 | 
						||
      {               
 | 
						||
        form().char_to_pos() = m.get(F_CTP)[0];
 | 
						||
        form().ipx() = m.get_int(F_IPX);
 | 
						||
        form().ipy() = m.get_int(F_IPY);
 | 
						||
        form().fpx() = m.get_int(F_FPX);
 | 
						||
        _dirty = TRUE;
 | 
						||
      }
 | 
						||
      
 | 
						||
      TString80 name(m.get(F_FONT));
 | 
						||
      int size = m.get_int(F_SIZE);
 | 
						||
      if (name != form().fontname() || size != form().fontsize())
 | 
						||
      {   
 | 
						||
        if (!form().dirty()) form().set_dirty();
 | 
						||
        _dirty = TRUE;
 | 
						||
        s_data  prm;
 | 
						||
        prm.size_1=form().fontsize();
 | 
						||
        strcpy(prm.name_1,form().fontname());
 | 
						||
        prm.size_2=size;
 | 
						||
        strcpy(prm.name_2,name);
 | 
						||
        prm.ratio = 1.0;
 | 
						||
        // Next 3 lines may be changed
 | 
						||
        xvt_print_open();
 | 
						||
        xvt_print_start_thread (wpr, (long)&prm); 
 | 
						||
        xvt_print_close();
 | 
						||
 | 
						||
        form().fontname() = name;
 | 
						||
        form().fontsize() = size;                   
 | 
						||
        const char sechar[4] = { 'B', 'F', 'G',  'H' };
 | 
						||
        for (int sn = 0; sn < 4 ; sn++) 
 | 
						||
        {
 | 
						||
          const char sc = sechar[sn];
 | 
						||
          for (pagetype pt = odd_page; pt <= last_page; pt = pagetype(pt+1))
 | 
						||
          {            
 | 
						||
            TPrint_section* sec = form().exist(sc, pt);
 | 
						||
            if (sec != NULL)
 | 
						||
            { 
 | 
						||
              sec->set_dirty();                       
 | 
						||
              for (word i = 0; i < sec->fields() ; i++)
 | 
						||
              {
 | 
						||
                TForm_item& fi = sec->field(i);
 | 
						||
                if (fi.x() > 0 && (prm.ratio != 1.0))
 | 
						||
                {
 | 
						||
                  real x_pos;
 | 
						||
                  x_pos = fi.x() * prm.ratio;
 | 
						||
                  x_pos.round();
 | 
						||
                  fi.x() = (short)x_pos.integer();
 | 
						||
                  fi.set_dirty();
 | 
						||
                }
 | 
						||
              }
 | 
						||
            }
 | 
						||
          }    
 | 
						||
        }  
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  const word flags = 0x08 | (form().edit_level() > 1 ? 0x06 : 0x00);
 | 
						||
  
 | 
						||
  TString80 caption("ID@4|Descrizione@40|Riga@R|Col.@R|Non stampare");
 | 
						||
  if (form().edit_level() > 1) caption << "|Gr.@R|Campo@16";
 | 
						||
  
 | 
						||
  TArray_sheet a(-1, -1, 0, 0, title, caption, flags);
 | 
						||
 | 
						||
  for (word i = 0; i < fields(); i++)
 | 
						||
  {
 | 
						||
    TToken_string* s = new TToken_string(128);
 | 
						||
    field(i).print_on(*s);
 | 
						||
    a.add(s);
 | 
						||
  }
 | 
						||
 | 
						||
  KEY k;
 | 
						||
  while ((k = a.run()) != K_ESC)
 | 
						||
  {   
 | 
						||
    i = (word)a.selected();
 | 
						||
    
 | 
						||
    if (_msk == NULL && (k == K_ENTER || k == K_INS || k == K_CTRL + 'N'))
 | 
						||
    {
 | 
						||
      _msk = new TMask("ba2100f");
 | 
						||
      
 | 
						||
      _msk->set_handler(F_DFORMAT,    dateformat_handler);
 | 
						||
      _msk->set_handler(F_DYEAR,      dateformat_handler);
 | 
						||
      _msk->set_handler(F_DMONTH,     dateformat_handler);
 | 
						||
      _msk->set_handler(F_DDAY,       dateformat_handler);
 | 
						||
      _msk->set_handler(F_DSEP,       dateformat_handler); 
 | 
						||
      
 | 
						||
      _msk->set_handler(F_BUT_FILE1,  but_file_handler);
 | 
						||
      _msk->set_handler(F_BUT_FIELD1, but_field_handler);
 | 
						||
      _msk->set_handler(F_FROM1,      from_handler);
 | 
						||
      _msk->set_handler(F_TO1,        to_handler);
 | 
						||
      _msk->set_handler(F_BUT_FILE2,  but_file_handler);
 | 
						||
      _msk->set_handler(F_BUT_FIELD2, but_field_handler);
 | 
						||
      _msk->set_handler(F_FROM2,      from_handler);
 | 
						||
      _msk->set_handler(F_TO2,        to_handler);
 | 
						||
    }  
 | 
						||
    
 | 
						||
    TForm_string dummy(this);
 | 
						||
 | 
						||
    switch(k)
 | 
						||
    {
 | 
						||
    case K_ENTER:
 | 
						||
      _msk->set_mode(MODE_MOD);
 | 
						||
      if (field(i).edit(*_msk))
 | 
						||
      {
 | 
						||
        field(i).print_on(a.row(i));
 | 
						||
        _dirty = TRUE;
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case K_CTRL + 'N': 
 | 
						||
    case K_INS:
 | 
						||
      _msk->set_mode(MODE_INS);
 | 
						||
      if (dummy.edit(*_msk))
 | 
						||
      {        
 | 
						||
        const TString& c = _msk->get(F_CLASS).left(2);
 | 
						||
        TForm_item* item = parse_item(c);
 | 
						||
        if (item != NULL)
 | 
						||
        {
 | 
						||
          item->read_from(*_msk);
 | 
						||
          _item.insert(item, i);
 | 
						||
          
 | 
						||
          TToken_string s(128); item->print_on(s);
 | 
						||
          a.insert(s, i);
 | 
						||
          _dirty = TRUE;
 | 
						||
        }  
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case K_DEL: 
 | 
						||
      if (yesno_box("Confermare la cancellazione"))
 | 
						||
      {
 | 
						||
        _item.destroy(i, TRUE);
 | 
						||
        a.destroy(i);
 | 
						||
        _dirty = TRUE;
 | 
						||
      } 
 | 
						||
      break;  
 | 
						||
    default:
 | 
						||
      break;
 | 
						||
    }    
 | 
						||
  }
 | 
						||
  
 | 
						||
  set_dirty(_dirty);
 | 
						||
  return _dirty;
 | 
						||
}
 | 
						||
 | 
						||
void TPrint_section::print_on(ostream& out) const
 | 
						||
{        
 | 
						||
  out << ' ';
 | 
						||
  switch (page_type())
 | 
						||
  {
 | 
						||
  case even_page:
 | 
						||
    out << "EVEN"; break;
 | 
						||
  case first_page:
 | 
						||
    out << "FIRST"; break;
 | 
						||
  case last_page:
 | 
						||
    out << "LAST"; break;
 | 
						||
  default:
 | 
						||
    out << "ODD"; break;
 | 
						||
  }
 | 
						||
  out << ' ' << _height << endl << endl;
 | 
						||
  for(word i = 0; i < fields(); i++)
 | 
						||
    out << field(i);
 | 
						||
}
 | 
						||
 | 
						||
TForm_item& TPrint_section::find_field(short id) const
 | 
						||
{
 | 
						||
  for(word i = 0; i < fields(); i++)
 | 
						||
  {
 | 
						||
    TForm_item& f = field(i);
 | 
						||
    if (f.id() == id) return f;
 | 
						||
  }              
 | 
						||
  yesnofatal_box("Can't find item whit id %d", id);
 | 
						||
  return field(0);  
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TGraphic_section
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TGraphic_section : public TPrint_section
 | 
						||
{
 | 
						||
  TString _back;                                        
 | 
						||
 | 
						||
protected:  
 | 
						||
  TForm_item* parse_item(const TString& s);
 | 
						||
  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
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual const char* class_name() const { return "FIGURA"; }
 | 
						||
  virtual bool update();
 | 
						||
 | 
						||
public:
 | 
						||
  TForm_picture(TGraphic_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() {}
 | 
						||
};
 | 
						||
 | 
						||
bool TForm_picture::update()
 | 
						||
{                        
 | 
						||
  const bool ok = _prompt.not_empty();
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    TString80 i;
 | 
						||
    i << "i{" << _prompt << ',' << _x << ',' << _y << ',' 
 | 
						||
      << (_x+width()-1) << ',' << (_y+height()-1) << '}';
 | 
						||
    ((TGraphic_section&)section()).append(i);
 | 
						||
  }  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm_line::update()
 | 
						||
{                                        
 | 
						||
  TString80 i;
 | 
						||
  const int w = _prompt[0] == '@' ? 3 : 1; 
 | 
						||
  i << 'W' << w << "l{" << _x << ',' << _y << ','
 | 
						||
    << (_x+width()-1) << ',' << (_y+height()-1) << '}';
 | 
						||
  
 | 
						||
  ((TGraphic_section&)section()).append(i);
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TForm_item* TGraphic_section::parse_item(const TString& s)
 | 
						||
{
 | 
						||
  if (s == "FI")
 | 
						||
    return new TForm_picture(this);
 | 
						||
  else if (s == "LI")
 | 
						||
    return new TForm_line(this);
 | 
						||
 | 
						||
  error_box("Campo di stampa non ammesso per lo sfondo: %s", (const char*)s);
 | 
						||
  return NULL;  
 | 
						||
}
 | 
						||
 | 
						||
bool TGraphic_section::update()
 | 
						||
{                       
 | 
						||
  _back.cut(0);
 | 
						||
  const bool ok = TPrint_section::update();
 | 
						||
  printer().setbackground(_back);
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
bool TForm::parse_use(TScanner& scanner)
 | 
						||
{
 | 
						||
  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;
 | 
						||
  if (scanner.popkey() == "KE")
 | 
						||
    key = scanner.integer();
 | 
						||
  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();
 | 
						||
 | 
						||
  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("JOIN senza espressioni INTO");
 | 
						||
  scanner.push();
 | 
						||
  
 | 
						||
  if (isdigit(j[0]))
 | 
						||
    _relation->add(atoi(j), exp, key, to, alias);   // join file
 | 
						||
  else
 | 
						||
    _relation->add(j, exp, key, to, alias);         // join table
 | 
						||
  
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
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.popkey() == "OF")   // Offsets
 | 
						||
      {
 | 
						||
        _x = scanner.integer();
 | 
						||
        _y = scanner.integer();
 | 
						||
      }
 | 
						||
      else scanner.push();    
 | 
						||
      if (scanner.popkey() == "FO")   // Font name
 | 
						||
        _fontname = scanner.string();
 | 
						||
      else scanner.push();    
 | 
						||
      if (scanner.popkey() == "SI")   // Font size
 | 
						||
        _fontsize = scanner.integer();
 | 
						||
      else scanner.push();
 | 
						||
      if (scanner.popkey() == "CA")   // Carattere di posizionamento
 | 
						||
        _char_to_pos = scanner.string()[0];
 | 
						||
      else scanner.push();
 | 
						||
      if (scanner.popkey() == "IN")   // Riga e colonna del posizionamento iniziale
 | 
						||
      {
 | 
						||
        _ipx = scanner.integer();
 | 
						||
        _ipy = scanner.integer();
 | 
						||
      }
 | 
						||
      else scanner.push();
 | 
						||
      if (scanner.popkey() == "FI")   // Riga e colonna del posizionamento finale
 | 
						||
      {                              
 | 
						||
        _fpx = scanner.integer();
 | 
						||
      }
 | 
						||
      else scanner.push();
 | 
						||
      
 | 
						||
      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 << "END\n" << endl;
 | 
						||
}
 | 
						||
 | 
						||
TPrint_section* TForm::exist(char s, pagetype t, bool create)
 | 
						||
{
 | 
						||
  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::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 %d", id);
 | 
						||
  return ps->find_field(id);
 | 
						||
}
 | 
						||
 | 
						||
TPrint_section& TForm::section(char s, word p)
 | 
						||
{              
 | 
						||
  pagetype pos = odd_page;  
 | 
						||
  // It was p==0
 | 
						||
  if (p == 3 && exist(s, last_page)) pos = last_page;
 | 
						||
  // It was p==1
 | 
						||
  if (p == 2 && exist(s, first_page)) pos = first_page;
 | 
						||
  // It was pos == odd_page && (p & 0x1) == 0
 | 
						||
  if (p == 1 && exist(s, even_page)) pos = even_page;
 | 
						||
  
 | 
						||
  TPrint_section* sec = exist(s, pos, TRUE);
 | 
						||
  return *sec;
 | 
						||
}
 | 
						||
 | 
						||
word TForm::set_background(word p, bool u)
 | 
						||
{
 | 
						||
  word len = 0;
 | 
						||
  
 | 
						||
  if (u && _back.items()) 
 | 
						||
  {
 | 
						||
    TPrint_section& graph = section('G', p);
 | 
						||
    graph.update();
 | 
						||
    len = printer().formlen();
 | 
						||
  }    
 | 
						||
  
 | 
						||
  return len;
 | 
						||
}
 | 
						||
 | 
						||
word TForm::set_header(word p, bool u)
 | 
						||
{           
 | 
						||
  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();
 | 
						||
}
 | 
						||
 | 
						||
word TForm::set_body(word p, bool u)
 | 
						||
{
 | 
						||
  TPrint_section& body = section('B', p);
 | 
						||
 | 
						||
  if (u) body.update(); 
 | 
						||
  else body.reset();
 | 
						||
  
 | 
						||
  if (u) 
 | 
						||
  {
 | 
						||
    TPrinter& pr = printer();
 | 
						||
    for (word j = 0; j < body.height(); j++)
 | 
						||
      pr.print(body.row(j));
 | 
						||
  }
 | 
						||
  
 | 
						||
  return body.height();
 | 
						||
}
 | 
						||
 | 
						||
word TForm::set_footer(word p, bool u)
 | 
						||
{
 | 
						||
  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)
 | 
						||
{
 | 
						||
  const word page = form().page(p);
 | 
						||
  form().set_background(page, TRUE);
 | 
						||
  form().set_header(page, TRUE);
 | 
						||
  form().set_footer(page, FALSE);
 | 
						||
}
 | 
						||
 | 
						||
void TForm::footer_handler(TPrinter& p)
 | 
						||
{
 | 
						||
  const word page = form().page(p);
 | 
						||
  form().set_footer(page, TRUE); 
 | 
						||
  if (page)
 | 
						||
    form().set_header(page+1, FALSE);
 | 
						||
}   
 | 
						||
 | 
						||
 | 
						||
word TForm::page(const TPrinter& p) const
 | 
						||
{
 | 
						||
  return _lastpage ? 0 : p.getcurrentpage();
 | 
						||
}                                   
 | 
						||
 | 
						||
void TForm::arrange_form()
 | 
						||
{                     
 | 
						||
  TString device;
 | 
						||
#if XVT_OS == XVT_OS_WIN
 | 
						||
  char defPrinter[80];
 | 
						||
  char szDevice[50];
 | 
						||
 | 
						||
  // get default printer driver
 | 
						||
  GetProfileString ("windows", "device", ",,,", defPrinter, sizeof(defPrinter));
 | 
						||
  TToken_string pdev (defPrinter, ',');
 | 
						||
  GetProfileString ("devices", pdev, "", szDevice, sizeof(szDevice));
 | 
						||
  pdev.add(szDevice);             
 | 
						||
  device = pdev.get(2);
 | 
						||
  device = device.left(4); //Legge solo LPTx...
 | 
						||
#endif      
 | 
						||
  FILE* lpt = fopen(device,"w"); 
 | 
						||
  // 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.
 | 
						||
  // 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!.
 | 
						||
    // Quindi, per ovviare a tutto cio, visto che 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;  
 | 
						||
  if (lpt == NULL) fatal_box("Non rieso ad aprire il device %s.",device);
 | 
						||
  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";
 | 
						||
  fprintf(lpt,"%s",(const char*) str_pos);  
 | 
						||
  fflush(lpt);              // Salta le righe...                           
 | 
						||
  str_pos.cut(0);  //Azzera la stringa di posizionamento
 | 
						||
  for (i=1; i < _ipx; i++) str_pos << " "; //Aggiunge gli spazi necessari...
 | 
						||
  if (_ipx > 0 && _ipy > 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
 | 
						||
  TString bspc; bspc.fill('\b',str_pos.len()); // Questi sevono per tornare indietro...
 | 
						||
  do
 | 
						||
  {              
 | 
						||
    fprintf(lpt,"%s",(const char*) bspc);  
 | 
						||
    fprintf(lpt,"%s",(const char*) str_pos);  
 | 
						||
    fflush(lpt);
 | 
						||
  } while (m.run() == K_ESC);     // cicla sulla stampa posizionamento...
 | 
						||
  const int h = height(odd_page);                   
 | 
						||
  str_pos.cut(0);
 | 
						||
  for (i=0; i <= h; i++) str_pos << "\n";
 | 
						||
  fprintf(lpt, "%s", (const char*) str_pos); // Salta tante righe quanto e' lungo il form standard
 | 
						||
  fclose (lpt);       
 | 
						||
#if XVT_OS != XVT_OS_WIN  
 | 
						||
#pragma message ("Voglio proprio vedere come fai a gestire il posizionamento sotto Unix!")
 | 
						||
#endif
 | 
						||
}
 | 
						||
 | 
						||
long TForm::records() const
 | 
						||
{             
 | 
						||
  const long r = _cursor ? _cursor->items() : 0;
 | 
						||
  return r;
 | 
						||
}
 | 
						||
 | 
						||
// Stampa gli items dal from a to
 | 
						||
// se to < 0 stampa fino alla fine del file
 | 
						||
 | 
						||
bool TForm::print(long from, long to)
 | 
						||
{ 
 | 
						||
  _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 (_char_to_pos != '\0' || (_ipx +_ipy+_fpx) != 0)   // Effettua il posizionamento del form...
 | 
						||
  {
 | 
						||
    if (pr.printtype() == screenvis)
 | 
						||
      error_box("Stampa a video selezionata. Non e' possibile effettuare il posizionamento.");
 | 
						||
    else
 | 
						||
      arrange_form();
 | 
						||
  }                        
 | 
						||
  
 | 
						||
  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(odd_page));
 | 
						||
  }
 | 
						||
  pr.set_char_size(_fontsize);                     // Set font name and size
 | 
						||
  pr.set_fontname(_fontname);                      // according to current form
 | 
						||
  const bool was_open = pr.isopen();
 | 
						||
 | 
						||
  _lastpage = 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; i++)
 | 
						||
  {
 | 
						||
    if (from < 0) to = from;
 | 
						||
    else if (_cursor) *_cursor = i;
 | 
						||
    
 | 
						||
    const word h = set_body(page(pr), FALSE);
 | 
						||
    if (h > pr.rows_left())
 | 
						||
      pr.formfeed();
 | 
						||
 | 
						||
    set_body(page(pr), TRUE);
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (i == lastrec)
 | 
						||
  {                
 | 
						||
    if (_cursor) *_cursor = i;
 | 
						||
    _lastpage = TRUE;
 | 
						||
    set_background(0, TRUE);
 | 
						||
    set_header(0, TRUE);
 | 
						||
    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())
 | 
						||
    {
 | 
						||
      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;
 | 
						||
    }  
 | 
						||
  }
 | 
						||
} 
 | 
						||
 | 
						||
bool TForm::validate(TForm_item& f, TToken_string&)
 | 
						||
{ return FALSE; }                                        
 | 
						||
 | 
						||
void TForm::print_on(ostream& out) const
 | 
						||
{                   
 | 
						||
  main_app().begin_wait();
 | 
						||
 | 
						||
  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;
 | 
						||
  
 | 
						||
  main_app().end_wait();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
word TForm::height(word page)
 | 
						||
{               
 | 
						||
  word h = 0;
 | 
						||
  
 | 
						||
  if (_back.items() == 0)
 | 
						||
  {
 | 
						||
    if (_head.items() && exist('H', pagetype(page)) != NULL)
 | 
						||
      h += section('H', page).height();
 | 
						||
    if (_body.items() && exist('B', pagetype(page)) != NULL)
 | 
						||
      h += section('B', page).height();
 | 
						||
    if (_foot.items() && exist('F', pagetype(page)) != NULL)
 | 
						||
      h += section('F', page).height();
 | 
						||
  } 
 | 
						||
  else 
 | 
						||
    h = printer().formlen();    
 | 
						||
  
 | 
						||
  return h;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TForm::read_profile()
 | 
						||
{      
 | 
						||
  TLocalisamfile prof(LF_FORM);  
 | 
						||
  TLocalisamfile rprof(LF_RFORM); 
 | 
						||
  
 | 
						||
  prof.zero();
 | 
						||
  prof.put("TIPOPROF",_name);
 | 
						||
  prof.put("CODPROF",_code);
 | 
						||
  if (prof.read(_isequal) == NOERR)
 | 
						||
  {
 | 
						||
    bool complete = FALSE;
 | 
						||
    rprof.zero();
 | 
						||
    rprof.put("TIPOPROF", _name);
 | 
						||
    rprof.put("CODPROF", _code);
 | 
						||
    const TRectype filter(rprof.curr());
 | 
						||
    
 | 
						||
    for (int err = rprof.read(_isgteq); err == NOERR && rprof.curr() == filter; err = rprof.next())
 | 
						||
    {              
 | 
						||
      const TString& s = rprof.get("SEZ"); 
 | 
						||
      const char sec = s[0];
 | 
						||
      const pagetype pt = char2page(s[1]);
 | 
						||
      const short id = rprof.get_int("ID");
 | 
						||
      
 | 
						||
      if (!complete) complete=TRUE;
 | 
						||
      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 (complete) // Get general data from header of form only if it's complete.
 | 
						||
    {             // Complete means that there's at least a row
 | 
						||
      _x = prof.get_int("OFFX");
 | 
						||
      _y = prof.get_int("OFFY");
 | 
						||
      _fontname = prof.get("FONTNAME");
 | 
						||
      _fontsize = prof.get_int("FONTSIZE");
 | 
						||
      _char_to_pos = prof.get_char("CTP");
 | 
						||
      _ipx = prof.get_int("IPX");
 | 
						||
      _ipy = prof.get_int("IPY");
 | 
						||
      _fpx = prof.get_int("FPX");
 | 
						||
    }
 | 
						||
  }             
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TForm::write_profile()
 | 
						||
{
 | 
						||
  const char sechar[4] = { 'B', 'F', 'G',  'H' };
 | 
						||
  
 | 
						||
  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.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("Errore di salvataggio profilo: %d", err);
 | 
						||
  
 | 
						||
  return TRUE;
 | 
						||
}    
 | 
						||
 | 
						||
TForm::TForm(const char* name, const char* code, int lev, const char* desc) 
 | 
						||
: _name(name), _code(code), _relation(NULL), _cursor(NULL), _rel_desc(NULL), 
 | 
						||
  _isnew(FALSE), _editlevel(lev), _desc(desc), _fontname("Courier New"),
 | 
						||
  _fontsize(12), _x(0), _y(0), _char_to_pos('\0'), _ipx(0), _ipy(0), _fpx(0),
 | 
						||
  _dirty(FALSE)
 | 
						||
{ 
 | 
						||
  main_app().begin_wait();
 | 
						||
 | 
						||
  if (_code != "")
 | 
						||
  {
 | 
						||
    // 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.write();
 | 
						||
    }                
 | 
						||
    else _desc = forms.get("DESC");
 | 
						||
  }
 | 
						||
 | 
						||
  // read base form  
 | 
						||
  TFilename n(_name); n.ext("frm");
 | 
						||
  TScanner scanner(n);
 | 
						||
 | 
						||
  bool ok = TRUE;
 | 
						||
  if (scanner.popkey() == "US")                         // Parse relation
 | 
						||
  {
 | 
						||
    ok = parse_use(scanner);
 | 
						||
    while (ok && scanner.popkey() == "JO")
 | 
						||
      ok = parse_join(scanner);  
 | 
						||
    
 | 
						||
    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 != "")
 | 
						||
    read_profile();    // read from LF_RFORM file
 | 
						||
  
 | 
						||
  main_app().end_wait();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TForm::~TForm()
 | 
						||
{
 | 
						||
  if (_cursor)
 | 
						||
  {
 | 
						||
    delete _cursor;
 | 
						||
    delete _relation;   
 | 
						||
    if (_rel_desc)
 | 
						||
      delete _rel_desc;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 |