81534d006f
Files correlati : tutti Ricompilazione Demo : [ ] Commento : 0001213: mappa di login, fuoco Lla mappa di login si apre ma per poter digitare la password bisogna cliccare sul campo col mouse. Stesso problema richiamando le ricerche, per esempio quella clienti. git-svn-id: svn://10.65.10.50/trunk@18591 c028cbd2-c16b-5b4b-a496-9718f37d4682
1641 lines
45 KiB
C++
Executable File
1641 lines
45 KiB
C++
Executable File
//#include <ctype.h>
|
||
//#include <stdarg.h>
|
||
|
||
//#include <currency.h>
|
||
#include <tabutil.h>
|
||
#include <printapp.h>
|
||
#include <progind.h>
|
||
#include <urldefid.h>
|
||
#include <utility.h>
|
||
|
||
const char* const printf_types = "dDiIuUoOxXfeEgGcCnNsSpPrRtTaAvV";
|
||
|
||
// _FieldTok flags
|
||
|
||
const word LONG_FLAG = 0x0001;
|
||
const word PICTURE_FLAG = 0x0002;
|
||
const word PAD_FLAG = 0x0004;
|
||
const word ALIGN_FLAG = 0x0008;
|
||
const word TRANS_FLAG = 0x0010;
|
||
const word DATE_FLAG = 0x0020;
|
||
const word STRING_FLAG = 0x0040;
|
||
const word NUMBER_FLAG = 0x0080;
|
||
const word DEC_FLAG = 0x0100;
|
||
const word FONT_FLAG = 0x0200;
|
||
const word JUMP_FLAG = 0x0400;
|
||
const word RECNO_FLAG = 0x0800;
|
||
const word BOOLEAN_FLAG = 0x1000;
|
||
const word IGNORE_FILL = 0x2000;
|
||
const word VALUTA_FLAG = 0x4000;
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// print token containers
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class _Transfield : public TObject
|
||
{
|
||
friend class TPrint_application;
|
||
|
||
int _lognum; // logical number
|
||
TString16 _fn;
|
||
TString _from, _to;
|
||
|
||
public:
|
||
_Transfield (int l, const char *fn, const char *from, const char *to) :
|
||
_lognum(l), _fn(fn), _from (from), _to (to)
|
||
{ }
|
||
virtual ~_Transfield() { }
|
||
};
|
||
|
||
class _Token : public TObject
|
||
{
|
||
friend class TPrint_application;
|
||
int _tag;
|
||
int _row;
|
||
|
||
public:
|
||
int tag() const { return _tag; }
|
||
int row() const { return _row; }
|
||
void tag(int t) { _tag = t; }
|
||
void row (int r) { _row = r; }
|
||
virtual ~ _Token () {}
|
||
};
|
||
|
||
class _PrintfTok : public _Token
|
||
// something to be printed (actually already printed on _val)
|
||
{
|
||
friend class TPrint_application;
|
||
TString _val;
|
||
|
||
public:
|
||
_PrintfTok (int rw, const char *val) : _val(val)
|
||
{ tag(0); row(rw); }
|
||
virtual ~_PrintfTok () {}
|
||
};
|
||
|
||
class _FieldTok : public _Token
|
||
// something more complex to be printed
|
||
{
|
||
friend class TPrint_application;
|
||
int _size, _dec;
|
||
char _align;
|
||
TString80 _fld; // field description
|
||
word _flags; // all you need to know
|
||
|
||
public:
|
||
_FieldTok (int rw, const char *fld, word flags, char align = 'l',
|
||
int size = -1, int dec = -1)
|
||
{
|
||
tag(1);
|
||
row(rw);
|
||
_fld = fld;
|
||
_flags = flags;
|
||
_size = size;
|
||
_align = align;
|
||
_dec = dec;
|
||
}
|
||
|
||
virtual ~_FieldTok () { }
|
||
};
|
||
|
||
class _PrintfRef : public _Token
|
||
// to be printed by reference via format
|
||
// must pass valid pointer to object
|
||
{
|
||
friend class TPrint_application;
|
||
void *_what;
|
||
char _type;
|
||
TString _fmt;
|
||
public:
|
||
_PrintfRef (int rw, const char *fmt, char type, void *what):_fmt (1)
|
||
{
|
||
tag (2);
|
||
row (rw);
|
||
_type = type;
|
||
_what = what;
|
||
_fmt = fmt;
|
||
_fmt[0] = '%';
|
||
}
|
||
virtual ~ _PrintfRef () {}
|
||
};
|
||
|
||
class _PrintRowToken : public _Token
|
||
// printrow direct
|
||
// must pass valid printrow (duplicated)
|
||
{
|
||
friend class TPrint_application;
|
||
TPrintrow _pr;
|
||
public:
|
||
TPrintrow& printrow() { return _pr; }
|
||
_PrintRowToken (int rw, TPrintrow& pr) : _pr((const TPrintrow&)pr)
|
||
{ tag(3); row(rw); }
|
||
virtual ~ _PrintRowToken () {}
|
||
};
|
||
|
||
|
||
void TPrint_application::_reset_tree(link_item * head)
|
||
{
|
||
if (head)
|
||
{
|
||
if (head->_brother)
|
||
_reset_tree (head->_brother);
|
||
if (head->_son)
|
||
_reset_tree (head->_son);
|
||
delete head;
|
||
}
|
||
}
|
||
|
||
// @doc INTERNAL
|
||
|
||
// @mfunc Cerca per il nodo <p head> dove agganciarsi per rispettare la relazione
|
||
//
|
||
// @rdesc Ritorna il nodo a cui agganciarsi
|
||
link_item *TPrint_application::_look_print_node (
|
||
link_item * head, // @parm Nodo per cui effettuare la ricerca
|
||
int logicnum) // @parm Numero logico del file
|
||
|
||
// @comm E' necessario che non esistano piu' nodi per lo stesso file/alias, altrimenti la
|
||
// la ricerca termina alla proma occorrenza incontrata
|
||
{
|
||
link_item *s;
|
||
while (head)
|
||
{
|
||
if (head->_logicnum == logicnum)
|
||
return head;
|
||
else if (head->_son)
|
||
if ((s = _look_print_node (head->_son, logicnum)) != NULL)
|
||
return s;
|
||
head = head->_brother;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Setta un segnalibro nell'anteprima di stampa
|
||
//
|
||
// @rdesc Ritorna il numero identificatore il segnalibro creato
|
||
int TPrint_application::set_bookmark(
|
||
const char* txt, // @parm Testo del segnalibro
|
||
int father) // @parm Identificatore del segnalibro padre (default -1)
|
||
|
||
// @comm L'aggiunta dei segnalibri causa la comparsa del menu 'Indice' nella viswin,
|
||
// con la lista dei segnalibri inseriti; questi possono essere legati ad albero n-ario
|
||
// specificando il bookmark padre, in tal caso il menu sara' gerarchico a sua volta.
|
||
// <nl>Nella prossima release di XVT il menu indice sara' pop-up nella finestra
|
||
|
||
{
|
||
return printer().set_bookmark(txt, father);
|
||
}
|
||
|
||
void TPrint_application::add_file (const char *tab, int from)
|
||
{
|
||
add_file(TTable::name2log(tab), from);
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Aggiunge un file del cursore nell'albero di stampa
|
||
void TPrint_application::add_file (
|
||
int file, // @parm Numero logico del file da aggiungere
|
||
int from) // @parm Posizione nell'albero di stampa nel quale aggiungere il file
|
||
// @parm const char* | tab | Nome del del file da aggiungere
|
||
|
||
// @syntax add_file(int file, int from = 0);
|
||
// @syntax add_file(const char* tab, int from = 0);
|
||
|
||
{
|
||
link_item *nw = new link_item (file);
|
||
if (_pr_tree == NULL)
|
||
{
|
||
_pr_tree = nw;
|
||
return;
|
||
}
|
||
|
||
if (from == 0)
|
||
from = _pr_tree->_logicnum;
|
||
|
||
link_item *fr = _look_print_node (_pr_tree, from);
|
||
|
||
CHECKD (fr, "add_file: nonexistent node: logicnum = ", from);
|
||
|
||
if (fr->_son)
|
||
{
|
||
fr = fr->_son;
|
||
while (fr->_brother)
|
||
fr = fr->_brother;
|
||
fr->_brother = nw;
|
||
}
|
||
else
|
||
fr->_son = nw;
|
||
}
|
||
|
||
// ---------------------------------------------------------------
|
||
// ------------ user function ------------------------------------
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Permette di trovare un link ipertestuale
|
||
//
|
||
// @rdesc Ritorna l'ID del link ipertestuale trovato (-1 se non viene trovato)
|
||
int TPrint_application::find_link(
|
||
const char* descr) const // @parm Testo del link da trovare
|
||
|
||
// @xref <mf TPrint_application::enable_link>
|
||
|
||
{
|
||
const TArray& arr = printer().links();
|
||
for (int i = 0; i < arr.items(); i++)
|
||
{
|
||
TToken_string& tt = (TToken_string&)arr[i];
|
||
const TFixed_string d(tt.get(0));
|
||
if (d == descr)
|
||
return i;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Permette di abilitare determinati colori come indicatori di legame ipertestuale
|
||
//
|
||
// @rdesc Ritorna l'ID del link ipertestuale di cui sono stati abilitati i colori
|
||
int TPrint_application::enable_link(
|
||
const char *descr, // @parm Testo del link da abilitare
|
||
char fg, // @parm Colore del carattere
|
||
char bg) // @parm Colore dello sfondo (default 'w')
|
||
|
||
// @comm Quando si vogliono abilitare determinati colori come indicatori di legame ipertestuale,
|
||
// si faccia enable_link nella create. L' ID ritornato viene passato a process_link
|
||
// assieme al testo selezionato.
|
||
|
||
{
|
||
int lnk = find_link(descr);
|
||
if (lnk < 0)
|
||
{
|
||
TToken_string *tt = new TToken_string(30);
|
||
char b[2] = { '\0', '\0' };
|
||
tt->add(descr);
|
||
b[0] = fg;
|
||
tt->add(b);
|
||
b[0] = bg;
|
||
tt->add(b);
|
||
lnk = printer().links().add(tt);
|
||
}
|
||
|
||
return lnk;
|
||
}
|
||
|
||
void TPrint_application::disable_link (char fg, char bg)
|
||
{
|
||
for (int i = 0; i < printer().links().items (); i++)
|
||
{
|
||
TToken_string & t = (TToken_string&)printer().links()[i];
|
||
const char f = *(t.get(1));
|
||
const char b = *(t.get());
|
||
if (f == fg && b == bg)
|
||
{
|
||
printer().links().remove(i, TRUE);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Abilita/disabilita pi<70> link per la <mf TPrint_application::enable_link>
|
||
void TPrint_application::set_multiple_link (
|
||
bool on) // @parm Indica se effettuare il link con tutti gli elementi selezioanti della riga
|
||
|
||
// @comm Se si setta <p on> a TRUE anziche' la descrizione del testo selezionato
|
||
// viene passata a <mf TPrint_application::enable_link> una tokenstring con tutti i
|
||
// 'bottoni' dello stesso colore presenti sulla riga.
|
||
|
||
{
|
||
printer().setmultiplelink (on);
|
||
}
|
||
|
||
bool TPrint_application::_pp_link (int id, const char *text)
|
||
{
|
||
TPrint_application& prapp = (TPrint_application&)main_app();
|
||
return prapp.process_link(id, text);
|
||
}
|
||
|
||
void TPrint_application::_pp_header (TPrinter& p)
|
||
{
|
||
TPrint_application& prapp = (TPrint_application&)main_app();
|
||
prapp.preprocess_header();
|
||
p.resetheader();
|
||
const int ii = prapp._header.last();
|
||
// reset and add header/footer lines
|
||
for (int i = 0; i <= ii; i++)
|
||
{
|
||
TPrintrow* pr = (TPrintrow*)prapp._header.objptr(i);
|
||
if (pr) p.setheaderline (i, new TPrintrow(*pr));
|
||
}
|
||
}
|
||
|
||
void TPrint_application::_pp_footer (TPrinter& p)
|
||
{
|
||
TPrint_application& prapp = (TPrint_application&)main_app();
|
||
|
||
prapp.preprocess_footer ();
|
||
p.resetfooter ();
|
||
int ii = prapp._footer.last();
|
||
for (int i = 0; i <= ii; i++)
|
||
{
|
||
TPrintrow* pr = (TPrintrow*)prapp._footer.objptr(i);
|
||
if (pr) p.setfooterline (i, new TPrintrow(*pr));
|
||
}
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Permette di stampare sullo sfondo e per variarne gli attributi
|
||
void TPrint_application::set_background (
|
||
const char *bgdesc) // @parm Stringa contente i codici per la stampa (vedi descrizione)
|
||
|
||
|
||
// @comm Occorre passare una stringa che contiene codici per stampare box, linee, bitmap
|
||
// sullo sfondo, e per variarne gli attributi: se NULL lo azzera.
|
||
// <nl>Il background e' stampato sia su <c TViswin> che su stampante, e riguarda
|
||
// una PAGINA fisica e non le righe o le "pages" relative al cursore;
|
||
// viene replicato ad ogni nuova pagina fisica a meno che non venga cancellato
|
||
// o ridefinito in una <lt>qualcosa<gt>process<lt>qualcos'altro<gt>().
|
||
// <nl><nl>CODICI BACKGROUND
|
||
// <nl>Una stringa con n codici, opzionalmente separati da spazi o tab
|
||
// <nl>SETTINGS
|
||
// @flag P<lt>n<gt> | Setta pen style (n = codice XVT)
|
||
// @flag B<lt>n<gt> | Setta brush style (idem)
|
||
// @flag W<lt>n<gt> | Altezza della linea in pixel
|
||
// @flag C<lt>n<gt> | Colore della penna (codice colore solito)
|
||
// @comm <nl><nl> DRAWING COMMANDS
|
||
// @flag i{string,x1,y1,x2,y2} | Disegna la bitmap <p string> (nome file) alle coordinate indicate
|
||
// @flag l{x1,y1,x2,y2} | Linea da/a (la resa delle oblique dipende dalla stampante)
|
||
// @flag b{x1,y1,x2,y2} | Box
|
||
// @flag r{x1,y1,x2,y2} | Rounded box
|
||
// @flag t{text,x,y} | Testo <lt>text<gt> a <p x>, <p y>
|
||
|
||
{
|
||
printer().setbackground (bgdesc);
|
||
}
|
||
|
||
const char* FLD (int lognum, const char *f, int from, int to)
|
||
{
|
||
TString80 tb; tb.format("%c|%d|%s|%d|%d", 'n', lognum, f, from, to);
|
||
return _strdup(tb);
|
||
}
|
||
|
||
const char* FLD (int lognum, const char *f, const char *picture)
|
||
{
|
||
TString80 tb; tb.format("%c|%d|%s|%s", 'p', lognum, f, picture);
|
||
return _strdup(tb);
|
||
}
|
||
|
||
const char* FLD (const char *tabname, const char *f, int from, int to)
|
||
{
|
||
CHECKS (strlen (tabname) < 5, "Invalid table name", tabname);
|
||
const int lognum = TTable::name2log (tabname);
|
||
TString80 tb; tb.format("%c|%d|%s|%d|%d", 'n', lognum, f, from, to);
|
||
return _strdup(tb);
|
||
}
|
||
|
||
const char* FLD (const char *tabname, const char *f, const char *picture)
|
||
{
|
||
CHECKS (strlen(tabname) <= 4, "Invalid table name", tabname);
|
||
const int lognum = TTable::name2log(tabname);
|
||
TString80 tb; tb.format("%c|%d|%s|%s", 'p', lognum, f, picture);
|
||
return _strdup(tb);
|
||
}
|
||
|
||
TString& fill_str (TString & t, char f)
|
||
{
|
||
const int len = t.len();
|
||
int kk;
|
||
for (kk = len - 1; kk >= 0; kk--)
|
||
if (t[kk] == ' ') t[kk] = f;
|
||
else break;
|
||
for (kk = 0; kk < len; kk++)
|
||
if (t[kk] == ' ') t[kk] = f;
|
||
else break;
|
||
return t;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Printapp code at last
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void TPrint_application::select_cursor (int c)
|
||
{
|
||
if (c < 0) _cur = NULL;
|
||
else _cur = (TCursor *) & _cursors[c];
|
||
}
|
||
|
||
TCursor* TPrint_application::get_cursor (int c)
|
||
{
|
||
if (c < 0) return NULL;
|
||
else return (TCursor *) & _cursors[c];
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Aggiunge un cursore alla classe
|
||
//
|
||
// @rdesc Ritorna l'identificatore del cursore aggiunto
|
||
int TPrint_application::add_cursor (
|
||
TCursor * c) // @parm Cursore da aggiungere all'albero
|
||
|
||
// @comm Nel caso sia passato NULL a <p c> non viene utilizzato nessun file, ma la
|
||
// <mf TPirnt_application::print_one> viene chaiamta e le iterazione sono valoutate da
|
||
// pre_ e post_ process.
|
||
|
||
{
|
||
if (c == NULL)
|
||
return -1;
|
||
_cursors.add (c);
|
||
_cur = c;
|
||
return _cursors.items() - 1;
|
||
}
|
||
|
||
void TPrint_application::reset_row (int r)
|
||
{
|
||
r--;
|
||
int tmp = _rows.items ();
|
||
for (int j = 0; j < tmp; j++)
|
||
{
|
||
_Token *t = (_Token *) (_rows.objptr (j));
|
||
if (t)
|
||
{
|
||
if (t->row () == r)
|
||
_rows.add (NULL, j);
|
||
}
|
||
}
|
||
_rows.pack ();
|
||
if (_maxrow == r && _maxrow > 0)
|
||
_maxrow--;
|
||
}
|
||
|
||
void TPrint_application::reset_print ()
|
||
{
|
||
_rows.destroy ();
|
||
_maxrow = 0;
|
||
_print_defined = FALSE;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Permette di definire l'header della stampa
|
||
void TPrint_application::set_header (
|
||
int r, // @parm Numero della riga nella quale stampare l'header
|
||
const char *fmt, // @parm Testo dell'header da stampare
|
||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||
|
||
{
|
||
TString256 tmp;
|
||
|
||
CHECK (r >= 1, "Header rows start at 1");
|
||
va_list vl;
|
||
va_start (vl, fmt);
|
||
vsprintf (tmp.get_buffer(), fmt, vl);
|
||
va_end (vl);
|
||
|
||
TPrintrow *pp = (TPrintrow *)_header.objptr(r - 1);
|
||
if (!pp)
|
||
{
|
||
pp = new TPrintrow;
|
||
_header.add (pp, r - 1);
|
||
}
|
||
pp->put (tmp);
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Permette di definire il footer della stampa
|
||
void TPrint_application::set_footer (
|
||
int r, // @parm Numero della riga nella quale stampare il footer
|
||
const char *fmt, // @parm Testo del footer da stampare
|
||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||
|
||
{
|
||
CHECK (r >= 1, "Footer rows start at 1");
|
||
TString256 tmp;
|
||
va_list vl;
|
||
va_start (vl, fmt);
|
||
vsprintf (tmp.get_buffer(), fmt, vl);
|
||
va_end (vl);
|
||
TPrintrow *pp = (TPrintrow *) _footer.objptr (r - 1);
|
||
if (pp == NULL)
|
||
{
|
||
pp = new TPrintrow;
|
||
_footer.add (pp, r - 1);
|
||
}
|
||
pp->put (tmp);
|
||
}
|
||
|
||
void TPrint_application::reset_header ()
|
||
{
|
||
_header.destroy ();
|
||
printer().resetheader ();
|
||
}
|
||
|
||
void TPrint_application::reset_footer ()
|
||
{
|
||
_footer.destroy ();
|
||
printer().resetfooter ();
|
||
}
|
||
|
||
void TPrint_application::fill_page (int from)
|
||
{
|
||
from--;
|
||
for (int i = (from == -1 ? _maxrow : from); i <= printer().formlen (); i++)
|
||
{
|
||
reset_row (i);
|
||
set_row (i, "");
|
||
}
|
||
}
|
||
|
||
void TPrint_application::merge_export_file(const char* file, bool header, bool direct)
|
||
{
|
||
if (direct) printer().merge_export_file(file, header);
|
||
else
|
||
{
|
||
set_row(_currow+1,"");
|
||
TTextfile txt(file);
|
||
for (long i = 0l; i < txt.lines(); i++)
|
||
set_row(_currow+(int)i+1 + (i == 0l ? 1 : 0), txt.line_formatted(i));
|
||
}
|
||
}
|
||
|
||
void TPrint_application::set_row(int r, TPrintrow& pr)
|
||
{
|
||
CHECK (r >= 1, "Print rows start at 1");
|
||
_print_defined = TRUE;
|
||
_currow = --r;
|
||
if (_currow > _maxrow)
|
||
_maxrow = _currow;
|
||
_rows.add(new _PrintRowToken(_currow, pr));
|
||
}
|
||
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Permette di settare una riga di stampa
|
||
void TPrint_application::set_row (
|
||
int r, // @parm Numero della riga da settare
|
||
const char *frmt, // @parm Contenuto della riga da stampare
|
||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p frmt>
|
||
|
||
// @comm COME SETTARE LE RIGHE DI STAMPA
|
||
// <nl><nl>Questa funzione si usa come una printf per settare le righe di stampa
|
||
// che vengono stampate da <mf TPrint_application::print>.
|
||
// <nl>I codici per gli argomenti variabili sono di 3 tipi:
|
||
// @flag @ | Si usa per stampare campi di database o informazioni di controllo
|
||
// posizione carrello e font
|
||
// ATTENZIONE: i codici di formato sono diversi da quelli di printf e
|
||
// sono elencati sotto. Per i campi di database occorre che il codice
|
||
// sia accoppiato ad una delle funzioni <f FLD> passata come argomento;
|
||
// questa provoca la stampa di campi della relazione corrente,
|
||
// posizionata come e' stato deciso nell'inizializzazione
|
||
// @flag % | Si usa esattamente come in una printf con un plus: se il codice di
|
||
// formato e' maiuscolo (es. S per stringa, D per intero) viene
|
||
// ignorato il carattere di riempimento eventualmente specificato
|
||
// con <mf TPrint_application::set_fillchar>. Cio' vale anche per i codici @ (vedi)
|
||
// <nl>E' possibile usare due codici aggiuntivi: r(R) e t(T). A questi
|
||
// va fatto seguire un PUNTATORE a <c real> o a <c TString>. Il formato
|
||
// viene interpretato con le stesse regole di %t in dsprintf per real
|
||
// (come %d o %f) e di %s per TString. Il puntatore NON
|
||
// viene memorizzato; per questo occorre il codice # (sotto).
|
||
// @flag # | Si usa come % (stessi codici di printf) ma memorizza gli argomenti
|
||
// per riferimento: ovvero, ogni volta che la riga viene stampata
|
||
// viene stampato il contenuto in quel momento (che si puo' cambiare
|
||
// in una delle pre- o post- process). Cio' implica che:
|
||
// 1) gli argomenti vanno passati per RIFERIMENTO (set_row(1,"#5d",&i))
|
||
// 2) i puntatori devono rimanere validi e costanti tra la set_row e
|
||
// la fine della stampa
|
||
// Quindi, attenzione a %s con <c TString> ridimensionate; si possono
|
||
// usare solo se predimensionate alla dimensione massima, ma e' meglio
|
||
// usare char* o il codice apposito. I codici #r, #a e #t prendono puntatori a
|
||
// real, <c TParagraph_string> e a <c TString>, memorizzandoli. Non ci sono problemi con la resize.
|
||
// Comunque, il modo corretto di adoperare il codice # e'
|
||
// usarlo solo per stampare MEMBRI della classe derivata da TPrint_application
|
||
//
|
||
// @comm <nl><nl>CODICI DI CAMPO (da utilizzare con una delle funzione <f FLD>):
|
||
// @flag @@ | Carattere @
|
||
// @flag @[n[,{l<pipe>c<pipe>r}]s | STRING: n = pad, lcr = alignment
|
||
// @flag @{[n[.d=0]]<pipe>[n[,{l<pipe>c<pipe>r}]]p}n | NUMBER: n = digits, d = decimals
|
||
// p = picture string (first matching arg)
|
||
// @flag @[l]d | DATE: l = full year
|
||
// @flag @f | BOOL: prints si/no
|
||
// @flag @[n,{l<pipe>c<pipe>r}]t | Translated field (must set translation)
|
||
//
|
||
// @comm Tutti questi codici possono essere usati anche maiuscoli, il che inibisce
|
||
// l'uso del carattere di riempimento (set_fillchar) per uno specifico campo.
|
||
//
|
||
// <nl><nl>Per tutti i codici che riguardano la stampa di <c real> (@n, %r, #r)
|
||
// se non vengono date ulteriori specifiche di formato viene usata
|
||
// una picture che e' "" per default, ma puo' essere modificata con
|
||
// <mf TPint_application::set_real_picture>.
|
||
// <nl>Normalmente un real uguale a zero viene stampato come stringa vuota
|
||
// a meno che non si specifichi TRUE nella <mf TPrint_application::set_print_zero>.
|
||
//
|
||
// <nl><nl>CODICI POSIZIONAMENTO E MOVIMENTO CARRELLO
|
||
// @flag @<lt>n<gt>g | Vai a posizione n
|
||
// @flag @<lt>n<gt>j | Salta di n posizioni (in orizzontale)
|
||
// @comm <nl><nl>CODICI STILE
|
||
// @flag @b | Grassetto
|
||
// @flag @i | Corsivo
|
||
// @flag @u | Sottolineato
|
||
// @flag @r | Ritorna allo stile normale
|
||
//
|
||
// @comm <nl><nl>CODICI COLORE PER VISUALIZZAZIONE E COLLEGAMENTO
|
||
//
|
||
// <nl><nl>Se si vuole che in visualizzazione il testo sia colorato
|
||
// si usa il codice $[]; tra le quadre si scrive il colore
|
||
// di foreground, opzionalmente seguito da una virgola e dal
|
||
// colore di background (bianco per default). I colori si
|
||
// specificano con un singolo carattere come segue:
|
||
// @flag n | Nero
|
||
// @flag g | Verde
|
||
// @flag b | Blu
|
||
// @flag c | Cyan
|
||
// @flag y | Giallo
|
||
// @flag v | Magenta
|
||
// @flag m | Colore background maschere (azzurrotto)
|
||
// @flag d | Grigio scuro
|
||
// @flag l | Grigio chiaro
|
||
// @flag k | Grigio normale
|
||
//
|
||
// @comm <nl><nl>Se si fa <mf TPrint_application::enable_link> con un certo colore, tutto
|
||
// cio che e' scritto in quel colore diventa selezionabile
|
||
// e alla sua selezione (premendo 'Collega') si puo' associare
|
||
// un'azione in <mf TPrint_application::process_link>. A quest'ultima viene passata
|
||
// l'ID ritornata da enable_link() e il testo selezionato alla
|
||
// pressione di Collega. Vedere ba6 e stampare l'elenco (con
|
||
// Includi ditte abilitato) per un esempio.
|
||
|
||
{
|
||
CHECK (r >= 1, "Print rows start at 1");
|
||
|
||
r--;
|
||
|
||
char digbuf[10];
|
||
TString bigbuf(256);
|
||
char* strbuf = bigbuf.get_buffer();
|
||
|
||
// let the poor programmer use format() at will
|
||
const TString fftt(frmt);
|
||
|
||
char fill = _fillchar;
|
||
|
||
word flags = 0;
|
||
int size = 0, dec = 0, strind = 0;
|
||
char ch, align = 'l';
|
||
|
||
_print_defined = TRUE;
|
||
|
||
_currow = r;
|
||
if (_currow > _maxrow)
|
||
_maxrow = _currow;
|
||
|
||
va_list params;
|
||
va_start(params, frmt);
|
||
|
||
// parse format string
|
||
const char* fmt = fftt;
|
||
while ((ch = *fmt++) != '\0')
|
||
{
|
||
if (ch == '@')
|
||
{
|
||
// check for pending string
|
||
if (strind)
|
||
{
|
||
strbuf[strind] = '\0';
|
||
_rows.add (new _PrintfTok (_currow, strbuf));
|
||
strind = 0;
|
||
}
|
||
ch = *fmt++;
|
||
if (isdigit (ch))
|
||
{
|
||
int i = 0;
|
||
digbuf[i++] = ch;
|
||
while (isdigit (ch = *fmt++))
|
||
digbuf[i++] = ch;
|
||
digbuf[i] = '\0';
|
||
size = atoi (digbuf);
|
||
flags |= PAD_FLAG;
|
||
if (ch == '.')
|
||
{
|
||
// decimal size follows
|
||
i = 0;
|
||
digbuf[i++] = ch;
|
||
while (isdigit (ch = *fmt++))
|
||
digbuf[i] = ch;
|
||
digbuf[i] = '\0';
|
||
dec = atoi (digbuf);
|
||
flags |= DEC_FLAG;
|
||
}
|
||
else if (ch == ',')
|
||
{
|
||
// aligment spec follows
|
||
align = (ch = *fmt++);
|
||
CHECK (ch == 'l' || ch == 'r' || ch == 'c',
|
||
"TPrint_application::set_row: invalid alignment spec");
|
||
flags |= ALIGN_FLAG;
|
||
ch = *fmt++;
|
||
}
|
||
}
|
||
switch (ch)
|
||
{
|
||
// modifiers
|
||
case 'l':
|
||
case 'L':
|
||
flags |= LONG_FLAG;
|
||
ch = *fmt++;
|
||
break;
|
||
case 'p':
|
||
case 'P':
|
||
flags |= PICTURE_FLAG;
|
||
ch = *fmt++;
|
||
break;
|
||
}
|
||
switch (ch)
|
||
{
|
||
// codes
|
||
case '@':
|
||
_rows.add (new _PrintfTok (_currow, "@"));
|
||
break;
|
||
case 'b':
|
||
case 'i':
|
||
case 'u':
|
||
case 'r':
|
||
{
|
||
char x[2] = { ch, '\0' };
|
||
_rows.add (new _FieldTok (_currow, x, FONT_FLAG));
|
||
}
|
||
break;
|
||
case 'g':
|
||
case 'j':
|
||
{
|
||
const char* x = format ("%c %d", ch, size);
|
||
_rows.add (new _FieldTok (_currow, x, JUMP_FLAG));
|
||
}
|
||
break;
|
||
case 'T':
|
||
flags |= IGNORE_FILL;
|
||
// fall down
|
||
case 't':
|
||
flags |= TRANS_FLAG;
|
||
break;
|
||
case 'D':
|
||
flags |= IGNORE_FILL;
|
||
// fall down
|
||
case 'd':
|
||
flags |= DATE_FLAG;
|
||
break;
|
||
case 'F':
|
||
flags |= IGNORE_FILL;
|
||
// fall down
|
||
case 'f':
|
||
flags |= BOOLEAN_FLAG;
|
||
break;
|
||
case 'S':
|
||
flags |= IGNORE_FILL;
|
||
// fall down
|
||
case 's':
|
||
flags |= STRING_FLAG;
|
||
break;
|
||
case 'C':
|
||
flags |= IGNORE_FILL;
|
||
// fall down
|
||
case 'c':
|
||
flags |= RECNO_FLAG;
|
||
break;
|
||
case 'N':
|
||
flags |= IGNORE_FILL;
|
||
// fall down
|
||
case 'n':
|
||
if (_magic_currency)
|
||
{
|
||
if (size >= 9 && dec == 0 && _picture.find(',') < 0)
|
||
{
|
||
flags |= VALUTA_FLAG;
|
||
flags &= ~PAD_FLAG;
|
||
}
|
||
else
|
||
flags |= NUMBER_FLAG;
|
||
}
|
||
else
|
||
flags |= NUMBER_FLAG;
|
||
break;
|
||
case 'V':
|
||
flags |= IGNORE_FILL;
|
||
// fall down
|
||
case 'v':
|
||
flags |= VALUTA_FLAG;
|
||
flags &= ~PAD_FLAG;
|
||
break;
|
||
default:
|
||
CHECK (0, "TPrint_application::set_row: invalid @ code");
|
||
break;
|
||
}
|
||
if (flags & NUMBER_FLAG ||
|
||
flags & DATE_FLAG ||
|
||
flags & TRANS_FLAG ||
|
||
flags & BOOLEAN_FLAG ||
|
||
flags & STRING_FLAG ||
|
||
flags & VALUTA_FLAG)
|
||
{
|
||
char* x = va_arg (params, char *);
|
||
_rows.add (new _FieldTok (_currow, x, flags, align, size, dec));
|
||
delete x; // FLD macro has mallocated it!
|
||
}
|
||
flags = 0x0000;
|
||
align = 'l';
|
||
}
|
||
else
|
||
{
|
||
switch (ch)
|
||
{
|
||
case '#':
|
||
case '%':
|
||
{
|
||
const char ccc = ch;
|
||
// check for pending string
|
||
if (strind)
|
||
{
|
||
strbuf[strind] = '\0';
|
||
_rows.add (new _PrintfTok (_currow, strbuf));
|
||
strind = 0;
|
||
}
|
||
if ((ch = *fmt++) == ccc)
|
||
_rows.add (new _PrintfTok (_currow, ccc == '%' ? "%" : "#"));
|
||
else
|
||
{
|
||
// read format
|
||
TString80 formato;
|
||
formato << ccc;
|
||
bool islong = FALSE;
|
||
while (strchr (printf_types, ch) == NULL)
|
||
{
|
||
formato << ch;
|
||
if (ch == 'l')
|
||
islong = TRUE;
|
||
ch = *fmt++;
|
||
if (ch == '\0')
|
||
NFCHECK("sorry, zer's samzing vruong uitz ioar format.");
|
||
}
|
||
if (isupper (ch))
|
||
{
|
||
ch = tolower (ch);
|
||
fill = ' ';
|
||
}
|
||
if (ch == 't' || ch == 'a')
|
||
formato << 's';
|
||
else if (ch == 'r')
|
||
#ifdef __LONGDOUBLE__
|
||
formato << "Lf";
|
||
#else
|
||
formato << 't';
|
||
#endif
|
||
else
|
||
formato << ch;
|
||
if (ccc == '%')
|
||
{
|
||
TString256 q;
|
||
switch (ch)
|
||
{
|
||
case 'd':
|
||
case 'i':
|
||
case 'u':
|
||
case 'o':
|
||
case 'x':
|
||
case 'X':
|
||
q.format (formato, islong ? va_arg (params, long) : va_arg (params, int));
|
||
break;
|
||
case 'f':
|
||
case 'e':
|
||
case 'E':
|
||
case 'G':
|
||
#ifdef WIN32
|
||
q.format (formato, islong ? va_arg (params, double) : va_arg (params, float));
|
||
#else
|
||
q.format (formato, va_arg (params, double));
|
||
#endif
|
||
break;
|
||
case 'c':
|
||
#ifdef WIN32
|
||
q.format (formato, va_arg (params, char));
|
||
#else
|
||
q.format (formato, va_arg (params, int));
|
||
#endif
|
||
break;
|
||
case 's':
|
||
q.format (formato, va_arg (params, char *));
|
||
break;
|
||
case 't': // TString
|
||
q.format(formato,(const char*)(TString)*((va_arg (params, TString*))));
|
||
break;
|
||
case 'a': // TParagraph_string
|
||
q.format(formato,(const char*)(TParagraph_string)*((va_arg (params, TParagraph_string*))));
|
||
break;
|
||
case 'r': // Real
|
||
{
|
||
const real& rrr = * va_arg (params, real *);
|
||
if (_picture.not_empty() && (formato.len() == 2 || formato == "%Lf"))
|
||
{
|
||
// no format specifications
|
||
// use default picture
|
||
q.cut(0);
|
||
if (_magic_currency)
|
||
{
|
||
if (_picture == "." || (_picture.len() >= 9 && _picture.find(',') < 0))
|
||
real2currency(q, rrr);
|
||
}
|
||
if (q.empty())
|
||
q = rrr.string(_picture);
|
||
}
|
||
else
|
||
{
|
||
#ifdef __LONGDOUBLE__
|
||
q.format(formato, (long double)rrr);
|
||
#else
|
||
q = rrr.format(formato);
|
||
#endif
|
||
}
|
||
if (rrr.is_zero () && !_print_zero)
|
||
q.fill (' ', q.len());
|
||
}
|
||
break;
|
||
case 'v': // Currency
|
||
{
|
||
const TCurrency& cur = *va_arg(params, TCurrency*);
|
||
if (cur.get_num().is_zero() && !_print_zero)
|
||
q.cut(0);
|
||
else
|
||
q = cur.string(_picture.find('.') >= 0);
|
||
const int width = atoi(formato.mid(1,-1));
|
||
if (width > 0)
|
||
q.right_just(width);
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
if (fill != ' ')
|
||
q = fill_str (q, fill);
|
||
fill = _fillchar;
|
||
_rows.add (new _PrintfTok (_currow, q));
|
||
}
|
||
else
|
||
_rows.add (new _PrintfRef (_currow, formato, ch, va_arg (params, void *)));
|
||
}
|
||
}
|
||
break;
|
||
case '\n': // ignore
|
||
break;
|
||
default:
|
||
// add to string
|
||
strbuf[strind++] = ch;
|
||
if (!ch)
|
||
fmt--;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (strind)
|
||
{
|
||
strbuf[strind] = '\0';
|
||
_rows.add(new _PrintfTok(_currow, strbuf));
|
||
strind = 0;
|
||
}
|
||
va_end (params);
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Setta i valori di traduzione dei campi
|
||
void TPrint_application::set_translation (
|
||
int lognum, // @parm Numero logido del file condenete il campo da tradurre
|
||
const char *field, // @parm Campo di cui effettuare la straduzione
|
||
const char *from, // @parm Valore da tradurre
|
||
const char *to) // @parm Valore che assume il campo
|
||
|
||
// @comm Questa funzione occorre che sia chiamata per ogni traduzione da effettuare.
|
||
// <nl>Esempio: set_translation(12,"STATOCIV","1","Celibe") provoca la stampa
|
||
// automatica di stringhe al posto di determinati valori dei campi se e' dato
|
||
// il codice @t.
|
||
// <nl>Il posto giusto per chiamarla e' nella <mf TPrint_application::user_create>.
|
||
{
|
||
_transtab.add (new _Transfield (lognum, field, from, to));
|
||
}
|
||
|
||
void TPrint_application::print()
|
||
{
|
||
_cancelled = FALSE;
|
||
_print_defined = FALSE;
|
||
|
||
// open printer if needed
|
||
if (!(printer().isopen ()))
|
||
if (!printer().open ())
|
||
return;
|
||
|
||
// only external apps can change it
|
||
_repeat_print = FALSE;
|
||
|
||
|
||
// NULL cursor passed only prints once
|
||
// pre and post process do everything
|
||
|
||
if (_cur == NULL)
|
||
{
|
||
//************************************************
|
||
int cnt = 0;
|
||
bool ok = TRUE;
|
||
do {
|
||
if (preprocess_print (0, cnt))
|
||
{
|
||
int cnt2 = 0;
|
||
do {
|
||
if (preprocess_page (0, cnt2))
|
||
{
|
||
set_page (0, cnt2);
|
||
ok = print_one (0);
|
||
}
|
||
}
|
||
while (ok && postprocess_page (0, cnt2++) == REPEAT_PAGE);
|
||
}
|
||
}
|
||
while (ok && postprocess_print (0, cnt++) == REPEAT_PAGE);
|
||
// *****************************************************
|
||
}
|
||
else
|
||
{
|
||
// cursor exists *********************************************
|
||
(*_cur) = 0l;
|
||
_cur->freeze (TRUE);
|
||
|
||
if (_cur->items () >= _wthr &&
|
||
(_force_progind || printer ().printtype () != screenvis))
|
||
_prind = new TProgind (_cur->items (), TR("Stampa in corso..."), _wcancel, _wbar);
|
||
print_tree (_pr_tree);
|
||
_cur->freeze (FALSE);
|
||
|
||
if (_prind)
|
||
{
|
||
delete _prind;
|
||
_prind = NULL;
|
||
}
|
||
// ****************************************************************
|
||
}
|
||
if (!_repeat_print)
|
||
{
|
||
if (printer().isopen ())
|
||
{
|
||
printer().close();
|
||
printer().resetheader();
|
||
printer().resetfooter();
|
||
}
|
||
postclose_print ();
|
||
}
|
||
else
|
||
printer().formfeed();
|
||
}
|
||
|
||
bool TPrint_application::print_tree (link_item * head)
|
||
{
|
||
bool go = TRUE;
|
||
while (head)
|
||
{
|
||
head->_cnt = 0;
|
||
if (_cur->is_first_match (head->_logicnum))
|
||
{
|
||
do
|
||
{
|
||
if (!preprocess_print (head->_logicnum, head->_cnt))
|
||
break;
|
||
do
|
||
{
|
||
// set print rows according to current file
|
||
if (_force_setpage || _cur_file != head->_logicnum
|
||
|| !_print_defined)
|
||
{
|
||
reset_print ();
|
||
set_page(head->_logicnum, head->_cnt);
|
||
_cur_file = head->_logicnum;
|
||
}
|
||
int cnt2 = 0;
|
||
do
|
||
{
|
||
if (!preprocess_page (head->_logicnum, cnt2))
|
||
break;
|
||
go = print_one (head->_logicnum);
|
||
if (go && head->_son)
|
||
go = print_tree (head->_son);
|
||
}
|
||
while (go && postprocess_page (head->_logicnum, cnt2++) ==
|
||
REPEAT_PAGE);
|
||
}
|
||
while (go && _cur->next_match (head->_logicnum));
|
||
}
|
||
while (go && postprocess_print (head->_logicnum, head->_cnt++) == REPEAT_PAGE);
|
||
}
|
||
if (!go)
|
||
break;
|
||
go = TRUE;
|
||
head = head->_brother;
|
||
}
|
||
return go;
|
||
}
|
||
|
||
void TPrint_application::real2currency(TString& s, const real& r, const char* p) const
|
||
{
|
||
const TFixed_string pic = (p && *p) ? p : (const char *) _picture;
|
||
if (!r.is_zero() || _print_zero)
|
||
{
|
||
TCurrency c(r);
|
||
if (_curr_codval.not_empty())
|
||
c.change_value(_curr_codval);
|
||
const bool dotted = pic.empty() || pic.find('.') >= 0;
|
||
s = c.string(dotted);
|
||
}
|
||
else
|
||
s.cut(0);
|
||
const int len = pic.len();
|
||
if (len >= 9)
|
||
s.right_just(len);
|
||
}
|
||
|
||
HIDDEN void raddoppia_chiocciole(TString& toprint)
|
||
{
|
||
for (int i = toprint.len()-1; i >= 0; i--)
|
||
{
|
||
if (toprint[i] == '@')
|
||
toprint.insert("@", i);
|
||
}
|
||
}
|
||
|
||
// @doc INTERNAL
|
||
|
||
// @mfunc Stampa un singolo record
|
||
//
|
||
// @rdesc Ritorna il risultato dell'operazione:
|
||
//
|
||
// @flag TRUE | Se e' riuscito a stampare il record
|
||
// @flag FALSE | Se la stampa non ha avuto successo
|
||
bool TPrint_application::print_one (
|
||
int file) // @parm Numero logico del file di cui stampare il record
|
||
|
||
// @comm Dopo la stampa del record non viene spostato in avanti il cursore
|
||
{
|
||
int i = 0;
|
||
TPrinter& prn = printer();
|
||
|
||
if ((_prind && _prind->iscancelled()) || prn.frozen())
|
||
if (_cancelled = cancel_hook()) return FALSE;
|
||
|
||
if (!_print_defined)
|
||
return TRUE;
|
||
|
||
if (_prind && file == _pr_tree->_logicnum)
|
||
_prind->addstatus (1);
|
||
|
||
TArray rw(_maxrow + 1);
|
||
int *pos = new int[_maxrow + 1];
|
||
|
||
for (i = 0; i <= _maxrow; i++)
|
||
{
|
||
rw.add(new TPrintrow());
|
||
pos[i] = -1;
|
||
}
|
||
|
||
// printing workhorse
|
||
for (i = 0; i <= _maxrow; i++)
|
||
for (int j = 0; j < _rows.items (); j++)
|
||
{
|
||
_Token* t = (_Token*)&(_rows[j]);
|
||
if (!t) continue; // should not happen
|
||
|
||
if (t->row() == i)
|
||
{
|
||
TString80 pic; // was char pic[36]
|
||
TString16 fn; // was char fn[17]
|
||
int ch, ln, from, to;
|
||
|
||
if (t->tag() == 3)
|
||
{
|
||
_PrintRowToken* r = (_PrintRowToken*)t;
|
||
rw.add(r->printrow(), r->row());
|
||
}
|
||
else if (t->tag () == 1)
|
||
{
|
||
// it's a _FieldTok
|
||
_FieldTok *ft = (_FieldTok *) t;
|
||
TString256 toprint;
|
||
from = to = -1;
|
||
|
||
if (ft->_flags & FONT_FLAG)
|
||
{
|
||
TPrintstyle st = normalstyle;
|
||
switch (ft->_fld[0])
|
||
{
|
||
case 'u':
|
||
st = underlinedstyle;
|
||
break;
|
||
case 'b':
|
||
st = boldstyle;
|
||
break;
|
||
case 'i':
|
||
st = italicstyle;
|
||
break;
|
||
case 'r':
|
||
st = normalstyle;
|
||
break;
|
||
default:
|
||
st = normalstyle;
|
||
break;
|
||
}
|
||
((TPrintrow *)(&rw[ft->row()]))->set_style (st);
|
||
}
|
||
else if (ft->_flags & JUMP_FLAG)
|
||
{
|
||
char ch;
|
||
int p;
|
||
|
||
ch = ft->_fld[0];
|
||
p = atoi (((const char *) ft->_fld) + 2);
|
||
if (ch == 'g')
|
||
// go to
|
||
pos[ft->row ()] = p;
|
||
else
|
||
// jump ahead
|
||
pos[ft->row ()] =
|
||
((TPrintrow *) (&rw[ft->row ()]))->lastpos () + p;
|
||
}
|
||
else
|
||
{
|
||
if (ft->_fld[0] == 'p')
|
||
{
|
||
// picture
|
||
TToken_string ttt (ft->_fld, '|');
|
||
ch = (ttt.get ())[0];
|
||
ln = atoi ((const char *) ttt.get ());
|
||
fn = ttt.get();
|
||
pic = ttt.get();
|
||
}
|
||
else
|
||
{
|
||
TToken_string ttt (ft->_fld, '|');
|
||
ch = (ttt.get ())[0];
|
||
ln = ttt.get_int();
|
||
fn = ttt.get();
|
||
from = ttt.get_int();
|
||
to = ttt.get_int();
|
||
}
|
||
// get field val
|
||
TLocalisamfile &f = _cur->file(ln);
|
||
if (ft->_flags & TRANS_FLAG)
|
||
{
|
||
_Transfield *tr = NULL;
|
||
// look up field value in translation table
|
||
int i;
|
||
for (i = 0; i < _transtab.items (); i++)
|
||
{
|
||
tr = (_Transfield *) & _transtab[i];
|
||
if (tr->_fn == fn && tr->_lognum == ln)
|
||
{
|
||
// check value
|
||
if (tr->_from == f.get(fn).sub(from<0 ? 0 : from,to))
|
||
break;
|
||
}
|
||
}
|
||
if (i == _transtab.items())
|
||
toprint = "";
|
||
else
|
||
toprint = tr->_to;
|
||
}
|
||
else if (ft->_flags & DATE_FLAG)
|
||
{
|
||
const TDate d(f.get(fn));
|
||
toprint = d.string (ft->_flags & LONG_FLAG ? full : brief);
|
||
if (toprint.empty ())
|
||
{
|
||
toprint = (ft->_flags & LONG_FLAG ? " - - " : " - - ");
|
||
}
|
||
}
|
||
else if (ft->_flags & BOOLEAN_FLAG)
|
||
{
|
||
toprint = f.get(fn) == "X" ? TR("Si") : TR("No");
|
||
}
|
||
else if (ft->_flags & NUMBER_FLAG)
|
||
{
|
||
TString80 pict;
|
||
real r(f.get(fn));
|
||
|
||
bool isreal = f.curr ().type (fn) == _realfld;
|
||
|
||
if (ft->_flags & PICTURE_FLAG)
|
||
pict = pic;
|
||
else if (!(ft->_flags & DEC_FLAG) && *_picture && isreal)
|
||
pict = _picture;
|
||
|
||
if (pict.len () > 0)
|
||
toprint = r.string (pict);
|
||
else if (ft->_flags & DEC_FLAG)
|
||
toprint = r.string (ft->_size, ft->_dec);
|
||
else
|
||
toprint = r.string ();
|
||
|
||
if (r.is_zero () && !_print_zero)
|
||
toprint.fill (' ', toprint.len());
|
||
}
|
||
else if (ft->_flags & STRING_FLAG)
|
||
{
|
||
toprint = f.curr().get (fn);
|
||
// perform string extraction
|
||
if (from != -1)
|
||
toprint = toprint.sub (from, to);
|
||
else if (to != -1)
|
||
toprint = toprint.left (to);
|
||
if (toprint.find('@') >= 0)
|
||
raddoppia_chiocciole(toprint);
|
||
}
|
||
else if (ft->_flags & VALUTA_FLAG)
|
||
{
|
||
const real n(f.get(fn));
|
||
real2currency(toprint, n);
|
||
}
|
||
}
|
||
// adjust size and set fill char
|
||
if (ft->_flags & PAD_FLAG)
|
||
{
|
||
if (!(ft->_flags & NUMBER_FLAG))
|
||
{
|
||
if (ft->_size < toprint.len ())
|
||
toprint.cut (ft->_size);
|
||
else
|
||
toprint.left_just (ft->_size);
|
||
}
|
||
if (ft->_flags & ALIGN_FLAG)
|
||
{
|
||
if (ft->_align == 'r')
|
||
toprint.right_just (ft->_size);
|
||
else if (ft->_align == 'c')
|
||
toprint.center_just (ft->_size);
|
||
else if (ft->_align == 'l')
|
||
toprint.left_just (ft->_size);
|
||
}
|
||
}
|
||
if (_fillchar != ' ' && !(ft->_flags & IGNORE_FILL))
|
||
toprint = fill_str (toprint, _fillchar);
|
||
// add to print row
|
||
((TPrintrow *)(&rw[ft->row()]))->put (toprint, pos[ft->row ()]);
|
||
|
||
if (pos[ft->row()] != -1)
|
||
pos[ft->row ()] += toprint.len ();
|
||
}
|
||
else if (t->tag () == 0)
|
||
{
|
||
// it's a _PrintfTok
|
||
_PrintfTok *pt = (_PrintfTok *) t;
|
||
TString v = pt->_val;
|
||
((TPrintrow *) (&rw[pt->row ()]))->put (v, pos[pt->row ()]);
|
||
if (pos[pt->row ()] != -1)
|
||
{
|
||
pos[pt->row ()] += v.len ();
|
||
const char* s = v;
|
||
while (*s && strncmp(s, "$[", 2) == 0)
|
||
{
|
||
while (*s && *s != ']')
|
||
{
|
||
pos[pt->row()]--;
|
||
s++;
|
||
}
|
||
if (*s)
|
||
pos[pt->row()]--;
|
||
while (*s && *s != '$') s++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
if (t->tag () == 2)
|
||
{
|
||
// printf by reference
|
||
_PrintfRef *pr = (_PrintfRef *) t;
|
||
TString ps;
|
||
TParagraph_string * para_str = NULL;
|
||
bool islong = (pr->_fmt).find ('l') != -1;
|
||
switch (pr->_type)
|
||
{
|
||
case 'd':
|
||
case 'i':
|
||
case 'u':
|
||
case 'o':
|
||
case 'x':
|
||
case 'X':
|
||
ps.format (pr->_fmt, islong ? *((long *) (pr->_what)) :
|
||
*((int *) (pr->_what)));
|
||
break;
|
||
case 'f':
|
||
case 'e':
|
||
ps.format (pr->_fmt, islong ? *((double *) (pr->_what)) :
|
||
*((float *) (pr->_what)));
|
||
break;
|
||
case 'c':
|
||
ps.format (pr->_fmt, *((char *) (pr->_what)));
|
||
break;
|
||
case 's':
|
||
ps.format (pr->_fmt, (char *) (pr->_what));
|
||
break;
|
||
case 't':
|
||
ps.format (pr->_fmt, (const char *)
|
||
(*((TString *) (pr->_what))));
|
||
break;
|
||
case 'a':
|
||
{
|
||
para_str = ((TParagraph_string *) (pr->_what));
|
||
const char * s = para_str->get();
|
||
|
||
if (s != NULL)
|
||
ps.format (pr->_fmt, s);
|
||
break;
|
||
}
|
||
case 'r':
|
||
{
|
||
const real& rrr = *(real*)pr->_what;
|
||
const char* fff = pr->_fmt;
|
||
if (*_picture && (strlen(fff) == 2 || strcmp(fff, "%Lf") == 0))
|
||
{
|
||
if (_magic_currency && _picture == "." ||
|
||
(_picture.len() >= 9 && _picture.find(',') < 0))
|
||
real2currency(ps, rrr);
|
||
else
|
||
ps = rrr.string(_picture);
|
||
}
|
||
else
|
||
{
|
||
#ifdef __LONGDOUBLE__
|
||
ps.format(fff, (long double)rrr);
|
||
#else
|
||
ps = rrr.format(fff);
|
||
#endif
|
||
}
|
||
if (rrr.is_zero () && !_print_zero)
|
||
ps.fill (' ', ps.len());
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
ps = fill_str (ps, _fillchar);
|
||
((TPrintrow *) (&rw[pr->row ()]))->put (ps, pos[pr->row ()]);
|
||
if (para_str != NULL)
|
||
{
|
||
const char * s = para_str->get();
|
||
int row = pr->row();
|
||
TPrintstyle xstyle = ((TPrintrow *)(&rw[row]))->get_style();
|
||
|
||
while (s != NULL)
|
||
{
|
||
ps.format (pr->_fmt, s);
|
||
ps = fill_str (ps, _fillchar);
|
||
row++;
|
||
if (rw.objptr(row) == NULL)
|
||
rw.add(new TPrintrow ());
|
||
((TPrintrow *) (&rw[row]))->set_style(xstyle);
|
||
((TPrintrow *) (&rw[row]))->put(ps, pos[pr->row()]);
|
||
s = para_str->get();
|
||
}
|
||
((TPrintrow *) (&rw[row]))->set_style(normalstyle);
|
||
}
|
||
if (pos[pr->row ()] != -1)
|
||
pos[pr->row ()] += ps.len ();
|
||
}
|
||
}
|
||
}
|
||
|
||
// print!
|
||
const int last = rw.last();
|
||
|
||
for (i = 0; i <= /*_maxrow*/ last; i++)
|
||
{
|
||
TPrintrow *pr = (TPrintrow *) & rw[i];
|
||
if (!(prn.print(*pr)))
|
||
break;
|
||
}
|
||
|
||
//callback che segnala la fine della stampa fisica di una riga (da lui chiamata "page")
|
||
on_page_printed(file);
|
||
|
||
if (_auto_ff && prn.rows_left() > 0)
|
||
printer().formfeed ();
|
||
delete pos;
|
||
|
||
// TRUE if all rows have been printed
|
||
// if stopped by preprocess_page returns ok
|
||
return i == last /*_maxrow */ + 1;
|
||
}
|
||
|
||
bool TPrint_application::menu(MENU_TAG m)
|
||
{
|
||
// funziona da se' fino a 20 voci della menubar
|
||
if (m >= BAR_ITEM_ID(1) && m <= BAR_ITEM_ID(20))
|
||
{
|
||
_last_choice = m;
|
||
do_print((m - BAR_ITEM_ID(0)) / 100);
|
||
}
|
||
|
||
// Se non esistono altre voci di menu termina l'applicazione
|
||
return xvtil_test_menu_tag (BAR_ITEM_ID(2));
|
||
}
|
||
|
||
bool TPrint_application::create()
|
||
{
|
||
TApplication::create();
|
||
printer().setfooterhandler (_pp_footer);
|
||
printer().setheaderhandler (_pp_header);
|
||
printer().setlinkhandler (_pp_link);
|
||
if (user_create())
|
||
{
|
||
dispatch_e_menu (_last_choice);
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
bool TPrint_application::destroy ()
|
||
{
|
||
user_destroy();
|
||
reset_files();
|
||
_cursors.destroy();
|
||
return TApplication::destroy ();
|
||
}
|
||
|
||
void TPrint_application::do_print(int n)
|
||
{
|
||
while (set_print(n))
|
||
{
|
||
do { print(); } while(_repeat_print);
|
||
enable_print_menu();
|
||
}
|
||
}
|
||
|
||
void TPrint_application::enable_print_menu()
|
||
{
|
||
enable_menu_item(M_FILE_PREVIEW, TRUE);
|
||
enable_menu_item(M_FILE_PRINT, TRUE);
|
||
}
|
||
|
||
void TPrint_application::disable_print_menu()
|
||
{
|
||
enable_menu_item(M_FILE_PREVIEW, FALSE);
|
||
enable_menu_item(M_FILE_PRINT, FALSE);
|
||
}
|
||
|
||
void TPrint_application::enable_setprint_menu()
|
||
{
|
||
enable_menu_item(BAR_ITEM_ID(1), TRUE);
|
||
}
|
||
|
||
void TPrint_application::disable_setprint_menu()
|
||
{
|
||
enable_menu_item (BAR_ITEM_ID(1), FALSE);
|
||
}
|
||
|
||
TPrint_application::TPrint_application ():TApplication (), _rows (100),
|
||
_cursors (10), _transtab (10), _header (10),
|
||
_footer (10)
|
||
{
|
||
_cur = NULL;
|
||
_repeat_print = FALSE;
|
||
_currow = _maxrow = 0;
|
||
_auto_ff = FALSE;
|
||
_wbar = _wcancel = TRUE;
|
||
_wthr = 5;
|
||
_fillchar = ' ';
|
||
_pr_tree = NULL;
|
||
_print_defined = FALSE;
|
||
_force_progind = FALSE;
|
||
_force_setpage = FALSE;
|
||
_magic_currency = FALSE;
|
||
_prind = NULL;
|
||
_cur_file = 0;
|
||
_magic_currency = FALSE;
|
||
_print_zero = FALSE;
|
||
|
||
_last_choice = BAR_ITEM_ID(1);
|
||
}
|
||
|
||
void TPrint_application::reset_files()
|
||
{
|
||
if (_pr_tree != NULL)
|
||
{
|
||
_reset_tree(_pr_tree);
|
||
_pr_tree = NULL;
|
||
}
|
||
}
|
||
|
||
|
||
TPrint_application::~TPrint_application ()
|
||
{}
|