2178 lines
		
	
	
		
			53 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2178 lines
		
	
	
		
			53 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <stdlib.h>
 | 
						|
 | 
						|
#define STRICT
 | 
						|
#define XVT_INCL_NATIVE
 | 
						|
#include <xvt.h>
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
#include <strstrea.h>
 | 
						|
#else
 | 
						|
#include <strstream.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#if XVT_OS==XVT_OS_SCOUNIX
 | 
						|
#include <unistd.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/wait.h>
 | 
						|
#else
 | 
						|
#include <stdio.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#define STYLE_NUM 4
 | 
						|
 | 
						|
#include <applicat.h>
 | 
						|
#include <config.h>
 | 
						|
#include <execp.h>
 | 
						|
#include <golem.h>
 | 
						|
#include <mask.h>   
 | 
						|
#include <printer.h>
 | 
						|
#include <printwin.h>
 | 
						|
#include <urldefid.h>
 | 
						|
#include <utility.h>
 | 
						|
#include <viswin.h>
 | 
						|
 | 
						|
#include <bagn001a.h> 
 | 
						|
 | 
						|
HIDDEN TPrinter* _printer = NULL;
 | 
						|
 | 
						|
TPrinter& printer()
 | 
						|
{
 | 
						|
  if (_printer == NULL)
 | 
						|
    _printer = new TPrinter;
 | 
						|
  return *_printer;
 | 
						|
}
 | 
						|
 | 
						|
void printer_destroy()
 | 
						|
{
 | 
						|
  if (_printer != NULL)
 | 
						|
  {
 | 
						|
    delete _printer;
 | 
						|
    _printer = NULL;
 | 
						|
  }  
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------
 | 
						|
// TPrint_intersector
 | 
						|
// ----------------------------------------------------------------------
 | 
						|
 | 
						|
// TPrint_intersector: calcola intersezioni tra elementi grafici e 
 | 
						|
// restituisce, riga per riga, i necessari caratteri di fincatura per
 | 
						|
// finculare in modo carattere
 | 
						|
// usata da viswin e printwin
 | 
						|
class TPrint_intersector : public TString_array
 | 
						|
{
 | 
						|
    const char* _fink;    
 | 
						|
 | 
						|
    char check_intersection(int x, int y, char ch);
 | 
						|
    void h_line(int x1, int y1, int len);
 | 
						|
    void v_line(int x1, int y1, int len);
 | 
						|
 | 
						|
    // caratteri fincazione: l'ho fatto perche' e' inline                                              
 | 
						|
    char f_topleft()      const { return _fink[0];  }                                              
 | 
						|
    char f_topmiddle()    const { return _fink[1];  }                                              
 | 
						|
    char f_topright()     const { return _fink[2];  }                                              
 | 
						|
    char f_botleft()      const { return _fink[3];  }                                              
 | 
						|
    char f_botmiddle()    const { return _fink[4];  }                                              
 | 
						|
    char f_botright()     const { return _fink[5];  }                                              
 | 
						|
    char f_centerleft()   const { return _fink[6];  }                                              
 | 
						|
    char f_centermiddle() const { return _fink[7];  }                                              
 | 
						|
    char f_centerright()  const { return _fink[8];  }                                              
 | 
						|
    char f_horizontal()   const { return _fink[9];  }                                              
 | 
						|
    char f_vertical()     const { return _fink[10]; }                                              
 | 
						|
 | 
						|
    
 | 
						|
  public:
 | 
						|
                                                                 
 | 
						|
    // aggiunge un elemento grafico                                                           
 | 
						|
    void add(TGraphic_shape s, int x1, int y1, int x2, int y2);
 | 
						|
    // aggiunge alla stringa passata i necessari caratteri, leggendo
 | 
						|
    // dalla pagina interna
 | 
						|
    const char* get_chars(int line) const;  
 | 
						|
    // sbianca tutto
 | 
						|
    void clear();
 | 
						|
    
 | 
						|
    TPrint_intersector(const char* fink, int pagesize) : TString_array(pagesize) , _fink(fink)
 | 
						|
    {}
 | 
						|
    virtual ~TPrint_intersector() {}
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
char TPrint_intersector::check_intersection(int x, int y, char ch)
 | 
						|
{ 
 | 
						|
  char a = ' ', b = ' ', c = ' ', d = ' ';
 | 
						|
  if (y > 0 && objptr(y-1) != NULL)
 | 
						|
    b = row(y-1)[x];
 | 
						|
  if (objptr(y+1) != NULL)
 | 
						|
    d = row(y+1)[x];
 | 
						|
  if (x > 0) a = row(y)[x-1];
 | 
						|
  if (x < row(y).len()-1) c = row(y)[x+1]; 
 | 
						|
  
 | 
						|
  if (a == ' ' && b == ' ' && c != ' ' && d != ' ')
 | 
						|
    ch = f_topleft();
 | 
						|
  else if (a == ' ' && b != ' ' && c != ' ' && d == ' ')
 | 
						|
    ch = f_botleft();
 | 
						|
  else if (a != ' ' && b != ' ' && c == ' ' && d == ' ')
 | 
						|
    ch = f_botright();
 | 
						|
  else if (a != ' ' && b == ' ' && c == ' ' && d != ' ')
 | 
						|
    ch = f_topright();
 | 
						|
  else if (a != ' ' && b != ' ' && c == ' ' && d != ' ')
 | 
						|
    ch = f_centerright();
 | 
						|
  else if (a == ' ' && b != ' ' && c != ' ' && d != ' ')
 | 
						|
    ch = f_centerleft();
 | 
						|
  else if (a != ' ' && b != ' ' && c != ' ' && d == ' ')
 | 
						|
    ch = f_botmiddle();
 | 
						|
  else if (a != ' ' && b == ' ' && c != ' ' && d != ' ')
 | 
						|
    ch = f_topmiddle();
 | 
						|
  else if ((a != ' ' && b != ' ' && c != ' ' && d != ' ') ||
 | 
						|
           ((a != ' ' && b == ' ' && c != ' ' && d == ' ') && ch == f_vertical()) ||
 | 
						|
           ((a == ' ' && b != ' ' && c == ' ' && d != ' ') && ch == f_horizontal()))
 | 
						|
    ch = f_centermiddle();
 | 
						|
     
 | 
						|
  return ch;
 | 
						|
}
 | 
						|
 | 
						|
void TPrint_intersector::h_line(int x1, int y1, int len)
 | 
						|
{          
 | 
						|
  if (objptr(y1) == NULL) 
 | 
						|
  {
 | 
						|
    TString* ss = new TString(256);
 | 
						|
    ss->spaces();
 | 
						|
    TArray::add(ss, y1);
 | 
						|
  }       
 | 
						|
  
 | 
						|
  TString& s = row(y1);
 | 
						|
  
 | 
						|
  for (int i = x1; i < x1+len; i++)
 | 
						|
    s[i] = f_horizontal();
 | 
						|
  for (i = x1; i < x1+len; i++)
 | 
						|
    s[i] = check_intersection(i, y1, f_horizontal());
 | 
						|
}
 | 
						|
 | 
						|
void TPrint_intersector::v_line(int x1, int y1, int len)
 | 
						|
{  
 | 
						|
  for (int i = y1; i < y1+len; i++)
 | 
						|
  {
 | 
						|
    if (objptr(i) == NULL) 
 | 
						|
    {
 | 
						|
      TString* ss = new TString(256);
 | 
						|
      ss->spaces();
 | 
						|
      TArray::add(ss, i);
 | 
						|
    }
 | 
						|
    row(i)[x1] = f_vertical();
 | 
						|
  }
 | 
						|
  for (i = y1; i < y1+len; i++)
 | 
						|
    row(i)[x1] = check_intersection(x1, i, f_vertical());
 | 
						|
}
 | 
						|
 | 
						|
void TPrint_intersector::add(TGraphic_shape s, int x1, int y1, int x2, int y2)
 | 
						|
{     
 | 
						|
  // rows start at 0
 | 
						|
  y1 --;  y2 --;
 | 
						|
  // columns pure, ma e' possibile che siano gia' 0 se la generazione
 | 
						|
  // e' stata automatica (colonna 1. campo - 1)
 | 
						|
  if (x1 > 0) x1 --;
 | 
						|
  if (x2 > 0) x2 --;
 | 
						|
 | 
						|
  switch (s)
 | 
						|
  {
 | 
						|
    case line:   
 | 
						|
      if (x1 == x2)       // vertical
 | 
						|
        v_line(x1, y1, y2-y1+1);
 | 
						|
      else if (y1 == y2)  // horizontal
 | 
						|
        h_line(x1,y1, x2-x1+1);
 | 
						|
      else error_box("Linee oblique non supportate in modalita' testo");
 | 
						|
      break;
 | 
						|
    case box: 
 | 
						|
      h_line(x1, y1, x2-x1+1);
 | 
						|
      h_line(x1, y2, x2-x1+1);
 | 
						|
      v_line(x1, y1, y2-y1+1);
 | 
						|
      v_line(x2, y1, y2-y1+1);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const char* TPrint_intersector::get_chars(int line) const
 | 
						|
{
 | 
						|
   if (objptr(line) == NULL)
 | 
						|
     return "";
 | 
						|
   else
 | 
						|
     return row(line);
 | 
						|
}
 | 
						|
 | 
						|
void TPrint_intersector::clear()
 | 
						|
{  
 | 
						|
  for (int i = 0; i < items(); i++)
 | 
						|
  {
 | 
						|
    TString* s = (TString*)objptr(i);
 | 
						|
    if (s != NULL)
 | 
						|
      s->spaces();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// PrDesc
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct PrDesc
 | 
						|
{
 | 
						|
  TTextfile *_txt;
 | 
						|
  PRINT_RCD *_prcd;
 | 
						|
  bool _graphics;
 | 
						|
  int _formlen;
 | 
						|
  int _charsize;
 | 
						|
  int _lines_per_inch;
 | 
						|
}
 | 
						|
PrintWhat;
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
 | 
						|
void TPrinter::_get_windows_printer_names (TToken_string & t)
 | 
						|
{
 | 
						|
  char *buf = new char[4096];   // ammazzao'
 | 
						|
 | 
						|
  GetProfileString ("devices", NULL, "", buf, 4096);
 | 
						|
 | 
						|
  for (int i = 0; i < 4095; i++)
 | 
						|
  {
 | 
						|
    if (buf[i] == '\0')
 | 
						|
    {
 | 
						|
      if (buf[i+1] != '\0') buf[i] = '|';
 | 
						|
      else break;
 | 
						|
    }  
 | 
						|
  }
 | 
						|
  t = buf;
 | 
						|
  delete buf;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN XVT_CALLCONV1 TPrinter::start_winprint (long data)
 | 
						|
{
 | 
						|
  PrDesc *pd = (PrDesc *) data;
 | 
						|
  TTextfile& txt = *(pd->_txt);
 | 
						|
  TPrintwin pw(txt);
 | 
						|
  pw.do_print();
 | 
						|
  return pw.aborted();
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
// utils del caz
 | 
						|
HIDDEN int read_int (const char *s, int &n, int &cnt)
 | 
						|
{
 | 
						|
  char nbuf[16];
 | 
						|
  
 | 
						|
  while (!isdigit (s[cnt]))
 | 
						|
    cnt++;
 | 
						|
 | 
						|
  for (int j = 0; isdigit (s[cnt]); j++)
 | 
						|
    nbuf[j] = s[cnt++];
 | 
						|
  nbuf[j] = '\0';
 | 
						|
 | 
						|
  return n = atoi (nbuf);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TPrinter::parse_background(const char* bg_desc, TArray& background)
 | 
						|
{
 | 
						|
  TString_array pix;
 | 
						|
  char op, ch;
 | 
						|
  int x1, x2, y1, y2;
 | 
						|
  int id, cnt = 0; 
 | 
						|
  
 | 
						|
  TToken_string tt;
 | 
						|
  TFilename bmp;
 | 
						|
 | 
						|
  if (!_isgraphics && _finker == NULL)
 | 
						|
    _finker = new TPrint_intersector(_fink, _formlen);
 | 
						|
  else if (_finker)
 | 
						|
    _finker->clear();
 | 
						|
 | 
						|
  while ((ch = bg_desc[cnt++]) != '\0')
 | 
						|
  {
 | 
						|
    op = ch;
 | 
						|
    tt = "";
 | 
						|
    char bf[2];
 | 
						|
    bf[1] = '\0';
 | 
						|
    switch (op)
 | 
						|
    {
 | 
						|
    case ' ':               
 | 
						|
    case '\t':
 | 
						|
    case '\n':
 | 
						|
      continue;             // ignore whitespace
 | 
						|
      break;
 | 
						|
    case 'i':
 | 
						|
      cnt++;
 | 
						|
      for (x1 = 0; bg_desc[cnt] != ','; x1++)
 | 
						|
        bmp[x1] = bg_desc[cnt++];
 | 
						|
      bmp[x1] = '\0';
 | 
						|
      id = _image_names.find(bmp);
 | 
						|
      if (id < 0) id = _image_names.add(bmp);
 | 
						|
      read_int(bg_desc, x1, cnt); if (x1 <= 0) x1 = 1;
 | 
						|
      read_int(bg_desc, y1, cnt); if (y1 <= 0) y1 = 1;
 | 
						|
      read_int(bg_desc, x2, cnt); if (x2 <= 0) x2 = formwidth();
 | 
						|
      read_int(bg_desc, y2, cnt); if (y2 <= 0) y2 = formlen();
 | 
						|
      cnt++;
 | 
						|
      if (_isgraphics)
 | 
						|
      {
 | 
						|
        tt << op;
 | 
						|
        tt.add(id);
 | 
						|
        tt.add(x1);
 | 
						|
        tt.add(y1);
 | 
						|
        tt.add(x2);  
 | 
						|
        tt.add(y2); 
 | 
						|
      } 
 | 
						|
      break;  
 | 
						|
    case 'l':               // line
 | 
						|
 | 
						|
    case 'b':               // box
 | 
						|
 | 
						|
    case 'r':               // round box
 | 
						|
      cnt++;
 | 
						|
      read_int (bg_desc, x1, cnt);
 | 
						|
      read_int (bg_desc, y1, cnt);
 | 
						|
      read_int (bg_desc, x2, cnt);
 | 
						|
      read_int (bg_desc, y2, cnt);
 | 
						|
      cnt++;                // skip separator
 | 
						|
      if (_isgraphics) 
 | 
						|
      {
 | 
						|
        tt << op;
 | 
						|
        tt.add (x1 - 1);
 | 
						|
        tt.add (y1 - 1);
 | 
						|
        tt.add (x2 - 1);
 | 
						|
        tt.add (y2 - 1); 
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        TGraphic_shape s = op == 'b' ? box : line;
 | 
						|
        _finker->add(s, x1, y1, x2, y2);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case 't':               // text
 | 
						|
      cnt++;
 | 
						|
      read_int (bg_desc, x1, cnt);
 | 
						|
      read_int (bg_desc, y1, cnt);
 | 
						|
      cnt++;
 | 
						|
      tt << op;
 | 
						|
      tt.add (x1-1);
 | 
						|
      tt.add (y1-1);
 | 
						|
      tt << '|';
 | 
						|
      while ((ch = bg_desc[cnt++]) != '}')
 | 
						|
        tt << ch;
 | 
						|
      break;
 | 
						|
      
 | 
						|
    case 'P':           // set pen style
 | 
						|
 | 
						|
    case 'B':           // set brush
 | 
						|
 | 
						|
    case 'W':           // set line width 
 | 
						|
 | 
						|
    case 'C':           // set pen color
 | 
						|
 | 
						|
      tt << op;
 | 
						|
      bf[0] = bg_desc[cnt++];
 | 
						|
      tt.add (bf);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      yesnofatal_box ("Unknown background opcode: %c", op);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    pix.add (tt);
 | 
						|
  }
 | 
						|
                               
 | 
						|
  // now build row descriptions
 | 
						|
 | 
						|
  // colors are listed in printapp:
 | 
						|
 | 
						|
  char curcol = 'n';
 | 
						|
  char curpen = 'n';
 | 
						|
  char curpat = 'n';
 | 
						|
  char curwid = '1';
 | 
						|
 | 
						|
  for (int l = 0; l < _formlen; l++)
 | 
						|
  {
 | 
						|
    if (background.objptr(l) == NULL)            // Se la riga non esiste creala
 | 
						|
    {                                        
 | 
						|
      TString* r = new TString(15);           
 | 
						|
      if (curcol != 'n') *r << 'C' << curcol;    // Setta valori se diversi da default
 | 
						|
      if (curpat != 'n') *r << 'B' << curpat;
 | 
						|
      if (curwid != '1') *r << 'W' << curwid;
 | 
						|
      if (curpen != 'n') *r << 'P' << curcol;
 | 
						|
      background.add(r, l);
 | 
						|
    }
 | 
						|
    
 | 
						|
    TString& rwd = (TString&)background[l];
 | 
						|
    for (int j = 0; j < pix.items(); j++)
 | 
						|
    {
 | 
						|
      TToken_string& tt = pix.row(j);
 | 
						|
 | 
						|
      // la stringa contiene l'opcode piu' i parametri in binario, 
 | 
						|
      // incrementati di 1 per evitare lo 0
 | 
						|
 | 
						|
      switch (tt.get_char(0))
 | 
						|
      {
 | 
						|
      case 'b':
 | 
						|
        x1 = tt.get_int (1) + 1;
 | 
						|
        y1 = tt.get_int (2) + 1;
 | 
						|
        x2 = tt.get_int (3) + 1;
 | 
						|
        y2 = tt.get_int (4) + 1;
 | 
						|
        if (y1 == l + 1)        // at ze biginnin
 | 
						|
        {
 | 
						|
          rwd << 'u' << char (x1);
 | 
						|
          rwd << 'r' << char (x1) << char (x2);
 | 
						|
          rwd << 'u' << char (x2);
 | 
						|
        }
 | 
						|
        else if (y2 == l + 1)   // at ze end
 | 
						|
        {
 | 
						|
          rwd << 'o' << char (x1);
 | 
						|
          rwd << 'r' << char (x1) << char (x2);
 | 
						|
          rwd << 'o' << char (x2);
 | 
						|
        }
 | 
						|
        else if (y1 < l + 1 && y2 > l + 1)      // in ze middol
 | 
						|
        {
 | 
						|
          rwd << 'v' << char (x1);
 | 
						|
          rwd << 'v' << char (x2);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case 'l':
 | 
						|
        x1 = tt.get_int (1) + 1;
 | 
						|
        y1 = tt.get_int (2) + 1;
 | 
						|
        x2 = tt.get_int (3) + 1;
 | 
						|
        y2 = tt.get_int (4) + 1;
 | 
						|
        if (y1 == y2 && y1 == l + 1)    // orizzontale 
 | 
						|
        {
 | 
						|
          rwd << 'h' << char (x1) << char (x2);
 | 
						|
        }
 | 
						|
        else if (y1 <= l + 1 && y2 >= l + 1)    // verticale  
 | 
						|
 | 
						|
        {
 | 
						|
          rwd << 'v' << char (x1);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case 'r':
 | 
						|
        x1 = tt.get_int (1) + 1;
 | 
						|
        y1 = tt.get_int (2) + 1;
 | 
						|
        x2 = tt.get_int (3) + 1;
 | 
						|
        y2 = tt.get_int (4) + 1;
 | 
						|
        if (y1 == y2)    // orizzontale 
 | 
						|
        {                          
 | 
						|
          if (y1 == l+1)
 | 
						|
            rwd << 'r' << char (x1) << char (x2);
 | 
						|
        }
 | 
						|
        else 
 | 
						|
        {                  
 | 
						|
          const int l1 = l+1;
 | 
						|
          if (l1 >= y1 && l1 <= y2)    // verticale  
 | 
						|
          {                       
 | 
						|
            char code = 'v';
 | 
						|
            if (y1 == l1) code = 'u'; else 
 | 
						|
            if (y2 == l1) code = 'o';
 | 
						|
            rwd << code << char(x1);
 | 
						|
          }  
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case 't':
 | 
						|
        x1 = tt.get_int (1) + 1;
 | 
						|
        y1 = tt.get_int (2) + 1;        // al gh'e'
 | 
						|
        if (y1 == l + 1)
 | 
						|
        {}
 | 
						|
        break; 
 | 
						|
      case 'i':
 | 
						|
        id = tt.get_int();
 | 
						|
        x1 = tt.get_int();
 | 
						|
        y1 = tt.get_int();
 | 
						|
        x2 = tt.get_int();
 | 
						|
        y2 = tt.get_int();
 | 
						|
        if (l+1 >= y1 && l+1 <= y2)                                    
 | 
						|
          rwd << 'i' << char(id+1) << char(l-y1+2) << char(x1) 
 | 
						|
            << char(x2-x1+1) << char(y2-y1+1);
 | 
						|
        break;  
 | 
						|
      case 'W':
 | 
						|
        curwid = *(tt.get (1));
 | 
						|
        rwd << 'W' << curwid;
 | 
						|
        break;
 | 
						|
      case 'P':
 | 
						|
        curpen = *(tt.get (1));
 | 
						|
        rwd << 'P' << curpen;
 | 
						|
        break;
 | 
						|
      case 'B':
 | 
						|
        curpat = *(tt.get (1));
 | 
						|
        rwd << 'B' << curpat;
 | 
						|
        break;
 | 
						|
      case 'C':
 | 
						|
        curcol = *(tt.get (1));
 | 
						|
        rwd << 'C' << curcol;
 | 
						|
        break;
 | 
						|
      default:
 | 
						|
        break;  
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TPrinter::setbackground(const char *b)
 | 
						|
{
 | 
						|
  _background.destroy();
 | 
						|
  _bg_desc = b;
 | 
						|
  if (b != NULL)
 | 
						|
    parse_background(_bg_desc, _background);
 | 
						|
}
 | 
						|
 | 
						|
bool printers_on_key(TMask_field & f, KEY key);
 | 
						|
 | 
						|
// fv support structs for config
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @mfunc Legge la descrizione della stampante dal file
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risultato dell'operazione:
 | 
						|
//
 | 
						|
// @flag TRUE | Se e' riuscito a leggere la descrizione della stampante
 | 
						|
// @flag FALSE | Se non e' riuscito a leggere la descrizione della stampante
 | 
						|
bool PrinterDef::read(
 | 
						|
  const char *name,     // @parm Nome della stampante di cui cercarne la descrizione
 | 
						|
  FILE * fd)            // @parm Puntatore al file contenente la descrizione
 | 
						|
{
 | 
						|
  _printername = name;
 | 
						|
  _printername.trim ();
 | 
						|
 | 
						|
  TToken_string tmp (64, '=');
 | 
						|
  TString l (48);
 | 
						|
  TString r (16);
 | 
						|
 | 
						|
  while (TRUE)
 | 
						|
  {
 | 
						|
    const long p = ftell (fd);  // Memorizza inizio paragrafo
 | 
						|
 | 
						|
    if (fgets (__tmp_string, 256, fd) == NULL)
 | 
						|
      return FALSE;
 | 
						|
    tmp = __tmp_string;
 | 
						|
    tmp.trim ();
 | 
						|
 | 
						|
    if (tmp == "[End of File]")
 | 
						|
      return FALSE;
 | 
						|
 | 
						|
    if (tmp[0] == '[')
 | 
						|
    {
 | 
						|
      fseek (fd, p, SEEK_SET);  // Ritorna ad inizio paragrafo
 | 
						|
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    l = tmp.get ();
 | 
						|
    l.trim ();
 | 
						|
    r = tmp.get ();
 | 
						|
    r.trim ();
 | 
						|
 | 
						|
    if (l == "Device name")
 | 
						|
    {
 | 
						|
      _devicename = r;
 | 
						|
    }
 | 
						|
    else if (l == "Filter name")
 | 
						|
    {
 | 
						|
      _filtername = r;
 | 
						|
    }
 | 
						|
    else if (l == "Printer type")
 | 
						|
    {
 | 
						|
      _printertype = r;
 | 
						|
    }
 | 
						|
    else if (l == "Normal")
 | 
						|
    {
 | 
						|
      strcpy (_atstr[normalstyle], r);
 | 
						|
    }
 | 
						|
    else if (l == "Bold")
 | 
						|
    {
 | 
						|
      strcpy (_atstr[boldstyle], r);
 | 
						|
    }
 | 
						|
    else if (l == "Italic")
 | 
						|
    {
 | 
						|
      strcpy (_atstr[italicstyle], r);
 | 
						|
    }
 | 
						|
    else if (l == "Underlined")
 | 
						|
    {
 | 
						|
      strcpy (_atstr[underlinedstyle], r);
 | 
						|
    }
 | 
						|
    else if (l == "Code")
 | 
						|
    {
 | 
						|
      TToken_string code (r);
 | 
						|
      _names.add ( code.get() );
 | 
						|
      _codes.add ( code.get() );
 | 
						|
    }
 | 
						|
    else if (l == "Form feed")
 | 
						|
    {
 | 
						|
      _ffcode = r;
 | 
						|
    }
 | 
						|
    else if (l == "Newline")
 | 
						|
    {
 | 
						|
      _nlcode = r;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      return error_box ("Riga di configurazione stampante errata:\n%s", (const char *) l);
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
bool PrinterDef::isdefault ()
 | 
						|
{
 | 
						|
  return strcmp(_printername, "Default") == 0;
 | 
						|
}
 | 
						|
 | 
						|
////////// TPRINTROW //////////
 | 
						|
 | 
						|
TPrintrow::TPrintrow()
 | 
						|
{
 | 
						|
  reset();
 | 
						|
}
 | 
						|
 | 
						|
TPrintrow::TPrintrow(const TPrintrow& pr)
 | 
						|
{
 | 
						|
  _row = pr.row ();
 | 
						|
  memcpy (_attr, pr._attr, MAXSTR);
 | 
						|
  memcpy (_cols, pr._cols, MAXSTR);
 | 
						|
  _currentcolor = 'w';
 | 
						|
  _currentcolor <<= 8;
 | 
						|
  _currentcolor += 'n';
 | 
						|
  _currentstyle = pr._currentstyle;
 | 
						|
  for (int i = 0; i < MAXSTR; i++)
 | 
						|
    _cols[i] = _currentcolor;
 | 
						|
  _lastpos = pr._lastpos;
 | 
						|
}
 | 
						|
 | 
						|
TObject *TPrintrow::dup () const
 | 
						|
{
 | 
						|
  return new TPrintrow (*this);
 | 
						|
}
 | 
						|
 | 
						|
const char *TPrintrow::class_name () const
 | 
						|
{
 | 
						|
  return "Printrow";
 | 
						|
}
 | 
						|
 | 
						|
word TPrintrow::class_id()
 | 
						|
  const
 | 
						|
{
 | 
						|
  return CLASS_PRINTROW;
 | 
						|
}
 | 
						|
 | 
						|
TPrintrow& TPrintrow::reset()
 | 
						|
{
 | 
						|
  _row.spaces (sizeof(_attr));                       // Azzera testo
 | 
						|
 | 
						|
  memset(_attr, normalstyle, sizeof (_attr));        // Azzera stile
 | 
						|
  
 | 
						|
  _tab.reset();                                       // Azzera tabulazioni
 | 
						|
 | 
						|
  _currentcolor = 'w';
 | 
						|
  _currentcolor <<= 8;
 | 
						|
  _currentcolor += 'n';
 | 
						|
  for (int i = 0; i < MAXSTR; i++)
 | 
						|
    _cols[i] = _currentcolor;                         // Azzera colori
 | 
						|
  
 | 
						|
  _lastpos = 0;
 | 
						|
  _currentstyle = normalstyle;
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
const char* TPrintrow::row_codified() const
 | 
						|
{
 | 
						|
 | 
						|
  char last_attr = -1;
 | 
						|
  int last_color = -1;
 | 
						|
  int last = 0, k = 0, len = -1;     
 | 
						|
  
 | 
						|
  for (int i = 0; i < _row.size(); i++)
 | 
						|
    if (_row[i] > ' ') len = i;
 | 
						|
 | 
						|
  for (i = 0; i < _row.size(); i++)
 | 
						|
  {
 | 
						|
    if (_tab[i])
 | 
						|
    {
 | 
						|
      __tmp_string[k++] = '@'; 
 | 
						|
      __tmp_string[k++] = 't';
 | 
						|
    }  
 | 
						|
    
 | 
						|
    if (_attr[i] != last_attr)
 | 
						|
    {
 | 
						|
      __tmp_string[k++] = '@';
 | 
						|
      switch (_attr[i])
 | 
						|
      {
 | 
						|
      case normalstyle:
 | 
						|
        __tmp_string[k++] = 'r';
 | 
						|
        break;
 | 
						|
      case boldstyle:
 | 
						|
        __tmp_string[k++] = 'b';
 | 
						|
        break;
 | 
						|
      case italicstyle:
 | 
						|
        __tmp_string[k++] = 'i';
 | 
						|
        break;
 | 
						|
      case underlinedstyle:
 | 
						|
        __tmp_string[k++] = 'u';
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      last_attr = _attr[i];
 | 
						|
    }
 | 
						|
    if (_cols[i] != last_color &&  i <= len)
 | 
						|
    {
 | 
						|
      __tmp_string[k++] = '$';
 | 
						|
      __tmp_string[k++] = '[';
 | 
						|
      __tmp_string[k++] = (char) (_cols[i] & 0x00ff);
 | 
						|
      __tmp_string[k++] = ',';
 | 
						|
      __tmp_string[k++] = (char) (_cols[i] >> 8);
 | 
						|
      __tmp_string[k++] = ']';
 | 
						|
      last_color = _cols[i];
 | 
						|
    }
 | 
						|
    __tmp_string[k++] = _row[i];
 | 
						|
    if (_row[i] > ' ') last = k;
 | 
						|
  }
 | 
						|
 | 
						|
  __tmp_string[last] = '\0';
 | 
						|
  return __tmp_string;
 | 
						|
}
 | 
						|
 | 
						|
TPrintrow& TPrintrow::put(const char *str, int position, int len)
 | 
						|
{
 | 
						|
  if (len < 1)
 | 
						|
    len = strlen (str);
 | 
						|
  
 | 
						|
  if (position < 0)
 | 
						|
    position = _lastpos;
 | 
						|
  else
 | 
						|
    _tab.set(position);  
 | 
						|
 | 
						|
  char bg = 'w', fg = 'n';
 | 
						|
  for (int i = 0; i < len; i++)
 | 
						|
  {
 | 
						|
    char c = str[i];
 | 
						|
    if (c == '$' && str[i + 1] == '[')
 | 
						|
    {
 | 
						|
      ++i;
 | 
						|
      fg = str[++i];
 | 
						|
      c = str[++i];
 | 
						|
      if (c == ']')
 | 
						|
        bg = _currentcolor >> 8;
 | 
						|
      else if (c == ',')
 | 
						|
      {
 | 
						|
        bg = str[++i];
 | 
						|
        i++;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        CHECK (0, "Error in color specification");
 | 
						|
      }
 | 
						|
      _currentcolor = (bg << 8) + fg;
 | 
						|
    }
 | 
						|
    else if (c == '@')
 | 
						|
    {
 | 
						|
      c = str[++i];
 | 
						|
      switch (toupper (c))
 | 
						|
      {
 | 
						|
      case '#':
 | 
						|
      case '<':
 | 
						|
      case '>':
 | 
						|
        // printer MUST handle them
 | 
						|
      {
 | 
						|
        const int n = (c == '#') ? 5 : ((c == '>') ? 10 : 8);
 | 
						|
        _row[position] = '@';
 | 
						|
        _attr[position++] = _currentstyle;
 | 
						|
        for (int j = 1; j < n; j++)
 | 
						|
        {
 | 
						|
          _row[position] = c;
 | 
						|
          _attr[position++] = _currentstyle;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break; 
 | 
						|
    case 'T':
 | 
						|
      _tab.set(position);
 | 
						|
      break;
 | 
						|
    case 'B':
 | 
						|
      _currentstyle = boldstyle;
 | 
						|
      break;
 | 
						|
    case 'I':
 | 
						|
      _currentstyle = italicstyle;
 | 
						|
      break;
 | 
						|
    case 'U':
 | 
						|
      _currentstyle = underlinedstyle;
 | 
						|
      break;
 | 
						|
    case 'R':
 | 
						|
      _currentstyle = normalstyle;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      // should be number followed by skip or jump
 | 
						|
      if (isdigit (c))
 | 
						|
      {
 | 
						|
        // read number
 | 
						|
        char digbuf[8];
 | 
						|
        int cnt = 0;
 | 
						|
        digbuf[cnt++] = c;
 | 
						|
        while (isdigit (c = str[++i]))
 | 
						|
          digbuf[cnt++] = c;
 | 
						|
        digbuf[cnt] = '\0';
 | 
						|
        int pp = atoi (digbuf);
 | 
						|
        if (toupper (c) == 'G')
 | 
						|
        {
 | 
						|
          if (pp >= MAXSTR)
 | 
						|
            fatal_box ("printrow reaches position %d", pp);
 | 
						|
          if (pp > position)
 | 
						|
            for (int k = position; k < pp; k++)
 | 
						|
            {
 | 
						|
              _attr[k] = _currentstyle;
 | 
						|
              _cols[k] = _currentcolor;
 | 
						|
            }
 | 
						|
          position = pp;
 | 
						|
          _tab.set(position);
 | 
						|
        }
 | 
						|
        else if (toupper (c) == 'J')
 | 
						|
        {
 | 
						|
          if (pp + position >= MAXSTR)
 | 
						|
            fatal_box ("printrow reaches position %d", pp + position);
 | 
						|
          for (int k = 0; k < pp; k++)
 | 
						|
          {
 | 
						|
            _attr[k + position] = _currentstyle;
 | 
						|
            _cols[k + position] = _currentcolor;
 | 
						|
          }
 | 
						|
          position += pp;
 | 
						|
          _tab.set(position);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        _row[position] = c;
 | 
						|
        _attr[position++] = _currentstyle;
 | 
						|
        _cols[position++] = _currentcolor;
 | 
						|
      }
 | 
						|
    }                   // switch
 | 
						|
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      _row[position] = c;
 | 
						|
      _attr[position] = _currentstyle;
 | 
						|
      _cols[position++] = _currentcolor;
 | 
						|
    }
 | 
						|
  }                             // for
 | 
						|
 | 
						|
  _lastpos = position;
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
////////// TPRINTER //////////
 | 
						|
 | 
						|
HIDDEN bool printer_handler (TMask_field & f, KEY key)
 | 
						|
{
 | 
						|
  if (key == K_SPACE)
 | 
						|
  {
 | 
						|
    TToken_string pn1(10), pn2(80);
 | 
						|
 | 
						|
    const PrinterDef & def = printer().get_description(atoi(f.get ()));
 | 
						|
    const char *s;
 | 
						|
    int j = 0;
 | 
						|
    while ((s = def.get_codenames (j)) != NULL)
 | 
						|
    {
 | 
						|
      pn1.add (format ("%02d", j));
 | 
						|
      pn2.add (s);
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
    ((TList_field &) f.mask ().field (MSK_CODES)).replace_items (pn1, pn2);
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void TPrinter::set_printrcd()
 | 
						|
{
 | 
						|
  if (_print_rcd != NULL)
 | 
						|
    xvt_print_destroy(_print_rcd);
 | 
						|
  _print_rcd = xvt_print_create(&_print_rcd_size);
 | 
						|
}
 | 
						|
 | 
						|
PRINT_RCD* TPrinter::get_printrcd(int *size)
 | 
						|
{
 | 
						|
  if (_print_rcd == NULL || !xvt_print_is_valid(_print_rcd)) 
 | 
						|
    set_printrcd();
 | 
						|
  if (size != NULL) *size = _print_rcd_size;  
 | 
						|
  return _print_rcd;  
 | 
						|
}
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Setta le caratteristiche della stampante leggendole da <p _print_rcd>
 | 
						|
void TPrinter::set_win_formlen(
 | 
						|
  WINDOW prwin) // @parm Finestra effettiva di stampa (default NULL_WIN)
 | 
						|
 | 
						|
  // @comm Nel caso <p prwin> sia NULL_WIN vengono solamente aggiornati i valori
 | 
						|
{
 | 
						|
  long pw, ph, phr, pvr; // Printer width, height, horizontal and vertical resolution
 | 
						|
  xvt_app_escape (XVT_ESC_GET_PRINTER_INFO, get_printrcd(), &ph, &pw, &pvr, &phr);
 | 
						|
  
 | 
						|
  if (pvr != 0)
 | 
						|
  {
 | 
						|
    _formlen       = int(ph * _lines_per_inch / pvr);   // Total number of lines per page
 | 
						|
    _dots_per_line = int(pvr / _lines_per_inch);        // Number of point per line
 | 
						|
    _vert_offset   = (int)(ph - ((long)_formlen * _dots_per_line)) >> 1;
 | 
						|
 | 
						|
    if (prwin != NULL_WIN)
 | 
						|
    {
 | 
						|
      TString256 spc; spc.spaces(256);                  // Compute maximun number of chars per line
 | 
						|
      int w = 0;
 | 
						|
      for (_formwidth = 256; _formwidth >= 80; _formwidth--)
 | 
						|
      {
 | 
						|
        w = xvt_dwin_get_text_width(prwin, (char*)(const char*)spc, _formwidth);
 | 
						|
        if (w < pw) break;
 | 
						|
      }     
 | 
						|
      _horz_offset = (_formwidth > 80) ? (int)(pw - w)/2 : 0;         
 | 
						|
    }
 | 
						|
    else 
 | 
						|
    {
 | 
						|
      _formwidth = 256;
 | 
						|
      _horz_offset = 0;
 | 
						|
    }                      
 | 
						|
  }
 | 
						|
  else
 | 
						|
    warning_box ("Il driver della stampante non e' valido.\n"
 | 
						|
                 "Non stampare prima di averlo reinstallato");
 | 
						|
}
 | 
						|
 | 
						|
// Handler della maschera di setup
 | 
						|
HIDDEN bool set_windows_print_device (TMask_field& f, KEY key)
 | 
						|
{
 | 
						|
  if (key == K_SPACE)
 | 
						|
  {             
 | 
						|
    main_app().begin_wait();
 | 
						|
    TPrinter& pr = printer();
 | 
						|
    
 | 
						|
    if (f.dirty())
 | 
						|
    {
 | 
						|
      TToken_string& pn = pr.getprinternames ();
 | 
						|
      TString80 pdev (pn.get(atoi (f.get())));          // Nome stampante corrente
 | 
						|
      
 | 
						|
      char szDevice[80];  
 | 
						|
      GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice));
 | 
						|
      pdev << "," << szDevice;
 | 
						|
 | 
						|
      // scrivi (e semmai lo si risistema poi)             
 | 
						|
      WriteProfileString("windows", "device", pdev);
 | 
						|
      pr.set_printrcd();
 | 
						|
      pr.set_win_formlen();
 | 
						|
    }
 | 
						|
    
 | 
						|
    const int MAX_FAMILIES = 128;
 | 
						|
    char* family[MAX_FAMILIES];
 | 
						|
    const int num_families = (int)xvt_fmap_get_families(pr.get_printrcd(), family, MAX_FAMILIES);
 | 
						|
    TToken_string pn1(256), pn2(256);                                                    
 | 
						|
 | 
						|
    //    const int MAXSIZES = 16;
 | 
						|
    //    long sizes[MAXSIZES]; 
 | 
						|
    //    BOOLEAN scalable;
 | 
						|
 | 
						|
    for (int i = 0; i < num_families; i++)
 | 
						|
    {
 | 
						|
      //     const int num_sizes = (int)xvt_fmap_get_family_sizes(pr.get_printrcd(), 
 | 
						|
      //                                                          family[i], sizes, &scalable, MAXSIZES);
 | 
						|
      //     if (num_sizes > 0)
 | 
						|
    {
 | 
						|
      pn1.add(family[i]);
 | 
						|
      pn2.add(family[i]);
 | 
						|
    }  
 | 
						|
    xvt_mem_free(family[i]);
 | 
						|
  }       
 | 
						|
    
 | 
						|
    TMask& m = f.mask();
 | 
						|
    TList_field& lst = (TList_field&)m.field(MSK_FONT);
 | 
						|
    
 | 
						|
    lst.replace_items(pn1, pn2);  
 | 
						|
    lst.set(printer().fontname());
 | 
						|
    
 | 
						|
    main_app().end_wait();
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
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(MSK_SIZE);
 | 
						|
    lst.replace_items(pn1, pn2);
 | 
						|
    lst.set(format("%d", printer().get_char_size()));
 | 
						|
    
 | 
						|
    main_app().end_wait();           
 | 
						|
  }   
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
TPrinter::TPrinter()
 | 
						|
: _date (TODAY), _multiple_link (FALSE), _frozen (FALSE), _isgraphics (TRUE),
 | 
						|
  _lines_per_inch (6), _ch_size (12), _ncopies(1), _export_header(FALSE),
 | 
						|
  _export_header_len(0), _vf(NULL), _l_offset(0), _c_offset(0)
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
  , _print_rcd(NULL)
 | 
						|
#endif
 | 
						|
 | 
						|
{
 | 
						|
  _footerhandler = _headerhandler = NULL;
 | 
						|
  _linkhandler = NULL;
 | 
						|
  _curprn = 0;                  // first in list if no default is specified
 | 
						|
 | 
						|
  _curcode = 0;                 // first in list if no default is specified
 | 
						|
 | 
						|
  _formlen = 66;
 | 
						|
  _frompage = 0;
 | 
						|
  _topage = 0xffff;
 | 
						|
  _hwformfeed = FALSE;
 | 
						|
  _currentpage = 1;
 | 
						|
  _currentrow = 1;
 | 
						|
  _fp = NULL;
 | 
						|
  _headersize = 0;
 | 
						|
  _footersize = 0;
 | 
						|
  _isopen = FALSE;
 | 
						|
  _multiple_copies = main_app().class_id() == CLASS_PRINT_APPLICATION;
 | 
						|
  
 | 
						|
  // read configuration file
 | 
						|
  read_configuration ();
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
  //  xvt_print_open ();           
 | 
						|
  set_win_formlen ();
 | 
						|
 | 
						|
  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);
 | 
						|
  
 | 
						|
  const TString80 p1(pdev.get(0));              // current printer
 | 
						|
  TToken_string& pn2 = getprinternames();       // get printer names
 | 
						|
  _curprn = pn2.get_pos(p1);
 | 
						|
  CHECKS(_curprn >= 0, "Can't find printer ", (const char*)p1);
 | 
						|
  
 | 
						|
  set_fincatura("+++++++++-|");                
 | 
						|
#else
 | 
						|
  _isgraphics = FALSE;
 | 
						|
#endif             
 | 
						|
 | 
						|
  _finker = _isgraphics ? NULL : new TPrint_intersector(_fink, _formlen);
 | 
						|
}
 | 
						|
 | 
						|
bool TPrinter::isfax() const
 | 
						|
{ 
 | 
						|
  bool fax = _printertype == winprinter || _printertype == screenvis;
 | 
						|
  if (fax)
 | 
						|
  {
 | 
						|
    const char* name = (const char*)((TPrinter*)this)->get_printrcd() + 4;
 | 
						|
    TToken_string p(256, ',');
 | 
						|
    GetProfileString ("devices", name, "", (char*)(const char*)p, p.size());
 | 
						|
    const char * driver = p.get(1);
 | 
						|
    fax = driver != NULL && stricmp(driver, "EASYFAX") == 0;
 | 
						|
  }  
 | 
						|
  return fax;
 | 
						|
}
 | 
						|
 | 
						|
TToken_string& TPrinter::getprinternames ()
 | 
						|
{
 | 
						|
  // per ora va solo in windows
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
  if (_printer_names.empty())
 | 
						|
    _get_windows_printer_names(_printer_names);
 | 
						|
#endif
 | 
						|
  return _printer_names;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Legge la configurazione della stampante
 | 
						|
void TPrinter::read_configuration(
 | 
						|
  const char* parag)    // parm Nome del file di configurazione della stampante (default NULL)
 | 
						|
 | 
						|
  // @comm Se <p parag> e' NULL viene letta la configurazione della stamapnte di default.
 | 
						|
{                  
 | 
						|
  main_app().begin_wait();
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_SCOUNIX
 | 
						|
  const char* const config = "printer.ini";
 | 
						|
  FILE *cnfp = fopen (config, "r");
 | 
						|
  if (cnfp == NULL)
 | 
						|
    fatal_box ("Impossibile aprire il file %s", config);
 | 
						|
 | 
						|
  for (int i = 0; !feof (cnfp); i++)
 | 
						|
  {
 | 
						|
    if (fgets (__tmp_string, 256, cnfp) == NULL)
 | 
						|
      return;
 | 
						|
    // else
 | 
						|
    if (strncmp (__tmp_string, "[Default]", 9) != 0)
 | 
						|
      // fgets(__tmp_string,256,cnfp);
 | 
						|
      // else
 | 
						|
    {
 | 
						|
      if (*__tmp_string == '[')
 | 
						|
      {
 | 
						|
        // fatal_box("[ expected in file of printer configuration");
 | 
						|
 | 
						|
        char *u = strchr (__tmp_string, ']');
 | 
						|
        if (u)
 | 
						|
          *u = '\0';
 | 
						|
        u = __tmp_string + 1;
 | 
						|
 | 
						|
        PrinterDef *pp = new PrinterDef;
 | 
						|
        _printers.add (pp);
 | 
						|
        if (pp->read (u, cnfp) == FALSE)
 | 
						|
          break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  fclose (cnfp);
 | 
						|
 | 
						|
#endif
 | 
						|
  
 | 
						|
  _config = parag;                                            // Inizializza nome configurazione
 | 
						|
  if (_config.empty())                                        // Se non specificata ...
 | 
						|
    _config = "Printer";                                      // ... usa configurazione standard
 | 
						|
 | 
						|
  TConfig* iniptr = NULL;                         
 | 
						|
  if (_config != "Printer")                                   // Cerca configurazione speciale
 | 
						|
  {                                                           
 | 
						|
    iniptr = new TConfig(CONFIG_STAMPE, _config);
 | 
						|
    const int what = iniptr->get_int("Type", NULL, -1, -1);
 | 
						|
    if (what < 0)                                             // Se configurazione annullata ...
 | 
						|
    { 
 | 
						|
      delete iniptr; iniptr = NULL;                            
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (iniptr == NULL)
 | 
						|
    iniptr = new TConfig(CONFIG_USER, "Printer");
 | 
						|
 | 
						|
  const int what = iniptr->get_int("Type", NULL, -1, 0);      // Tipo stampante
 | 
						|
  _curprn = iniptr->get_int("Number", NULL, -1, 0);           // Numero stampante corrente
 | 
						|
  _printerfile = iniptr->get("File", NULL, -1, "");           // File di stampa                
 | 
						|
  _curcode = iniptr->get_int("Codes", NULL, -1, 0);           // Codici di stampa               
 | 
						|
  _fontname = iniptr->get("Font", NULL, -1, XVT_FFN_FIXED);   // Nome del font
 | 
						|
  _ch_size = iniptr->get_int("Size", NULL, -1, 12);           // Dimensione del font
 | 
						|
  _lines_per_inch = iniptr->get_int("Lines", NULL, -1, 6);    // Linee per pollice
 | 
						|
  _isgraphics = iniptr->get_bool("Graphic", NULL, -1, FALSE); // Grafica attiva
 | 
						|
  
 | 
						|
  if (iniptr->exist("rcd", 0))
 | 
						|
  {              
 | 
						|
    int size, i = 0;
 | 
						|
    byte* rcd = (byte*)get_printrcd(&size);
 | 
						|
 | 
						|
    TToken_string s(256);         
 | 
						|
    for (int index = 0; i < size; index++)
 | 
						|
    {
 | 
						|
      s = iniptr->get("rcd", NULL, index);
 | 
						|
      for (const char* n = s.get(0); n; n = s.get())
 | 
						|
        rcd[i++] = (byte)atoi(n);
 | 
						|
    }
 | 
						|
  }           
 | 
						|
  
 | 
						|
  delete iniptr; iniptr = NULL;
 | 
						|
  
 | 
						|
  if (_printerfile.empty())
 | 
						|
  {
 | 
						|
    _printerfile.tempdir();
 | 
						|
#if XVT_OS == XVT_OS_SCOUNIX
 | 
						|
    _printerfile << '/';
 | 
						|
#else
 | 
						|
    _printerfile << '\\';
 | 
						|
#endif    
 | 
						|
  }                                                 
 | 
						|
  
 | 
						|
  if (_config == "Printer" || _printertype == winprinter)
 | 
						|
    switch (what)
 | 
						|
    {
 | 
						|
    case 0:
 | 
						|
    case 5:  
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
      _printertype = winprinter;
 | 
						|
#else
 | 
						|
      PrinterDef & def = (PrinterDef &) get_description (_curprn);
 | 
						|
      switch (atoi (def._printertype))
 | 
						|
      {
 | 
						|
      case 1:
 | 
						|
        _printertype = localprinter;
 | 
						|
        break;
 | 
						|
      case 2:
 | 
						|
        _printertype = spoolprinter;
 | 
						|
        break;
 | 
						|
      default:
 | 
						|
        _printertype = normprinter;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
#endif
 | 
						|
      break;
 | 
						|
    case 1:             // file
 | 
						|
      _printertype = fileprinter;
 | 
						|
      break;
 | 
						|
    case 4:             // video
 | 
						|
      _printertype = screenvis;
 | 
						|
      _curcode = 0;
 | 
						|
      break;
 | 
						|
    case 6:             // export
 | 
						|
      _printertype = export;
 | 
						|
      _curcode = 0;
 | 
						|
      break;
 | 
						|
    default:      
 | 
						|
      break;  
 | 
						|
    }                     
 | 
						|
  
 | 
						|
  main_app().end_wait();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TPrinter::save_configuration()
 | 
						|
{ 
 | 
						|
  main_app().begin_wait();
 | 
						|
 | 
						|
  CHECK(_config.not_empty(), "Invalid printer config");
 | 
						|
  TConfig prini(_config == "Printer" ? CONFIG_USER : CONFIG_STAMPE, _config);
 | 
						|
  
 | 
						|
  prini.set("Type", _printertype);              // Tipo stampante
 | 
						|
  prini.set("Number", _curprn);                 // Numero stampante corrente
 | 
						|
  prini.set("File", _printerfile);              // File di stampa                
 | 
						|
  prini.set("Codes", _curcode);                 // Codici di stampa               
 | 
						|
  prini.set("Font", _fontname);                 // Nome del font
 | 
						|
  prini.set("Size", _ch_size);                  // Dimensione del font
 | 
						|
  prini.set("Lines", _lines_per_inch);          // Linee per pollice
 | 
						|
  prini.set("Graphic", _isgraphics ? "X" : ""); // Grafica attiva
 | 
						|
  
 | 
						|
  int n = 0, index = 0;       
 | 
						|
  TToken_string val(256);             
 | 
						|
  
 | 
						|
  int rcdsize;                                      
 | 
						|
  byte* rcd = (byte*)get_printrcd(&rcdsize);
 | 
						|
  
 | 
						|
  for (int i = 0; i < rcdsize; i++)
 | 
						|
  {             
 | 
						|
    val.add((int)rcd[i]);
 | 
						|
    n++;
 | 
						|
    if (n == 24)
 | 
						|
    {
 | 
						|
      prini.set("rcd", val, NULL, TRUE, index++);
 | 
						|
      val.cut(n = 0);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (n > 0)
 | 
						|
    prini.set("rcd", val, NULL, TRUE, index);
 | 
						|
  
 | 
						|
  main_app().end_wait();
 | 
						|
}
 | 
						|
 | 
						|
TPrinter::~TPrinter ()
 | 
						|
{
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
  if (_print_rcd != NULL)
 | 
						|
  {
 | 
						|
    xvt_print_destroy(_print_rcd);
 | 
						|
    _print_rcd = NULL;
 | 
						|
  }  
 | 
						|
  // xvt_print_close();
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
const char* TPrinter::class_name () const
 | 
						|
{
 | 
						|
  return "Printer";
 | 
						|
}
 | 
						|
 | 
						|
word TPrinter::class_id () const
 | 
						|
{
 | 
						|
  return CLASS_PRINTER;
 | 
						|
}
 | 
						|
 | 
						|
TPrintrow *TPrinter::getheaderline (int linetoget)
 | 
						|
{
 | 
						|
  return ((TPrintrow *) _header.objptr (linetoget));
 | 
						|
}
 | 
						|
 | 
						|
TPrintrow *TPrinter::getfooterline (int linetoget)
 | 
						|
{
 | 
						|
  return ((TPrintrow *) _footer.objptr (linetoget));
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Setta il contenuto di una line dell'header
 | 
						|
void TPrinter::setheaderline (
 | 
						|
  int linetoset,        // @parm Numero della linea da settare
 | 
						|
  TPrintrow * line)     // @parm Contenuto della linea dell'header
 | 
						|
  // @parm const TPrintrow& | line | Indirizzo con il contenuto della 
 | 
						|
  //     linea dell'header
 | 
						|
 | 
						|
  // @syntax void setheaderline (int linetoset, TPrintrow* line);
 | 
						|
  // @syntax void setheaderline (int linetoset, const TPrintrow& line);
 | 
						|
 | 
						|
{
 | 
						|
  _header.add (line, linetoset);
 | 
						|
  if (linetoset >= _headersize)
 | 
						|
    _headersize = linetoset + 1;
 | 
						|
}
 | 
						|
 | 
						|
void TPrinter::setheaderline (int linetoset, const TPrintrow & line)
 | 
						|
{
 | 
						|
  TPrintrow *p = new TPrintrow (line);
 | 
						|
  setheaderline (linetoset, p);
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Setta il contenuto di una line dell'header
 | 
						|
void TPrinter::setfooterline (
 | 
						|
  int linetoset,        // @parm Numero della linea da settare
 | 
						|
  TPrintrow * line)     // @parm Contenuto della linea del footer
 | 
						|
  // @parm const TPrintrow& | line | Indirizzo con il contenuto della 
 | 
						|
  //     linea del footer
 | 
						|
 | 
						|
  // @syntax void setfooterline (int linetoset, TPrintrow* line);
 | 
						|
  // @syntax void setfooterline (int linetoset, const TPrintrow& line);
 | 
						|
 | 
						|
{
 | 
						|
  _footer.add (line, linetoset);
 | 
						|
}
 | 
						|
 | 
						|
void TPrinter::setfooterline (int linetoset, const TPrintrow& line)
 | 
						|
{
 | 
						|
  TPrintrow *p = new TPrintrow (line);
 | 
						|
  setfooterline (linetoset, p);
 | 
						|
}
 | 
						|
 | 
						|
void TPrinter::resetheader ()
 | 
						|
{
 | 
						|
  _header.destroy ();
 | 
						|
  _headersize = 0;
 | 
						|
}
 | 
						|
 | 
						|
void TPrinter::resetfooter ()
 | 
						|
{
 | 
						|
  _footer.destroy ();
 | 
						|
  // _footersize = 0;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Metodo base per la stampa
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risulato della stampa:
 | 
						|
//
 | 
						|
// @flag TRUE | Se la stampa ha avuto successo
 | 
						|
// @flag FALSE | Se la stampante non e' attiva
 | 
						|
bool TPrinter::printrow(
 | 
						|
  TPrintrow* rowtoprint) // @parm Riga da stampare
 | 
						|
 | 
						|
  // @comm Se la pagina logica corrente e' precedente alla prima pagina logica o successiva
 | 
						|
  //     all'ultima pagina logica viene ritornato TRUE.
 | 
						|
{
 | 
						|
  if (!isopen ())
 | 
						|
    return FALSE;
 | 
						|
 | 
						|
  if (_currentpage < _frompage || _currentpage > _topage)
 | 
						|
    return TRUE;
 | 
						|
 | 
						|
  TString rw (rowtoprint == NULL ? "" : (_printertype == screenvis || _printertype == winprinter || 
 | 
						|
                                         _printertype == export ? 
 | 
						|
                                         rowtoprint->row_codified () :
 | 
						|
                                         rowtoprint->row ()));
 | 
						|
  rw.rtrim ();
 | 
						|
 | 
						|
  int lun = rw.len ();
 | 
						|
  int idx;
 | 
						|
  
 | 
						|
  if (_printertype != export)
 | 
						|
  {
 | 
						|
    for (idx = 0; idx < lun; idx++)
 | 
						|
    {
 | 
						|
      if (rw[idx] == '@') // gestione data e n. di pagina      
 | 
						|
      {
 | 
						|
        switch (rw[idx + 1])
 | 
						|
        {
 | 
						|
        case '#':
 | 
						|
          rw.overwrite (format("%-5u", _currentpage), idx++);
 | 
						|
          break;
 | 
						|
        case '>':
 | 
						|
          rw.overwrite (_date.string (full), idx++);
 | 
						|
          break;
 | 
						|
        case '<':
 | 
						|
          rw.overwrite (_date.string (brief), idx++);
 | 
						|
          break;
 | 
						|
        default:
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (_printertype == screenvis)
 | 
						|
  {
 | 
						|
    if (!_vf->frozen ())
 | 
						|
      _vf->add_line(rw);
 | 
						|
    else
 | 
						|
      _frozen = TRUE;
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (_printertype == winprinter || _printertype == export)
 | 
						|
  {
 | 
						|
    // add line to txt
 | 
						|
    if (!_frozen)
 | 
						|
      _txt.append(rw);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
 | 
						|
  if (_printertype == fileprinter)
 | 
						|
  {
 | 
						|
    // add line to txt
 | 
						|
    if (!_frozen)
 | 
						|
      _txt.append (rw);
 | 
						|
    return TRUE;
 | 
						|
 | 
						|
  }
 | 
						|
#else
 | 
						|
 | 
						|
  const PrinterDef & pd = get_description (_curprn);
 | 
						|
  int prvstl = -1;
 | 
						|
  for (idx = 0; idx < lun; idx++)
 | 
						|
  {
 | 
						|
    int cst = rowtoprint->get_style (idx);
 | 
						|
    if (cst != prvstl)
 | 
						|
    {
 | 
						|
      fprintf (_fp, "%s", pd._atstr[normalstyle]);
 | 
						|
      if (cst != normalstyle)
 | 
						|
        fprintf (_fp, "%s", pd._atstr[cst]);
 | 
						|
    }
 | 
						|
    prvstl = cst;
 | 
						|
    putc (rw[idx], _fp);
 | 
						|
  }
 | 
						|
  if (newline ())
 | 
						|
    putc (newline (), _fp);
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
word TPrinter::rows_left() const
 | 
						|
{
 | 
						|
  word left = _formlen - _currentrow - _footersize + 1;
 | 
						|
  if (_currentrow < 2)
 | 
						|
    left -= _headersize;
 | 
						|
  return left;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Permette di stampare una riga
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risultato della stampa:
 | 
						|
//
 | 
						|
// @flag TRUE | Se la stampa ha avuto successo
 | 
						|
// @flag FALSE | Se non e' riuscito ad effettuare la stampa
 | 
						|
bool TPrinter::print(
 | 
						|
  TPrintrow& rowtoprint)        // @parm Riga da stampare
 | 
						|
 | 
						|
  // @comm Nel caso la riga non ci stia nella pagina logica corrente vengono stampanti il footer
 | 
						|
  //     della pagina corrente e l'header della successiva prima prima della stampa della riga
 | 
						|
  //     vera e propria.
 | 
						|
{
 | 
						|
  bool ok = TRUE;
 | 
						|
 | 
						|
  if (!(_printertype == export && !_export_header))
 | 
						|
  {
 | 
						|
    if (_currentrow > _formlen - _footersize)
 | 
						|
      ok = printfooter ();
 | 
						|
 | 
						|
    if (ok && _currentrow == 1)
 | 
						|
      ok = printheader();
 | 
						|
  }
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    ok = printrow(&rowtoprint);
 | 
						|
    _currentrow++;
 | 
						|
  }
 | 
						|
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TPrinter::printheader()
 | 
						|
{
 | 
						|
  if (_headerhandler)
 | 
						|
    _headerhandler (*this);
 | 
						|
 | 
						|
  bool ok = TRUE;
 | 
						|
  for (int i = 0; i < _headersize && ok; i++)
 | 
						|
    ok = printrow(getheaderline(i));
 | 
						|
 | 
						|
  _currentrow = _headersize + 1;
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TPrinter::printfooter()
 | 
						|
{
 | 
						|
  if (_footerhandler)
 | 
						|
    _footerhandler (*this);
 | 
						|
 | 
						|
  bool ok = TRUE;
 | 
						|
  for (int i = 0; i < _footersize && ok; i++)
 | 
						|
    ok = printrow(getfooterline(i));
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_SCOUNIX
 | 
						|
  if (ok)
 | 
						|
    printformfeed();
 | 
						|
#endif
 | 
						|
 | 
						|
  _currentrow = 1;
 | 
						|
  _currentpage++;
 | 
						|
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Permette di saltare alcune righe dalla posizione corrente
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risulato dell'operazione:
 | 
						|
//
 | 
						|
// @flag TRUE | Se e' riuscito a saltare le righe
 | 
						|
// @flag FALSE | Se non e' riuscito a saltare le righe
 | 
						|
bool TPrinter::skip(
 | 
						|
  int linestoskip)      // @parm Vengono accettai solo valori positivi
 | 
						|
 | 
						|
  // @xref <mf TPrinter::jump>
 | 
						|
{
 | 
						|
  int jumpline;
 | 
						|
 | 
						|
  CHECK (linestoskip >= 0, "Linestoskip can't be negative");
 | 
						|
  jumpline = _currentrow + linestoskip;
 | 
						|
  return jump(jumpline);
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Permette di saltare alla riga indicata
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risultato dell'operazione
 | 
						|
//
 | 
						|
// @flag TRUE | Se e' riuscito a saltare alla riga
 | 
						|
// @flag FALSE | Se non e' riuscito a saltare alla riga o se viene inserito un formfeed
 | 
						|
bool TPrinter::jump(
 | 
						|
  int jumpline) // @parm Numero della riga a cui saltare nella stampa. Vengono accettai
 | 
						|
  //     solo valori positivi
 | 
						|
 | 
						|
  // @comm Nel caso si cerchi di saltare ad una riga superiore alla lunghezza della pagina attiva
 | 
						|
  //     viene inserito un formfeed.
 | 
						|
 | 
						|
  // @xref <mf TPrinter::skip>
 | 
						|
{
 | 
						|
  int i = 0;
 | 
						|
  bool ok = TRUE;
 | 
						|
 | 
						|
  CHECK (jumpline >= 0, "Jumpline can't be negative");
 | 
						|
  if (jumpline > _formlen - _footersize)
 | 
						|
    ok = formfeed();
 | 
						|
  else
 | 
						|
    for (i = _currentrow; i < jumpline; i++)
 | 
						|
      if (!printrow())
 | 
						|
        ok = FALSE;
 | 
						|
  if (jumpline > _formlen - _footersize)
 | 
						|
    ok = FALSE;
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TPrinter::formfeed()
 | 
						|
{
 | 
						|
  const int lastrow = _formlen - _footersize;
 | 
						|
  for (; _currentrow + _export_header_len <= lastrow; _currentrow++)
 | 
						|
    printrow();
 | 
						|
  return printfooter();
 | 
						|
}
 | 
						|
 | 
						|
void TPrinter::reset()
 | 
						|
{
 | 
						|
  resetheader();
 | 
						|
  resetfooter();
 | 
						|
  _currentpage = 1;
 | 
						|
  _currentrow  = 1;
 | 
						|
}
 | 
						|
 | 
						|
bool TPrinter::printformfeed()
 | 
						|
{
 | 
						|
#if XVT_OS == XVT_OS_SCOUNIX
 | 
						|
  const PrinterDef & pd = get_description(_curprn);
 | 
						|
 | 
						|
  if (_printertype != screenvis && _hwformfeed)
 | 
						|
    fprintf(_fp, "%s",(const char *)pd._ffcode);
 | 
						|
#endif
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
bool TPrinter::open()
 | 
						|
{
 | 
						|
#if  XVT_OS==XVT_OS_SCOUNIX
 | 
						|
  if (_printertype == spoolprinter)
 | 
						|
  {
 | 
						|
    const PrinterDef & def = get_description(_curprn);
 | 
						|
    int pfd[2];
 | 
						|
 | 
						|
    if (pipe(pfd) == -1)
 | 
						|
      return error_box ("Impossibile creare processo di stampa " "(pipe)");
 | 
						|
 | 
						|
    int ret = fork();
 | 
						|
    if (ret == -1)
 | 
						|
      return error_box("Impossibile creare processo di stampa " "(fork)");
 | 
						|
 | 
						|
    if (ret == 0)
 | 
						|
    {
 | 
						|
      if ((::close(0) != -1) && (::dup(pfd[0]) == 0) &&
 | 
						|
          (::close(pfd[0]) == 0) && (::close(pfd[1]) != -1))
 | 
						|
      {
 | 
						|
        char s0[80];
 | 
						|
 | 
						|
        sprintf (s0, "-d%s", (const char *) def._devicename);
 | 
						|
        if ((def._filtername).not_empty ())
 | 
						|
        {
 | 
						|
          char s1[80];
 | 
						|
          sprintf (s1, "-o %s", (const char *) def._filtername);
 | 
						|
          char *ws[5] =
 | 
						|
          {"lpr", "-s", s0, s1, NULL};
 | 
						|
          execvp (ws[0], ws);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          char *ws[4] =
 | 
						|
          {"lpr", "-s", s0, NULL};
 | 
						|
          execvp(ws[0], ws);
 | 
						|
        }
 | 
						|
        exit(-1);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if ((::close (pfd[0]) == -1) || ((_fp = fdopen(pfd[1], "w")) == NULL))
 | 
						|
      return error_box ("Impossibile creare processo di stampa" "(close)");
 | 
						|
  }
 | 
						|
  else
 | 
						|
#endif
 | 
						|
    if (_printertype == screenvis)
 | 
						|
    { 
 | 
						|
      CHECK(_vf == NULL, "Print preview already open");
 | 
						|
      _vf = new TViswin (NULL, "Anteprima di stampa", TRUE, TRUE,
 | 
						|
                         _linksdescr.items () > 0);
 | 
						|
      _vf->open_modal ();
 | 
						|
    }
 | 
						|
    else if (_printertype == winprinter || _printertype == export 
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
             || _printertype == fileprinter
 | 
						|
#endif
 | 
						|
             )
 | 
						|
    {
 | 
						|
      // prepare text object for new text
 | 
						|
      _txt.destroy();
 | 
						|
      _txt.interactive(FALSE);
 | 
						|
      
 | 
						|
      if (isfax())
 | 
						|
        start_fax_server();
 | 
						|
    }
 | 
						|
#if  XVT_OS==XVT_OS_SCOUNIX
 | 
						|
else
 | 
						|
{
 | 
						|
  const PrinterDef & def = get_description (_curprn);
 | 
						|
  TFilename fname (_printerfile);
 | 
						|
 | 
						|
  if (_printertype == normprinter)
 | 
						|
    fname = def._devicename;
 | 
						|
  _fp = fopen (fname, "w");
 | 
						|
 | 
						|
  if (_fp == NULL)
 | 
						|
    return error_box ("Errore di apertura file stampa: '%s'",
 | 
						|
                      (const char *) fname);
 | 
						|
 | 
						|
  TString code (def.get_codes (_curcode));
 | 
						|
  if (code.not_empty ())
 | 
						|
  {
 | 
						|
    const char *s = code;
 | 
						|
    fputs (esc ((char *) s), _fp);
 | 
						|
  }
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
_currentrow = 1;
 | 
						|
_currentpage = 1;
 | 
						|
 | 
						|
return _isopen = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TPrinter::set()
 | 
						|
{
 | 
						|
  main_app().disable_menu_item (M_FILE_PG_SETUP);
 | 
						|
                  
 | 
						|
  TMask* msk = new TMask("bagn001a");
 | 
						|
  TMask& mask = *msk;
 | 
						|
  
 | 
						|
  TToken_string pn1(50), pn2(100);
 | 
						|
  int i;
 | 
						|
 | 
						|
  mask.set(MSK_FILENAME, _printerfile);
 | 
						|
  mask.set(MSK_NPAGES, _ncopies);
 | 
						|
  mask.enable(DLG_OK, _config == "Printer");
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
  mask.set_handler (MSK_PRINTERS, set_windows_print_device);
 | 
						|
  mask.set_handler (MSK_FONT, font_handler);
 | 
						|
  
 | 
						|
  pn2 = getprinternames();             
 | 
						|
  char old_default[80];
 | 
						|
  GetProfileString ("windows", "device", ",,,", old_default, sizeof(old_default));
 | 
						|
  
 | 
						|
  const int np = pn2.items();
 | 
						|
  for (i = 0; i < np; i++)
 | 
						|
    pn1.add(i);                                
 | 
						|
 | 
						|
  TList_field& plst = (TList_field&)mask.field (MSK_PRINTERS);
 | 
						|
  plst.replace_items(pn1, pn2);                // Genera printer list
 | 
						|
 | 
						|
  mask.set(MSK_PRINTERS, _curprn, TRUE);     // Genera font list
 | 
						|
  mask.set(MSK_FONT, _fontname, TRUE);       // Genera size list
 | 
						|
  mask.set(MSK_SIZE, _ch_size);
 | 
						|
  mask.set(MSK_LINES, _lines_per_inch);
 | 
						|
  mask.set(MSK_ISGRAPHICS, _isgraphics ? "X" : "");
 | 
						|
  
 | 
						|
  if (!_multiple_copies) 
 | 
						|
    mask.hide(MSK_NPAGES);
 | 
						|
  
 | 
						|
  if (_printertype == fileprinter)
 | 
						|
    mask.set (MSK_TYPE, "1");
 | 
						|
  else if (_printertype == screenvis)
 | 
						|
    mask.set (MSK_TYPE, "2");
 | 
						|
  else
 | 
						|
    mask.set (MSK_TYPE, "0");
 | 
						|
 | 
						|
  KEY k;                                           
 | 
						|
  int oldprn = _curprn;
 | 
						|
  
 | 
						|
  while ((k = mask.run ()) != K_ESC && k != K_ENTER && k != K_INS)
 | 
						|
  {
 | 
						|
    if (k == DLG_SETPRINT)
 | 
						|
    {
 | 
						|
      // l'handler setta default di windows a quella nel listbox e ribecca l'rcd
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
      if (xvt_dm_post_page_setup(get_printrcd()))
 | 
						|
      {
 | 
						|
        // see if user has changed printer
 | 
						|
        // determine index of currently selected printer 
 | 
						|
        // ACTHUNG! Deep hacking of XVT internals! NON PORTABLE!
 | 
						|
        
 | 
						|
        const char* name = (const char *)(_print_rcd + 4);
 | 
						|
        _curprn = pn2.get_pos(name);
 | 
						|
        CHECKS(_curprn >= 0, "Can't find printer ", name); 
 | 
						|
        mask.set(MSK_PRINTERS, pn1.get(_curprn));    
 | 
						|
        //        set_win_formlen();                          // Update dimensions
 | 
						|
      }
 | 
						|
      else
 | 
						|
        beep ();    
 | 
						|
#endif        
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (k == K_ESC || k == K_ENTER)
 | 
						|
  {
 | 
						|
    // riaggiusta stampante default windows come prima  
 | 
						|
    // curprn e rcd sono quelle di prima
 | 
						|
    main_app().enable_menu_item(M_FILE_PG_SETUP);
 | 
						|
    WriteProfileString("windows", "device", old_default);
 | 
						|
  }                                          
 | 
						|
  if (k == K_ESC)
 | 
						|
  {
 | 
						|
    _curprn = oldprn;
 | 
						|
    set_printrcd();
 | 
						|
    set_win_formlen();
 | 
						|
    
 | 
						|
    delete msk; msk = NULL;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  _curprn = atoi(mask.get(MSK_PRINTERS));
 | 
						|
  _ncopies = atoi (mask.get (MSK_NPAGES));
 | 
						|
 | 
						|
  switch (atoi (mask.get (MSK_TYPE)))
 | 
						|
  {
 | 
						|
  case 0:                       // stampante
 | 
						|
    _printertype = winprinter;
 | 
						|
    break;
 | 
						|
  case 1:                       // file
 | 
						|
    _printertype = fileprinter;
 | 
						|
    _printerfile = mask.get (MSK_FILENAME);
 | 
						|
    _curcode = atoi (mask.get (MSK_CODES));
 | 
						|
    break;
 | 
						|
  case 2:                       // video
 | 
						|
    _printertype = screenvis;
 | 
						|
    _curcode = 0;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  _fontname = mask.get(MSK_FONT);
 | 
						|
  
 | 
						|
  const int cs = mask.get_int(MSK_SIZE);
 | 
						|
  if (cs > 4) _ch_size = cs;
 | 
						|
 | 
						|
  _lines_per_inch = mask.get_int (MSK_LINES);
 | 
						|
  _isgraphics = mask.get_bool (MSK_ISGRAPHICS);
 | 
						|
  set_win_formlen ();
 | 
						|
#endif
 | 
						|
 | 
						|
  if (k == K_INS)
 | 
						|
    save_configuration();
 | 
						|
 | 
						|
  main_app().enable_menu_item (M_FILE_PG_SETUP);
 | 
						|
  
 | 
						|
  if (msk)
 | 
						|
  {
 | 
						|
    delete msk; 
 | 
						|
    msk = NULL;
 | 
						|
  }  
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Inserisce un file di export fatto da un'altra printer 
 | 
						|
void TPrinter::merge_export_file(
 | 
						|
  const char* file, 
 | 
						|
  bool header)  // @parm Indica se gli header sono presenti nel file:
 | 
						|
  //
 | 
						|
  // @flag TRUE | Gli header sono nel file e quindi non vengono stampanti (default)
 | 
						|
  // @flag FALSE | Gli header non sono nel file e quindi vengono stampanti
 | 
						|
 | 
						|
  // @comm Vengono inseriti nel file di export i formati e tutto il resto. Vengono ignorati gli
 | 
						|
  //     header supponendo che siano gia' presenti nel file
 | 
						|
{
 | 
						|
  TTextfile txt(file); 
 | 
						|
  
 | 
						|
  for (long i = 0; i < txt.lines(); i++)
 | 
						|
  {
 | 
						|
    TPrintrow* p = new TPrintrow();  
 | 
						|
    p->put(txt.line_formatted(i));
 | 
						|
    if (header) printrow(p);  
 | 
						|
    else        print(*p);   
 | 
						|
  }              
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Crea un segnalibro
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'identificatore del segnalibro creato
 | 
						|
int TPrinter::set_bookmark(
 | 
						|
  const char* txt,      // @parm Nome del segnalibro da creare
 | 
						|
  int father)           // @parm Identificatore del segnalibro padre a cui collegare quello 
 | 
						|
  //     da creare
 | 
						|
{                                                     
 | 
						|
  if (_printertype == screenvis)
 | 
						|
  {
 | 
						|
    BkDef* bkd = new BkDef;
 | 
						|
    
 | 
						|
    bkd->_row       = (_currentrow + ((_currentpage - 1)*_formlen)) - 1;
 | 
						|
    bkd->_father_id = father;
 | 
						|
    bkd->_id        = _bookmarks.items() + 1;
 | 
						|
    bkd->_txt       = txt;
 | 
						|
    
 | 
						|
    _bookmarks.add(bkd);
 | 
						|
    
 | 
						|
    return _bookmarks.items();
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TPrinter::print_txt(TTextfile& txt)
 | 
						|
{
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
  if (txt.lines() > 0)
 | 
						|
  {
 | 
						|
    PrintWhat._prcd = _print_rcd;
 | 
						|
    PrintWhat._txt = &txt;
 | 
						|
    PrintWhat._graphics = _isgraphics;
 | 
						|
    PrintWhat._charsize = _ch_size;
 | 
						|
    xvt_print_open();
 | 
						|
    xvt_print_start_thread (start_winprint, (long) (&PrintWhat));
 | 
						|
    xvt_print_close();
 | 
						|
  }  
 | 
						|
#endif  
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TPrinter::close ()
 | 
						|
{
 | 
						|
  const bool isfirstpage = (_currentpage == 1 && _frompage == 0) ||
 | 
						|
    (_currentpage <= _frompage);
 | 
						|
 | 
						|
  if (isopen() && (!isfirstpage || _currentrow > _headersize) &&
 | 
						|
      (_printertype != screenvis && _printertype != winprinter 
 | 
						|
       && _printertype != export))
 | 
						|
    formfeed();
 | 
						|
 | 
						|
  if (_fp)
 | 
						|
  {
 | 
						|
    fclose (_fp);
 | 
						|
    _fp = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  if (_printertype == screenvis)
 | 
						|
  {
 | 
						|
    _vf->close_print();
 | 
						|
    const KEY key = _vf->run ();
 | 
						|
    if (_vf->is_open ()) _vf->close_modal ();  
 | 
						|
    _bookmarks.destroy();   
 | 
						|
    freeze (FALSE);             
 | 
						|
    
 | 
						|
    if (key == K_CTRL+'S')
 | 
						|
    {
 | 
						|
      _isopen = FALSE;
 | 
						|
      _currentrow = _currentpage = 1;
 | 
						|
      print_txt(_vf->text());
 | 
						|
    }
 | 
						|
 | 
						|
    delete _vf; _vf = NULL;
 | 
						|
  }
 | 
						|
  else if (_printertype == export)
 | 
						|
  {                          
 | 
						|
    if (_exportfile.not_empty() && _txt.lines() > 0L)
 | 
						|
    {
 | 
						|
      ofstream txt((const char*)_exportfile); 
 | 
						|
      for (long i = 0; i < _txt.lines(); i++)
 | 
						|
        txt << _txt.line_formatted(i) << '\n';
 | 
						|
      txt.close();
 | 
						|
    }
 | 
						|
  }
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
else if (_printertype == winprinter && _txt.lines() > 0L)
 | 
						|
{     
 | 
						|
  print_txt(_txt);
 | 
						|
}
 | 
						|
else if (_printertype == fileprinter)
 | 
						|
{
 | 
						|
  FILE* fp = fopen(_printerfile, "w"); 
 | 
						|
  if (fp == NULL)
 | 
						|
  {
 | 
						|
    error_box("Impossibile aprire il file %s", (const char*)_printerfile); 
 | 
						|
    return; 
 | 
						|
  }
 | 
						|
  for (long i = 0; i < _txt.lines(); i++)
 | 
						|
    fprintf(fp,"%s\n", _txt.line(i));
 | 
						|
  fclose(fp);
 | 
						|
  message_box("Stampa su file terminata. Nome archivio: %s",(const char *)_printerfile);
 | 
						|
}
 | 
						|
#endif
 | 
						|
else if (_printertype == localprinter)
 | 
						|
{
 | 
						|
#if XVT_OS == XVT_OS_SCOUNIX
 | 
						|
  TFilename s1 = tmpnam (NULL);
 | 
						|
  switch (fork ())
 | 
						|
  {
 | 
						|
  case -1:
 | 
						|
    break;
 | 
						|
  case 0:
 | 
						|
    execlp ("localprint", "localprint", (const char *) s1, NULL);
 | 
						|
  default:
 | 
						|
    wait ((int *) NULL);
 | 
						|
  }
 | 
						|
  remove (s1);
 | 
						|
#endif
 | 
						|
}   
 | 
						|
if (_finker) 
 | 
						|
{
 | 
						|
  delete _finker;
 | 
						|
  _finker = NULL;
 | 
						|
}
 | 
						|
_isopen = FALSE;
 | 
						|
}
 | 
						|
 | 
						|
//  
 | 
						|
// TFile_printer
 | 
						|
// 
 | 
						|
 | 
						|
#include <bagn004.h>
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
const char* const FORMAT_COMMAND = "FORMAT";
 | 
						|
#else
 | 
						|
const char* const FORMAT_COMMAND = "dosformat -fq";
 | 
						|
#endif
 | 
						|
 | 
						|
const long disk_sizes[] = { 360000L, 1200000L, 720000L, 1400000L, 2880000L };
 | 
						|
 | 
						|
TFile_printer::TFile_printer (const char *ffile, const char *label, int len_rec, int num_rec_inizio, int num_rec_fine, int tipo_disco)
 | 
						|
{
 | 
						|
  set_printtype (fileprinter);
 | 
						|
 | 
						|
  _num_rec_testa_coda = num_rec_inizio + num_rec_fine;
 | 
						|
  _file = ffile;
 | 
						|
  _label = label;
 | 
						|
  _len_rec = len_rec;
 | 
						|
  _volume = 1;
 | 
						|
  _size = disk_sizes[tipo_disco];
 | 
						|
  _num_rec_volume = int ((_size / len_rec) - _num_rec_testa_coda);
 | 
						|
  _nome_file_fissato = TRUE;
 | 
						|
  _formatta = FALSE;
 | 
						|
  _label_fissata = TRUE;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void TFile_printer::open()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void TFile_printer::close ()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
bool TFile_printer::genera_dischetti ()
 | 
						|
{
 | 
						|
  int r;
 | 
						|
 | 
						|
  for (int i = 0; i < _tmp_files.items (); i++)
 | 
						|
  {
 | 
						|
    // Avvisa l'utente di inserire un dischetto
 | 
						|
    r = yesno_box ("Inserire il dischetto n. %2d di %2d nel drive %2s",
 | 
						|
                   i + 1, _volume, _drive);
 | 
						|
    if (!r)
 | 
						|
      return error_box ("Procedura interrotta!");
 | 
						|
 | 
						|
    // e eventualmente lo formatta 
 | 
						|
    if (_formatta)
 | 
						|
    {
 | 
						|
      TString80 dep;
 | 
						|
      if (_label != NULL)
 | 
						|
        dep << FORMAT_COMMAND << " " << "/v:" << _label << " " << _drive;
 | 
						|
      else
 | 
						|
        dep << FORMAT_COMMAND << " " << _drive;
 | 
						|
 | 
						|
      TExternal_app sys (dep);
 | 
						|
      sys.run ();
 | 
						|
    }
 | 
						|
 | 
						|
    // copia il file sul dischetto
 | 
						|
    fcopy ((const char *) &_tmp_files[i], (const char *) _drive);
 | 
						|
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
TFile_printer::~TFile_printer ()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
bool TFile_printer::set ()
 | 
						|
{
 | 
						|
  TMask m ("bagn004");
 | 
						|
  int f;
 | 
						|
 | 
						|
  //
 | 
						|
  // 
 | 
						|
  // --------------------------------------------------------------------
 | 
						|
  // Qui bisogna inserire la lista dei drive disponibili nella maschera
 | 
						|
  // Per ora tale lista e' fissa e contiene solo A: e B:
 | 
						|
  // --------------------------------------------------------------------
 | 
						|
  // 
 | 
						|
  // 
 | 
						|
 | 
						|
  m.set (F_FILE_DESTINAZIONE, _file);
 | 
						|
  m.set (F_LABEL, _label);
 | 
						|
 | 
						|
  if (_nome_file_fissato)
 | 
						|
    m.disable (F_FILE_DESTINAZIONE);
 | 
						|
 | 
						|
  if (_label_fissata)
 | 
						|
    m.disable (F_LABEL);
 | 
						|
 | 
						|
  const bool ok = m.run () == K_ENTER;
 | 
						|
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    f = atoi(m.get(F_FORMATO_DISCO));
 | 
						|
    _drive = m.get(F_DRIVE);
 | 
						|
    _file = m.get(F_FILE_DESTINAZIONE);
 | 
						|
    _label = m.get(F_LABEL);
 | 
						|
    _formatta = (bool)(m.get(F_FORMATTA) == "X");
 | 
						|
    _size = disk_sizes[f];
 | 
						|
    _num_rec_volume = int ((_size / _len_rec) - _num_rec_testa_coda);
 | 
						|
  } 
 | 
						|
  
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 
 | 
						|
const char* TPrinter::background_chars(int l) const 
 | 
						|
{ 
 | 
						|
  return _finker == NULL ? "" : _finker->get_chars(l); 
 | 
						|
}
 | 
						|
 
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Gestione fax
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
bool TPrinter::start_fax_server() const
 | 
						|
{
 | 
						|
  TDDE dde;
 | 
						|
  return dde.execute("EASYFAX", "FAX", "", "bafax");
 | 
						|
}
 | 
						|
 | 
						|
void TPrinter::close_fax_server() const
 | 
						|
{           
 | 
						|
  TDDE dde;
 | 
						|
  const bool running = dde.initiate("EASYFAX", "FAX");
 | 
						|
  if (running)
 | 
						|
    dde.execute("[FileClose]");
 | 
						|
}
 | 
						|
 | 
						|
bool TPrinter::send_fax(const char* tipo, const char* codice)
 | 
						|
{
 | 
						|
  bool ok = isopen() && isfax();
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    if (tipo && codice)
 | 
						|
    {
 | 
						|
      TString cmd(80);
 | 
						|
      cmd << "[SetRecipient(" << tipo << ',' << codice << ")]";
 | 
						|
 | 
						|
      TDDE dde;
 | 
						|
      dde.execute("EASYFAX", "FAX", cmd, "bafax");    
 | 
						|
    }
 | 
						|
    close();  // termina la stampa corrente e la spedisce
 | 
						|
    open();   // riapre la stampante
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 |