diff --git a/include/form.cpp b/include/form.cpp index 3ba775fce..b1bf29c45 100755 --- a/include/form.cpp +++ b/include/form.cpp @@ -574,10 +574,10 @@ void TForm_item::print_on(TToken_string& row) const row.add(key()); row.add(_y); row.add(_x); + row.add(shown() ? " " : "X"); if (form().edit_level() > 1) { - row.add(shown() ? " " : "X"); const long fu = _group.first_one(); if (fu > 0) row.add(fu); else row.add(" "); @@ -861,10 +861,18 @@ protected: void put_paragraph(const char* s); public: + virtual bool edit(TMask& m); TForm_string(TPrint_section* section) : TForm_item(section) {} virtual ~TForm_string() {} }; +bool TForm_string::edit(TMask& m) +{ + const bool godmode = form().edit_level() > 1; + m.enable(F_PROMPT, godmode ? TRUE : (_field.items()==0)); + return TForm_item::edit(m); +} + bool TForm_string::parse_item(TScanner& scanner) { if (scanner.key() == "FI") @@ -1071,7 +1079,7 @@ class TForm_number : public TForm_string { protected: // TForm_string virtual const char* class_name() const { return "NUMERO"; } - virtual bool parse_head(TScanner& scanner); +virtual bool parse_head(TScanner& scanner); virtual bool update(); virtual int height() const { return 0; } @@ -1107,20 +1115,28 @@ bool TForm_number::update() if (!picture().blank()) { TToken_string delim(4, ','); // Stringa con i due delimitatori - const char* pic = picture(); // Picture senza delimitatori - + TString pic(picture()); // Picture senza delimitatori + int maxlen = -1; + int at = pic.find('@'); + if (at >= 0) + { + maxlen = atoi(&pic[at+1]); + pic.cut(at); + } if (pic[0] == '(') // Se ci sono i delimitatori ... { - const int bra = picture().find(')'); + const int bra = pic.find(')'); if (bra > 0) // ... cerca la parentesi chiusa { - delim = picture().sub(1, bra); // memorizza delimitatori - pic += bra+1; // toglili dalla picture + delim = pic.sub(1, bra); // memorizza delimitatori + pic.ltrim(bra + 1); // toglili dalla picture } } TString80 s(n.string(pic)); // riempi la stringa col valore pitturato - + + if (maxlen >= 0) + s.cut(maxlen); if (!delim.empty_items()) // Aggiungi delimitatori { TString16 d(delim.get(0)); @@ -1641,15 +1657,12 @@ bool TPrint_section::edit(const char* title) m.set_caption(title); m.set(F_HEIGHT, _height); m.set(F_X, form().offset_x()); - m.set(F_Y, form().offset_y()); + m.set(F_Y, form().offset_y()); + m.set(F_CTP, format("%c",form().char_to_pos())); + m.set(F_IPX, form().ipx()); + m.set(F_IPY, form().ipy()); + m.set(F_FPX, form().fpx()); m.set(F_FLEN, printer().formlen()); - // Calcola la sommatoria delle lunghezze delle varie sezioni di questa pagina... - int sum=form().height(_page_type); - if (_sec_type == 'G') sum = _height; // Se e' grafic section ho tutto il foglio a disposizione! - // ... devo pero' sottrarre la lunghezza della sezione corrente... - sum -= _height; //N.B. non e' mai negativo, perche' form().height() ritorna la lunghezza compresa la sezione corrente!! - // ... il risultato lo decurto dalla lunghezza del foglio ed ottengo la lunghezza disponibile. - m.set(F_FLENAV, printer().formlen() - sum); { const int MAX_FAMILIES = 128; @@ -1691,6 +1704,14 @@ bool TPrint_section::edit(const char* title) form().offset_y() = m.get_int(F_Y); form().set_dirty(); _dirty = TRUE; + } + if (m.get(F_CTP)[0] != form().char_to_pos()) + { + form().char_to_pos() = m.get(F_CTP)[0]; + form().ipx() = m.get_int(F_IPX); + form().ipy() = m.get_int(F_IPY); + form().fpx() = m.get_int(F_FPX); + _dirty = TRUE; } TString80 name(m.get(F_FONT)); @@ -2082,7 +2103,22 @@ bool TForm::parse_general(TScanner &scanner) else scanner.push(); if (scanner.popkey() == "SI") // Font size _fontsize = scanner.integer(); - else scanner.push(); + else scanner.push(); + if (scanner.popkey() == "CA") // Carattere di posizionamento + _char_to_pos = scanner.string()[0]; + else scanner.push(); + if (scanner.popkey() == "IN") // Riga e colonna del posizionamento iniziale + { + _ipx = scanner.integer(); + _ipy = scanner.integer(); + } + else scanner.push(); + if (scanner.popkey() == "FI") // Riga e colonna del posizionamento finale + { + _fpx = scanner.integer(); + } + else scanner.push(); + extended_parse_general(scanner); // Parse non-standard parameters } } else scanner.push(); @@ -2095,7 +2131,13 @@ void TForm::print_general(ostream& out) const out << "GENERAL\nBEGIN\n"; out << " OFFSET " << _x << " " << _y << "\n"; out << " FONT " << "\"" << _fontname << "\"\n"; - out << " SIZE " << _fontsize << "\n" ; + out << " SIZE " << _fontsize << "\n" ; + if (_char_to_pos != '\0') + { + out << " CARATTERE " << _char_to_pos << "\n" ; + out << " INIZIO_POS " << _ipx << " " << _ipy << "\n"; + out << " FINE_POS " << _fpx << "\n"; + } out << "END\n" << endl; } @@ -2236,7 +2278,72 @@ void TForm::footer_handler(TPrinter& p) word TForm::page(const TPrinter& p) const { return _lastpage ? 0 : p.getcurrentpage(); -} +} + +void TForm::arrange_form() +{ + TString device; +#if XVT_OS == XVT_OS_WIN + char defPrinter[80]; + char szDevice[50]; + + // get default printer driver + GetProfileString ("windows", "device", ",,,", defPrinter, sizeof(defPrinter)); + TToken_string pdev (defPrinter, ','); + GetProfileString ("devices", pdev, "", szDevice, sizeof(szDevice)); + pdev.add(szDevice); + device = pdev.get(2); + device = device.left(4); //Legge solo LPTx... +#endif + FILE* lpt = fopen(device,"w"); + // Nota: siccome si scrive direttamente sulla porta, sarebbe necessario + // mandare una stringa di reset alla stampante, o per lo meno far si' che + // ogni volta che si fa il posizionamento il font col quale scrive sia sempre + // lo stesso. Tutto cio' non e' possibile con la generica solo testo, o meglio + // ad ogni stampa col posizionamento e' necessario che la stampante sia resettata. + // Riassumendo, come regola generale, i posizionamenti devono essere fatti con il + // font di default della stampante (tipicamente 10 cpi). Accade pero' (con la generica + // solo testo) che rimanga settato l'ultimo font, di conseguenza quando si effettua una + // seconda stampa con posizionamento, stampera' tali caratteri in 17"!!!! Per questo + // motivo e' necessario settare a 17 cpi, almeno la prima volta, la stampante!. + // Quindi, per ovviare a tutto cio, visto che TForm::arange_form() ha senso solo su + // stampanti ad aghi, che le stampanti ad aghi possono andare in emulazione EPSON o IBM, + // che il codice per settare il font draft 17cpi e' lo stesso sia per EPSON che IBM + // CHR(15), allora prima del posizionamento scrivo il chr(15) sulla stampante! + int i, x; + TString str_pos; + if (lpt == NULL) fatal_box("Non rieso ad aprire il device %s.",device); + TMask m("ba2100c"); + + // _ipy viene assunto uguale per entrambi i posizionamneti + str_pos << "\017"; // Questo e' 15 in ottale... + for (i=1; i < _ipy; i++) str_pos << "\n"; + fprintf(lpt,"%s",(const char*) str_pos); + fflush(lpt); // Salta le righe... + str_pos.cut(0); //Azzera la stringa di posizionamento + for (i=1; i < _ipx; i++) str_pos << " "; //Aggiunge gli spazi necessari... + if (_ipx > 0 && _ipy > 0) + str_pos << _char_to_pos; // aggiunge il primo carattere di posizionamento... + x = _fpx - _ipx ; // calcola quanti spazi aggiungere... + for (i=1; i < x; i++) str_pos << " "; + if (_fpx > 0) + str_pos << _char_to_pos; // aggiunge il secondo carattere di posizionamento + TString bspc; bspc.fill('\b',str_pos.len()); // Questi sevono per tornare indietro... + do + { + fprintf(lpt,"%s",(const char*) bspc); + fprintf(lpt,"%s",(const char*) str_pos); + fflush(lpt); + } while (m.run() == K_ESC); // cicla sulla stampa posizionamento... + const int h = height(odd_page); + str_pos.cut(0); + for (i=0; i <= h; i++) str_pos << "\n"; + fprintf(lpt, "%s", (const char*) str_pos); // Salta tante righe quanto e' lungo il form standard + fclose (lpt); +#if XVT_OS != XVT_OS_WIN +#pragma message ("Voglio proprio vedere come fai a gestire il posizionamento sotto Unix!") +#endif +} long TForm::records() const { @@ -2251,32 +2358,53 @@ bool TForm::print(long from, long to) { _cur_form = this; - TPrinter& pr = printer(); // Setta handlers - pr.setheaderhandler(header_handler); - pr.setfooterhandler(footer_handler); - for (pagetype t = odd_page; t <= last_page; t = pagetype(t+1)) + if ((_char_to_pos != '\0' || ((_ipx +_ipy+_fpx) != 0)) && // Se i parametri di posizionamento sono settati e + (_x != 0 || _y != 0)) // cosi' pure gli offset genera un errore. { - if (height(t)> (word)pr.formlen()) - { - TString s("La lunghezza totale della sezione "); - switch ( t ) - { - case odd_page: - s << "standard"; break; - case even_page: - s << "pagine pari"; break; - case first_page: - s << "prima pagina"; break; - case last_page: - s << "ultima pagina"; break; - default: - break; - } - s << " eccede la lunghezza reale del foglio."; - message_box(s); - } + error_box("Non e' possibile settare contemporaneamente gli offset" + " e i parametri di posizionamento del modulo."); + return FALSE; + } + TPrinter& pr = printer(); + if (_char_to_pos != '\0' || (_ipx +_ipy+_fpx) != 0) // Effettua il posizionamento del form... + { + if (pr.printtype() == screenvis) + error_box("Stampa a video selezionata. Non e' possibile effettuare il posizionamento."); + else + arrange_form(); + } + + pr.setheaderhandler(header_handler); // Setta handlers + pr.setfooterhandler(footer_handler); + if (!pr.is_generic()) + { + for (pagetype t = odd_page; t <= last_page; t = pagetype(t+1)) + { + if (height(t)> (word)pr.formlen()) + { + TString s("La lunghezza totale della sezione "); + switch ( t ) + { + case odd_page: + s << "standard"; break; + case even_page: + s << "pagine pari"; break; + case first_page: + s << "prima pagina"; break; + case last_page: + s << "ultima pagina"; break; + default: + break; + } + s << " eccede la lunghezza reale del foglio."; + message_box(s); + } + } + } + else + { + pr.formlen(height(odd_page)); } - pr.formlen(height(odd_page)); pr.set_char_size(_fontsize); // Set font name and size pr.set_fontname(_fontname); // according to current form const bool was_open = pr.isopen(); @@ -2440,6 +2568,10 @@ bool TForm::read_profile() _y = prof.get_int("OFFY"); _fontname = prof.get("FONTNAME"); _fontsize = prof.get_int("FONTSIZE"); + _char_to_pos = prof.get_char("CTP"); + _ipx = prof.get_int("IPX"); + _ipy = prof.get_int("IPY"); + _fpx = prof.get_int("FPX"); } } return TRUE; @@ -2461,6 +2593,10 @@ bool TForm::write_profile() form.put("OFFX",_x); form.put("FONTNAME",_fontname); form.put("FONTSIZE",_fontsize); + form.put("CTP",_char_to_pos); + form.put("IPX", _ipx); + form.put("IPY", _ipy); + form.put("FPX", _fpx); form.rewrite(); _dirty=FALSE; } @@ -2515,7 +2651,8 @@ bool TForm::write_profile() TForm::TForm(const char* name, const char* code, int lev, const char* desc) : _name(name), _code(code), _relation(NULL), _cursor(NULL), _rel_desc(NULL), _isnew(FALSE), _editlevel(lev), _desc(desc), _fontname("Courier New"), - _fontsize(12), _x(0), _y(0), _dirty(FALSE) + _fontsize(12), _x(0), _y(0), _char_to_pos('\0'), _ipx(0), _ipy(0), _fpx(0), + _dirty(FALSE) { main_app().begin_wait(); @@ -2538,6 +2675,10 @@ TForm::TForm(const char* name, const char* code, int lev, const char* desc) forms.put("OFFX",_x); forms.put("FONTNAME",_fontname); forms.put("FONTSIZE",_fontsize); + forms.put("CTP", _char_to_pos); + forms.put("IPX", _ipx); + forms.put("IPY", _ipy); + forms.put("FPX", _fpx); forms.write(); } else _desc = forms.get("DESC"); diff --git a/include/form.h b/include/form.h index 47ffb6d1d..ddc67179b 100755 --- a/include/form.h +++ b/include/form.h @@ -97,6 +97,9 @@ class TForm : public TObject TString80 _fontname; // Font name int _fontsize; // Font size int _x, _y; // Offset validi per tutte le sezioni + char _char_to_pos; // Carattere utilizzato per il posizionamento dei moduli + int _ipx, _ipy; // Coordinate del posizionamento iniziale + int _fpx; // Coordinata del posizionamento finale (la riga e' la stessa) bool _dirty; // Flag per ragistrare i parametri(font ed offset) TRelation* _relation; // Can be NULL @@ -142,6 +145,7 @@ protected: bool write_profile(); word page(const TPrinter& p) const; + void arrange_form(); virtual long records() const; virtual word set_background(word p, bool u); @@ -168,7 +172,11 @@ public: int& offset_x() { return _x; } int& offset_y() { return _y; } TString80& fontname() { return _fontname; } - int& fontsize() { return _fontsize; } + int& fontsize() { return _fontsize; } + char& char_to_pos(){ return _char_to_pos; } + int& ipx() { return _ipx; } + int& ipy() { return _ipy; } + int& fpx() { return _fpx; } bool dirty() const { return _dirty; } void set_dirty(bool d = TRUE) { _dirty = d; } diff --git a/include/printer.h b/include/printer.h index 485782b5e..d3aa47e2e 100755 --- a/include/printer.h +++ b/include/printer.h @@ -577,6 +577,9 @@ public: // @cmember Crea un segnalibro int set_bookmark(const char* txt, int father = -1); + + // @cmember Ritorna vero se la stampante e' generica/solo testo + bool is_generic() { return (_dots_per_line == 1); } }; diff --git a/include/printwin.cpp b/include/printwin.cpp index 77c27acc2..5eeaccadd 100755 --- a/include/printwin.cpp +++ b/include/printwin.cpp @@ -203,7 +203,12 @@ void TPrintwin::paint_row(long j) } else { set_font(printer().fontname(), XVT_FS_NONE, _char_size); - xvt_dwin_draw_text(win(), 0, y, (char*)_txt.line(j), -1); + TString s(_txt.line(j)); +#if XVT_OS == XVT_OS_WIN + if ((j % _realformlen) == 0 && (j != 0)) // Questa e' la patch per TTY.DRV. + s.insert("\n"); // Quando uscira' un nuovo driver, si dovra' controllare +#endif // se esiste ancora questo piccolo bug. + xvt_dwin_draw_text(win(), 0, y, (char*)(const char*)s, -1); } } @@ -300,6 +305,18 @@ TPrintwin::TPrintwin(TTextfile& txt) #endif _formlen = p.formlen(); + + if (p.is_generic()) + { + long pw, ph, phr, pvr; // Printer width, height, horizontal and vertical resolution + xvt_app_escape (XVT_ESC_GET_PRINTER_INFO, p.get_printrcd(), &ph, &pw, &pvr, &phr); + if (pvr != 0) + _realformlen = int(ph * p.get_lines_per_inch() / pvr); + else + _realformlen = 66; + } + else + _realformlen = 66; // Anche se non e' importante settarlo in altri casi. _formwidth = p.formwidth(); _inited = TRUE; } diff --git a/include/printwin.h b/include/printwin.h index 6a96c543b..1baac806a 100755 --- a/include/printwin.h +++ b/include/printwin.h @@ -34,6 +34,9 @@ class TPrintwin : public TWindow int _formlen; // @cmember Larghezza del modulo di stampa int _formwidth; + // @cmember Lunghezza reale (vale per stampanti Generico/Solo testo) del modulo di stampa + int _realformlen; + // @cmember L'intero background della pagina (vedi ) TArray* _bg; // @cmember TText da stampare