From 7a60c073578a2a04f1737228114c49588d58c0fe Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 16 Aug 1994 16:07:16 +0000 Subject: [PATCH] Corretto il comportamento della set. Nel caso di annullamento dell' operazione non riabilitava la propria scelta di menu'. git-svn-id: svn://10.65.10.50/trunk@12 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/printer.cpp | 2688 ++++++++++++++++++++++--------------------- 1 file changed, 1346 insertions(+), 1342 deletions(-) diff --git a/include/printer.cpp b/include/printer.cpp index aad079a92..f37d9a168 100755 --- a/include/printer.cpp +++ b/include/printer.cpp @@ -1,1342 +1,1346 @@ -#include -#include - -#if XVT_OS==XVT_OS_SCOUNIX -#include -#include -#include -#else -#include -#endif - -#define STYLE_NUM 4 - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -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 - -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_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 - -#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 -// +#include +#include + +#if XVT_OS==XVT_OS_SCOUNIX +#include +#include +#include +#else +#include +#endif + +#define STYLE_NUM 4 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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 + +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_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) + { + MainApp()->enable_menu_item(M_FILE_PG_SETUP); + 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(); + MainApp()->enable_menu_item(M_FILE_PG_SETUP); + 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 + +#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 +//