#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.\n" "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), _ncopies(1) { _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; _multiple_copies = MainApp()->class_id() == CLASS_PRINT_APPLICATION; // 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 (); static char defPrinter[80]; static char szDevice[50]; // 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, ','); TToken_string pn2(1024); // get printer names _get_windows_printer_names (pn2); // determine index of current default printer for (int i = 0; i < pn2.items (); i++) { if (TString(dio.get(0)) == TString(pn2.get (i))) { _curprn = i; break; } } #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"); 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); if (!_multiple_copies) mask.hide(MSK_1_NPAGES); 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.set(MSK_1_NPAGES, _ncopies); 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)); _ncopies = atoi(mask.get(MSK_1_NPAGES)); 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 _get_windows_printer_names (pn2); 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(_curprn)); mask.hide(MSK_1_CODES); if (!_multiple_copies) mask.hide(MSK_1_NPAGES); mask.set(MSK_1_ISGRAPHICS, _isgraphics ? "X" : ""); mask.set(MSK_1_SIZE, _ch_size); mask.set(MSK_1_LINES, _lines_per_inch); mask.set(MSK_1_NPAGES, _ncopies); 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; int oldprn = _curprn; 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 // 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) { _curprn = i; break; } mask.set (MSK_1_PRINTERS, pn1.get(_curprn)); 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); _curprn = oldprn; _print_rcd = get_print_rcd(&_print_rcd_size); set_win_formlen (); MainApp()->enable_menu_item(M_FILE_PG_SETUP); return; } _curprn = atoi(mask.get(MSK_1_PRINTERS)); if (mask.get (MSK_1_SAVE).not_empty ()) { TString s ("printer.def"); mask.set_workfile (s); mask.save (); } _ncopies = atoi (mask.get (MSK_1_NPAGES)); 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; freeze (FALSE); _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 ("bagn004"); 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 //