campo-sirio/include/printer.cpp

1343 lines
31 KiB
C++
Executable File

#include <stdlib.h>
#include <xvt.h>
#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 <mask.h>
#include <utility.h>
#include <viswin.h>
#include <applicat.h>
#include <extcdecl.h>
#include <printer.h>
#include <execp.h>
#include <bagn001a.h>
#include <strstream.h>
struct PrDesc {
TTextfile* _txt;
PRINT_RCD* _prcd;
bool _graphics;
int _formlen;
int _charsize;
int _lines_per_inch;
} PrintWhat;
#define LINES_PER_INCH (6.0)
#if XVT_OS == XVT_OS_WIN
#include <windows.h>
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' && buf[i+1] == '\0')
break;
if (buf[i] == '\0' && buf[i+1] != '\0')
buf[i] = '|';
}
t = buf;
delete buf;
}
BOOLEAN TPrinter::start_winprint(long data)
{
PrDesc* pd = (PrDesc*)data;
TTextfile& txt = *(pd->_txt);
TPrintwin pw(pd->_prcd, txt, pd->_charsize);
pw.print_background(pd->_graphics);
pw.do_print();
return pw.aborted();
}
#endif
// utils del caz
HIDDEN void read_int(const char* s, int& n, int& cnt)
{
static char nbuf[10]; int j = 0;
while (!isdigit(s[cnt])) cnt++;
while (isdigit(s[cnt])) nbuf[j++] = s[cnt++];
nbuf[j] = '\0'; n = atoi(nbuf);
}
#if XVT_OS == XVT_OS_WIN
void TPrinter::set_win_formlen()
{
long pw, ph, phr, pvr;
xvt_escape(XVT_ESC_GET_PRINTER_INFO, _print_rcd, &ph, &pw, &pvr, &phr);
if (pvr != 0)
{
_formlen = (int)((ph/pvr)*_lines_per_inch);
_dots_per_line = (int)(pvr/_lines_per_inch);
_vert_offset = (int)(ph % (long)(_formlen * _dots_per_line));
_horz_offset = 0; // not implemented (font dependent)
}
else warning_box("Il driver di stampante non e' valido. Non stampare prima di averlo"
" reinstallato");
}
#endif
void TPrinter::_parse_background()
{
char op; int x1, x2, y1, y2;
TToken_string tt(20);
TString txt(80);
TArray pix; char ch; int cnt = 0;
while ((ch = _bg_desc[cnt++]) != '\0')
{
op = ch; tt = ""; char bf[2]; bf[1] = '\0';
switch (op)
{
case ' ': // ignore whitespace
case '\t':
case '\n':
continue;
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++;
tt << op; tt.add(x1-1); tt.add(y1-1); tt.add(x2-1); tt.add(y2-1);
break;
case 't': // text
cnt++;
read_int(_bg_desc,x1,cnt); read_int(_bg_desc,y1,cnt);
cnt++; txt = "";
while ((ch = _bg_desc[cnt++]) != '}') txt << ch;
tt << op; tt.add(x1-1); tt.add(y1-1); tt.add(txt);
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++)
{
TString* rwd = (TString*)_background.objptr(l);
if (rwd == NULL)
{
_background.add(rwd = new TString,l);
if (curcol != 'n') (*rwd) << 'C' << curcol;
if (curpat != 'n') (*rwd) << 'B' << curpat;
if (curwid != '1') (*rwd) << 'W' << curwid;
if (curpen != 'n') (*rwd) << 'P' << curcol;
}
for (int j = 0; j < pix.items(); j++)
{
TToken_string& tt = (TToken_string&)pix[j];
tt.restart();
// la stringa contiene l'opcode piu' i parametri in binario,
// incrementati di 1 per evitare lo 0
switch(*(tt.get(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 't':
x1 = tt.get_int(1)+1; y1 = tt.get_int(2)+1; // al gh'e'
if (y1 == l+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;
}
}
}
}
void TPrinter::setbackground(const char* b)
{
_background.destroy();
_bg_desc = b;
if (b != NULL) _parse_background();
}
bool printers_on_key (TMask_field& f, KEY key);
// fv support structs for config
bool PrinterDef::read(const char* name, FILE* fd)
{
_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(TString( code.get()));
_codes.add(TString(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));
_currentcolor = 'w'; _currentcolor <<= 8; _currentcolor += 'n';
memset(_attr, normalstyle, sizeof(_attr));
for (int i = 0; i < MAXSTR; i++) _cols[i] = _currentcolor;
_lastpos = 0;
_currentstyle = normalstyle;
return *this;
}
const char* TPrintrow::row_codified()
{
// returns the row with @-codes for font style and color
char last_attr = -1; int last_color = -1;
int k = 0;
_row.rtrim();
for(int i = 0; i < _row.len(); i++)
{
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)
{
__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];
}
// k = k > 255 ? 255 : k;
__tmp_string[k] = '\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;
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 '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;
}
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;
}
}
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 //////////
bool printers_on_key (TMask_field& f, KEY key)
{
if (key==K_SPACE)
{
TToken_string pn1(10), pn2(20);
const PrinterDef& def = MainApp()->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_1_CODES)).replace_items(pn1, pn2);
}
return TRUE;
}
#if XVT_OS == XVT_OS_WIN
bool set_windows_print_device(TMask_field& f, KEY key)
{
static char szDevice[80];
if (key == K_SPACE)
{
if (MainApp()->printer().get_printrcd() != NULL)
free_print_rcd(MainApp()->printer().get_printrcd());
TToken_string& pn = MainApp()->printer().getprinternames();
TString pdev(pn.get(atoi(f.get())));
GetProfileString("devices", pdev, "", szDevice, sizeof(szDevice));
pdev << "," << szDevice;
// WriteProfileString("windows","device", pdev);
// madonna bona
MainApp()->printer().set_printrcd(get_print_rcd(&(MainApp()->printer().get_printrcdsize())));
MainApp()->printer().set_win_formlen();
}
return TRUE;
}
#endif
TPrinter::TPrinter() : _date(TODAY), _multiple_link(FALSE), _frozen(FALSE), _isgraphics(TRUE),
_lines_per_inch(6), _ch_size(12)
{
_footerhandler = _headerhandler = NULL;
_linkhandler = NULL;
_config = "printer.ini";
_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;
// read configuration file
read_configuration(_config);
#if XVT_OS == XVT_OS_WIN
print_begin();
_print_rcd = get_print_rcd(&_print_rcd_size);
set_win_formlen();
#else
_isgraphics = FALSE;
#endif
}
TToken_string& TPrinter::getprinternames()
{
// per ora va solo in windows
#if XVT_OS == XVT_OS_WIN
_get_windows_printer_names(_printer_names);
#endif
return _printer_names;
}
void TPrinter::read_configuration(const char* conf)
{
FILE* cnfp=fopen(conf, "r");
if (cnfp == NULL)
fatal_box("Impossibile aprire il file %s", (const char*) _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);
TString s("printer.def");
#if XVT_OS == XVT_OS_SCOUNIX
s << format(".%d", getuid());
#endif
if (fexist(s))
{
TScanner sc(s);
TToken_string t(sc.line());
int where_print = t.get_int(1);
t = sc.line();
_curprn = t.get_int(1);
t = sc.line();
_printerfile = t.get(1);
t = sc.line();
_curcode = t.get_int(1);
#if XVT_OS != XVT_OS_WIN
PrinterDef& def = (PrinterDef&)get_description(_curprn);
#endif
switch (where_print)
{
case 0: // stampante
#if XVT_OS == XVT_OS_WIN
_printertype = winprinter;
#else
switch (atoi(def._printertype))
{
case 0:
_printertype = normprinter;
break;
case 1:
_printertype = localprinter;
break;
case 2:
_printertype = spoolprinter;
break;
}
#endif
break;
case 1: // file
_printertype = fileprinter;
break;
case 2: // video
_printertype = screenvis;
_curcode = 0;
break;
}
}
}
TPrinter::~TPrinter()
{
#if XVT_OS == XVT_OS_WIN
print_end();
#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));
}
void TPrinter::setheaderline (int linetoset, 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);
}
void TPrinter::setfooterline (int linetoset, TPrintrow* line)
{
_footer.add(line,linetoset);
// if (linetoset >= _footersize) _footersize = linetoset+1;
}
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;
}
bool TPrinter::printrow(TPrintrow* rowtoprint)
{
if (!isopen()) return FALSE;
if (_currentpage < _frompage || _currentpage > _topage)
return TRUE;
TString rw(rowtoprint == NULL ? "" : (_printertype == screenvis || _printertype == winprinter ?
rowtoprint->row_codified() :
rowtoprint->row()));
rw.rtrim();
int lun = rw.len();
int idx;
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(4), idx++); break;
case '<': rw.overwrite(_date.string(2), idx++); break;
default : break;
}
}
}
if (_printertype == screenvis)
{
if (!_vf->frozen()) _vf->add_line(rw);
else _frozen = TRUE;
return TRUE;
}
if (_printertype == winprinter)
{
// add line to txt
if (!_frozen) _txt.append(rw);
return TRUE;
}
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);
return TRUE;
}
word TPrinter::rows_left() const
{
word left = _formlen-_currentrow-_footersize+1;
if (_currentrow < 2) left -= _headersize;
return left;
}
bool TPrinter::print(TPrintrow& rowtoprint)
{
bool ok = TRUE;
if (_currentrow > _formlen-_footersize)
ok = printfooter();
// if (ok && _currentrow <= _headersize)
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_WIN
if (ok) printformfeed();
#endif
_currentrow = 1;
_currentpage++;
return ok;
}
bool TPrinter::skip (int linestoskip)
{
int jumpline;
CHECK(linestoskip>=0, "Linestoskip can't be negative");
jumpline=_currentrow+linestoskip;
return jump(jumpline);
}
bool TPrinter::jump (int jumpline)
{
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 <= lastrow; _currentrow++)
printrow();
return printfooter();
}
void TPrinter::reset ()
{
resetheader();
resetfooter();
_currentpage=1;
_currentrow=1;
}
bool TPrinter::printformfeed ()
{
#if XVT_OS != XVT_OS_WIN
const PrinterDef& pd = get_description(_curprn);
if (_printertype != screenvis && _hwformfeed)
fprintf(_fp,"%s",(const char*)pd._ffcode);
#endif
return TRUE;
}
bool TPrinter::open ()
{
// qui
#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)
{
_vf = new TViswin(NULL, "Anteprima di stampa", TRUE, TRUE,
_linksdescr.items() > 0);
_vf->open_modal();
}
else if (_printertype == winprinter)
{
// prepare text object for new text
_txt.destroy();
}
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);
}
}
_currentrow = 1;
_currentpage = 1;
return _isopen = TRUE;
}
void TPrinter::set()
{
TMask mask("bagn001a.msk");
TToken_string pn1(50), pn2(100);
int i;
MainApp()->disable_menu_item(M_FILE_PG_SETUP);
#if XVT_OS != XVT_OS_WIN
for (i = 0; i < _printers.items(); i++)
{
pn1.add(i);
pn2.add(((PrinterDef&) _printers[i])._printername);
}
((TList_field&)(mask.field(MSK_1_PRINTERS))).replace_items(pn1, pn2);
mask.hide(MSK_1_SETUP);
mask.hide(MSK_1_SIZE);
mask.hide(MSK_1_LINES);
pn1 = "";
pn2 = "";
for (i = 0; i < ((PrinterDef&)_printers[_curprn])._names.items(); i++ )
{
pn1.add(format("%d", i));
pn2.add((TString&)((PrinterDef&) _printers[_curprn])._names[i]);
}
((TList_field&)(mask.field(MSK_1_CODES))).replace_items(pn1, pn2);
mask.set_handler(MSK_1_PRINTERS, printers_on_key);
if (_printertype == fileprinter)
mask.set(MSK_1_TYPE, "1");
else
if (_printertype == screenvis)
mask.set(MSK_1_TYPE, "2");
else
mask.set(MSK_1_TYPE, "0");
mask.set(MSK_1_PRINTERS, format("%d",_curprn));
mask.set(MSK_1_CODES, format("%d",_curcode));
mask.set(MSK_1_FILENAME, _printerfile);
mask.reset(MSK_1_SAVE);
if (mask.run() == K_ESC) return;
if (mask.get(MSK_1_SAVE).not_empty())
{
TString s("printer.def");
#if XVT_OS == XVT_OS_SCOUNIX
s << format(".%d", getuid());
#endif
mask.set_workfile(s);
mask.save();
}
// get user choices
_curprn = atoi(mask.get(MSK_1_PRINTERS));
PrinterDef& def = (PrinterDef&)get_description(_curprn);
switch (atoi(mask.get(MSK_1_TYPE)))
{
case 0: // stampante
_printertype = normprinter;
_curcode = atoi(mask.get(MSK_1_CODES));
switch (atoi(def._printertype))
{
case 0:
_printertype = normprinter;
break;
case 1:
_printertype = localprinter;
break;
case 2:
_printertype = spoolprinter;
break;
}
break;
case 1: // file
_printertype = fileprinter;
_printerfile = mask.get(MSK_1_FILENAME);
_curcode = atoi(mask.get(MSK_1_CODES));
break;
case 2: // video
_printertype = screenvis;
_curcode = 0;
break;
}
#else
static char defPrinter[80];
static char szDevice[50];
int defIndex;
// get default printer driver
GetProfileString("windows","device",",,,",defPrinter, sizeof(defPrinter));
TString pdev(defPrinter);
GetProfileString("devices", pdev, "", szDevice, sizeof(szDevice));
pdev << "," << szDevice;
TToken_string dio(pdev, ',');
// get printer names
_get_windows_printer_names(pn2);
// determine index of current default printer
for (i = 0; i < pn2.items(); i++)
{
if (TString(dio.get(0)) == TString(pn2.get(i)))
{
defIndex = i;
break;
}
}
if (defIndex == pn2.items()) defIndex = 0; // should never happen
for (i = 0; i < pn2.items(); i++) pn1.add(i);
((TList_field&)(mask.field(MSK_1_PRINTERS))).replace_items(pn1, pn2);
mask.set(MSK_1_PRINTERS, pn1.get(defIndex));
mask.hide(MSK_1_CODES);
mask.set(MSK_1_ISGRAPHICS, _isgraphics ? "X" : "");
mask.set(MSK_1_SIZE, format("%d",_ch_size));
mask.set(MSK_1_LINES, format("%d",_lines_per_inch));
if (_printertype == fileprinter)
mask.set(MSK_1_TYPE,"1");
else
if (_printertype == screenvis)
mask.set(MSK_1_TYPE, "2");
else
mask.set(MSK_1_TYPE, "0");
mask.set_handler(MSK_1_PRINTERS, set_windows_print_device);
mask.reset(MSK_1_SAVE);
KEY k;
while ((k = mask.run()) != K_ESC && k != K_ENTER)
{
if (k == MSK_1_SETUP)
{
if (_print_rcd != NULL)
{
if (page_setup_dlg(_print_rcd))
{
// see if user has changed printer
int dIndex;
// determine index of currently selected printer
// ACTHUNG! Deep hacking of XVT internals! NON PORTABLE!
for (i = 0; i < pn2.items(); i++)
if (strcmp((const char*)(_print_rcd+4), pn2.get(i)) == 0)
{
dIndex = i;
break;
}
mask.set(MSK_1_PRINTERS, pn1.get(dIndex));
set_win_formlen();
}
mask.set_focus();
}
else beep();
}
}
if (k == K_ESC)
{
// rimetti come prima
// WriteProfileString("windows","device", pdev);
if (_print_rcd != NULL) free_print_rcd(_print_rcd);
_print_rcd = get_print_rcd(&_print_rcd_size);
set_win_formlen();
return;
}
if (mask.get(MSK_1_SAVE).not_empty())
{
TString s("printer.def");
mask.set_workfile(s);
mask.save();
}
switch (atoi(mask.get(MSK_1_TYPE)))
{
case 0: // stampante
_printertype = winprinter;
break;
case 1: // file
_printertype = fileprinter;
_printerfile = mask.get(MSK_1_FILENAME);
_curcode = atoi(mask.get(MSK_1_CODES));
break;
case 2: // video
_printertype = screenvis;
_curcode = 0;
break;
}
_isgraphics = mask.get_bool(MSK_1_ISGRAPHICS);
_ch_size = atoi(mask.get(MSK_1_SIZE));
_lines_per_inch = atoi(mask.get(MSK_1_LINES));
set_win_formlen();
#endif
MainApp()->enable_menu_item(M_FILE_PG_SETUP);
}
void TPrinter::close ()
{
if (isopen() && _currentrow > 1 &&
(_footersize || (_printertype != screenvis && _printertype != winprinter)))
formfeed();
if (_fp)
{
fclose(_fp);
_fp = NULL;
}
if (_printertype == screenvis)
{
CHECK(_vf, "VF!");
_vf->close_print();
_vf->run();
if (_vf->is_open()) _vf->close_modal();
delete _vf;
_vf = NULL;
}
#if XVT_OS == XVT_OS_WIN
else if (_printertype == winprinter)
{
PrintWhat._prcd = _print_rcd;
PrintWhat._txt = &_txt;
PrintWhat._graphics = _isgraphics;
PrintWhat._charsize = _ch_size;
start_print_thread(start_winprint, (long)(&PrintWhat));
}
#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
}
_isopen = FALSE;
}
//
// TFile_printer
//
#include <tfilepr.h>
#if XVT_OS == XVT_OS_DOS
#define FORMAT_COMMAND "FORMAT"
#else
#define FORMAT_COMMAND "dosformat -fq"
#endif
const long disk_sizes [] = { 360000, 1200000, 720000, 1400000, 2880000 };
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;
warning_box ("Questa procedura richiede %2d dischetti",
_volume);
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)
{
TString dep (30);
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 ()
{
}
void TFile_printer::set()
{
TMask m ("tfilepr");
KEY tasto;
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);
tasto = m.run();
if (tasto == K_ENTER)
{
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);
}
}
//
// TFile printer fine
//