#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 //