1151 lines
26 KiB
C++
Executable File
1151 lines
26 KiB
C++
Executable File
// $Id: printapp.cpp,v 1.1.1.1 1994-08-12 10:51:57 alex Exp $
|
|
#include <ctype.h>
|
|
#include <stdarg.h>
|
|
|
|
#include <gm.h>
|
|
|
|
#include <progind.h>
|
|
#include <utility.h>
|
|
#include <tabutil.h>
|
|
#include <printapp.h>
|
|
#include <urldefid.h>
|
|
|
|
TLocalisamfile* fff;
|
|
|
|
const char* printf_types = "dDiIuUoOxXfeEgGcCnNsSpPrRtT";
|
|
|
|
// _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;
|
|
|
|
// =============================================================
|
|
// print token containers
|
|
// =============================================================
|
|
|
|
class _Transfield : public TObject
|
|
{
|
|
friend class TPrint_application;
|
|
TString _from, // "from" value
|
|
_to, // "to" value
|
|
_fn; // field name
|
|
int _lognum; // logical number
|
|
public:
|
|
_Transfield(int l, const char* fn, const char* from, const char* to) :
|
|
_from(3), _to(20), _fn(10)
|
|
{ _lognum = l; _from = from; _to = to; _fn = fn; }
|
|
};
|
|
|
|
class _Token: public TObject
|
|
{
|
|
friend class TPrint_application;
|
|
int _tag;
|
|
int _row;
|
|
public:
|
|
int tag() { return _tag; }
|
|
int row() { 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(0)
|
|
{ tag(0); row(rw); _val = val; }
|
|
virtual ~_PrintfTok() {}
|
|
};
|
|
|
|
class _FieldTok : public _Token
|
|
// something more complex to be printed
|
|
{
|
|
friend class TPrint_application;
|
|
int _size, _dec;
|
|
char _align;
|
|
TString _fld; // field description
|
|
word _flags; // all you need to know
|
|
public:
|
|
_FieldTok(int rw, char* fld, word flags, char align = 'l',
|
|
int size = -1, int dec = -1) :
|
|
_fld(20)
|
|
{
|
|
tag(1); row(rw); _fld = (const char*)fld; _flags = flags;
|
|
_size = size, _align = align; _dec = dec; delete fld;
|
|
}
|
|
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() {}
|
|
};
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
link_item* TPrint_application::_look_print_node(link_item* head, int logicnum)
|
|
{
|
|
// look for <from> node to attach to
|
|
// since it reflects a relation, it won't have more than
|
|
// one node for the same file/alias, so it stops at first match
|
|
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;
|
|
}
|
|
|
|
void TPrint_application::add_file(const char* tab, int from)
|
|
{
|
|
add_file(TTable::name2log(tab),from);
|
|
}
|
|
|
|
void TPrint_application::add_file(int file, int from)
|
|
{
|
|
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 ------------------------------------
|
|
|
|
static char tb[120];
|
|
|
|
int TPrint_application::enable_link (const char* descr, char fg, char bg)
|
|
{
|
|
TToken_string* tt = new TToken_string(30);
|
|
char b[2]; b[1] = '\0';
|
|
tt->add(descr); b[0] = fg; tt->add(b); b[0] = bg; tt->add(b);
|
|
printer().links().add(tt);
|
|
return printer().links().items() - 1;
|
|
}
|
|
|
|
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];
|
|
char f = *(t.get(1)); char b = *(t.get(2));
|
|
if (f == fg && b == bg)
|
|
{
|
|
printer().links().add(NULL,i);
|
|
printer().links().pack();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TPrint_application::set_multiple_link(bool on)
|
|
{
|
|
printer().setmultiplelink(on);
|
|
}
|
|
|
|
|
|
void TPrint_application::_pp_link(int id, const char* text)
|
|
{
|
|
TPrint_application* prapp = (TPrint_application*)MainApp();
|
|
prapp->process_link(id, text);
|
|
}
|
|
|
|
void TPrint_application::_pp_header(TPrinter&)
|
|
{
|
|
TPrint_application* prapp = (TPrint_application*)MainApp();
|
|
|
|
prapp->preprocess_header();
|
|
|
|
prapp->printer().resetheader();
|
|
int ii = (prapp->_header).last();
|
|
// reset and add header/footer lines
|
|
for (int i = 0; i <= ii; i++)
|
|
if ((prapp->_header).objptr(i) != NULL)
|
|
prapp->printer().setheaderline(i,
|
|
new TPrintrow((TPrintrow&)(prapp->_header)[i]));
|
|
}
|
|
|
|
|
|
void TPrint_application::_pp_footer(TPrinter&)
|
|
{
|
|
TPrint_application* prapp = (TPrint_application*)MainApp();
|
|
|
|
prapp->preprocess_footer();
|
|
prapp->printer().resetfooter();
|
|
int ii = (prapp->_footer).last();
|
|
for (int i = 0; i <= ii; i++)
|
|
if ((prapp->_footer).objptr(i) != NULL)
|
|
prapp->printer().setfooterline(i,
|
|
new TPrintrow((TPrintrow&)(prapp->_footer)[i]));
|
|
}
|
|
|
|
|
|
void TPrint_application::set_background(const char* bgdesc)
|
|
{
|
|
printer().setbackground(bgdesc);
|
|
}
|
|
|
|
|
|
|
|
const char* FLD(int lognum, const char* f, int from, int to)
|
|
{
|
|
sprintf(tb, "%c|%d|%s|%d|%d", 'n', lognum, f, from, to);
|
|
char* p = new char[strlen(tb)+1];
|
|
strcpy(p,tb);
|
|
return p;
|
|
}
|
|
|
|
const char* FLD(int lognum, const char* f, const char* picture)
|
|
{
|
|
sprintf(tb, "%c|%d|%s|%s", 'p', lognum, f, picture);
|
|
char* p = new char[strlen(tb)+1];
|
|
strcpy(p,tb);
|
|
return p;
|
|
}
|
|
|
|
const char* FLD(const char* tabname, const char* f, int from, int to)
|
|
{
|
|
CHECKS(strlen(tabname) < 5, "Invalid table name", tabname);
|
|
int lognum = TTable::name2log(tabname);
|
|
sprintf(tb, "%c|%d|%s|%d|%d", 'n', lognum, f, from, to);
|
|
char* p = new char[strlen(tb)+1];
|
|
strcpy(p,tb);
|
|
return p;
|
|
}
|
|
|
|
|
|
const char* FLD(const char* tabname, const char* f, const char* picture)
|
|
{
|
|
CHECKS(strlen(tabname) < 5, "Invalid table name", tabname);
|
|
int lognum = TTable::name2log(tabname);
|
|
sprintf(tb, "%c|%d|%s|%s", 'p', lognum, f, picture);
|
|
char* p = new char[strlen(tb)+1];
|
|
strcpy(p,tb);
|
|
return p;
|
|
}
|
|
|
|
|
|
TString& fill_str(TString& t, char f)
|
|
{
|
|
for (int kk = t.len() - 1; kk >= 0; kk--)
|
|
{ if (t[kk] == ' ') t[kk] = f; else break; }
|
|
for (kk = 0; kk < t.len(); kk++)
|
|
{ if (t[kk] == ' ') t[kk] = f; else break; }
|
|
return t;
|
|
}
|
|
|
|
// ========================================================
|
|
// Printapp code at last
|
|
// ========================================================
|
|
|
|
//void TPrint_application::enable_link(const char* descr, char fg, char bg)
|
|
//{
|
|
// printer().setlinkdescr(descr);
|
|
//}
|
|
|
|
void TPrint_application::select_cursor(int c)
|
|
{
|
|
if (c == -1) _cur = NULL;
|
|
else _cur = (TCursor*) &_cursors[c];
|
|
}
|
|
|
|
TCursor* TPrint_application::get_cursor(int c)
|
|
{
|
|
if (c == -1) return NULL;
|
|
else return (TCursor*) &_cursors[c];
|
|
}
|
|
|
|
int TPrint_application::add_cursor(TCursor* c)
|
|
{
|
|
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;
|
|
}
|
|
|
|
void TPrint_application::set_header(int r, const char* fmt, ...)
|
|
{
|
|
CHECK(r >= 1, "Header rows start at 1");
|
|
va_list vl;
|
|
va_start(vl, fmt);
|
|
vsprintf(__tmp_string, 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_string);
|
|
}
|
|
|
|
void TPrint_application::set_footer(int r, const char* fmt, ...)
|
|
{
|
|
CHECK(r >= 1, "Footer rows start at 1");
|
|
va_list vl;
|
|
va_start(vl, fmt);
|
|
vsprintf(__tmp_string, 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_string);
|
|
}
|
|
|
|
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::set_row(int r, const char* frmt, ...)
|
|
{
|
|
CHECK(r >= 1, "Print rows start at 1");
|
|
|
|
r--;
|
|
|
|
char digbuf[10];
|
|
char strbuf[120];
|
|
char fftt[120];
|
|
char* fmt = fftt;
|
|
char fill = _fillchar;
|
|
|
|
word flags = 0;
|
|
int size = 0, dec = 0, strind = 0;
|
|
char ch, align = 'l';
|
|
|
|
// let the poor programmer use format() at will
|
|
strcpy(fmt,frmt);
|
|
_print_defined = TRUE;
|
|
|
|
_currow = r;
|
|
if (_currow > _maxrow) _maxrow = _currow;
|
|
|
|
va_list params;
|
|
va_start(params,frmt);
|
|
|
|
// parse format string
|
|
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;
|
|
// ch = *fmt++;
|
|
}
|
|
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* xxxx = new char[2];
|
|
xxxx[0] = ch;
|
|
xxxx[1] = '\0';
|
|
_rows.add(new _FieldTok(_currow,xxxx, FONT_FLAG));
|
|
}
|
|
break;
|
|
case 'g':
|
|
case 'j':
|
|
{
|
|
const char* xxx = format("%c %d", ch, size);
|
|
char* xxxx = new char[strlen(xxx)+1];
|
|
strcpy(xxxx,xxx);
|
|
_rows.add(new _FieldTok(_currow, xxxx, JUMP_FLAG));
|
|
}
|
|
break;
|
|
case 'T':
|
|
flags |= IGNORE_FILL;
|
|
case 't':
|
|
flags |= TRANS_FLAG;
|
|
break;
|
|
case 'D':
|
|
flags |= IGNORE_FILL;
|
|
case 'd':
|
|
flags |= DATE_FLAG;
|
|
break;
|
|
case 'F':
|
|
flags |= IGNORE_FILL;
|
|
case 'f':
|
|
flags |= BOOLEAN_FLAG;
|
|
break;
|
|
case 'S':
|
|
flags |= IGNORE_FILL;
|
|
case 's':
|
|
flags |= STRING_FLAG;
|
|
break;
|
|
case 'C':
|
|
flags |= IGNORE_FILL;
|
|
case 'c':
|
|
flags |= RECNO_FLAG;
|
|
break;
|
|
case 'N':
|
|
flags |= IGNORE_FILL;
|
|
case 'n':
|
|
flags |= NUMBER_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)
|
|
{
|
|
char* xxx = va_arg(params, char*);
|
|
_rows.add(new _FieldTok(_currow, xxx,
|
|
flags, align, size, dec));
|
|
}
|
|
flags = 0x0000;
|
|
align = 'l';
|
|
}
|
|
else
|
|
{
|
|
TString t;
|
|
switch (ch)
|
|
{
|
|
case '#':
|
|
case '%':
|
|
{
|
|
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
|
|
t << ccc; bool islong = FALSE;
|
|
while (strchr(printf_types,ch) == NULL)
|
|
{
|
|
t << ch;
|
|
if (ch == 'l') islong = TRUE;
|
|
ch = *fmt++;
|
|
if (ch == '\0')
|
|
fatal_box("sorry, zer's samzing vruong"
|
|
" uitz ioar format.");
|
|
}
|
|
if (isupper(ch)) { ch = tolower(ch); fill = ' '; }
|
|
if (ch == 't') t << 's';
|
|
else if (ch == 'r') t << 't';
|
|
else t << ch;
|
|
if (ccc == '%')
|
|
{
|
|
TString q(60);
|
|
switch (ch)
|
|
{
|
|
case 'd':
|
|
case 'i':
|
|
case 'u':
|
|
case 'o':
|
|
case 'x':
|
|
case 'X':
|
|
q.format(t,islong?va_arg(params,int):
|
|
va_arg(params,long));
|
|
break;
|
|
case 'f':
|
|
case 'e':
|
|
case 'E':
|
|
case 'G':
|
|
q.format(t, islong ? va_arg(params,float) :
|
|
va_arg(params,double));
|
|
break;
|
|
case 'c':
|
|
q.format(t, va_arg(params,char));
|
|
break;
|
|
case 's':
|
|
q.format(t, va_arg(params,char*));
|
|
break;
|
|
case 't': // TString
|
|
q.format(t, (const char*)
|
|
(TString)*((va_arg(params,TString*))));
|
|
break;
|
|
case 'r': // Real
|
|
{
|
|
real* rrr = va_arg(params,real*);
|
|
if (t.len() == 2 && *_picture)
|
|
{
|
|
// no format specifications
|
|
// use default picture
|
|
q = rrr->string(_picture);
|
|
}
|
|
else
|
|
{
|
|
char* fff = (char*)((const char*)t);
|
|
// dsprintf(__tmp_string, fff, (DEC*)(*rrr));
|
|
dsprintf(__tmp_string, fff, rrr->ptr());
|
|
q = __tmp_string;
|
|
}
|
|
if (rrr->is_zero() && !_print_zero)
|
|
q.fill(' ');
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (fill != ' ') q = fill_str(q,fill);
|
|
fill = _fillchar;
|
|
_rows.add(new _PrintfTok(_currow, q));
|
|
}
|
|
else
|
|
_rows.add(new _PrintfRef(_currow, t, 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);
|
|
}
|
|
|
|
void TPrint_application::set_translation(int lognum, const char* field,
|
|
const char* from, const char* to)
|
|
{
|
|
_transtab.add(new _Transfield(lognum,field,from,to));
|
|
}
|
|
|
|
void TPrint_application::print()
|
|
{
|
|
// open printer if needed
|
|
if (!(printer().isopen()))
|
|
if (!printer().open())
|
|
return;
|
|
|
|
// 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(),
|
|
(char*)(const char*)_wmess,
|
|
_wcancel, _wbar, 35);
|
|
print_tree(_pr_tree);
|
|
_cur->freeze(FALSE);
|
|
|
|
if (_prind)
|
|
{
|
|
delete _prind;;
|
|
_prind = NULL;
|
|
}
|
|
}
|
|
if (printer().isopen())
|
|
{
|
|
printer().close();
|
|
printer().resetheader();
|
|
printer().resetfooter();
|
|
}
|
|
postclose_print();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
bool TPrint_application::print_one(int file)
|
|
{
|
|
int i =0;
|
|
|
|
if (_prind && _prind->iscancelled())
|
|
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)
|
|
{
|
|
char pic[36], fn[17];
|
|
int ch, ln, from, to;
|
|
|
|
if (t->tag() == 1)
|
|
{
|
|
// it's a _FieldTok
|
|
_FieldTok* ft = (_FieldTok*)t;
|
|
TString toprint;
|
|
from = to = -1;
|
|
|
|
if (ft->_flags & FONT_FLAG)
|
|
{
|
|
TPrintstyle st = normalstyle;
|
|
switch(((const char*)(ft->_fld))[0])
|
|
{
|
|
case 'u':
|
|
st = underlinedstyle;
|
|
break;
|
|
case 'b':
|
|
st = boldstyle;
|
|
break;
|
|
case 'i':
|
|
st = italicstyle;
|
|
break;
|
|
case 'r':
|
|
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 ((*(const char*)(ft->_fld)) == 'p')
|
|
{
|
|
// picture
|
|
TToken_string ttt(ft->_fld,'|');
|
|
ch = (ttt.get())[0];
|
|
ln = atoi((const char *)ttt.get());
|
|
strcpy(fn,(const char*)ttt.get());
|
|
strcpy(pic,(const char*)ttt.get());
|
|
}
|
|
else
|
|
{
|
|
TToken_string ttt(ft->_fld,'|');
|
|
ch = (ttt.get())[0];
|
|
ln = atoi((const char *)ttt.get());
|
|
strcpy(fn,(const char*)ttt.get());
|
|
from = atoi((const char *)ttt.get());
|
|
to = atoi((const char *)ttt.get());
|
|
}
|
|
// get field val
|
|
TLocalisamfile* f = _cur->file(ln);
|
|
if (ft->_flags & TRANS_FLAG)
|
|
{
|
|
_Transfield* tr = NULL;
|
|
// look up field value in translation table
|
|
for (int 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))
|
|
break;
|
|
}
|
|
}
|
|
if (i == _transtab.items())
|
|
toprint = "";
|
|
else toprint = tr->_to;
|
|
}
|
|
else if (ft->_flags & DATE_FLAG)
|
|
{
|
|
TDate d = (f->curr()).get_date(fn);
|
|
toprint = d.string(ft->_flags & LONG_FLAG ? 4 : 2);
|
|
if (toprint.empty())
|
|
{
|
|
toprint = (ft->_flags & LONG_FLAG ?
|
|
" - - " :
|
|
" - - ");
|
|
}
|
|
}
|
|
else if (ft->_flags & BOOLEAN_FLAG)
|
|
{
|
|
toprint = (f->curr()).get(fn) == "X" ? "Si":"No";
|
|
}
|
|
else if (ft->_flags & NUMBER_FLAG)
|
|
{
|
|
TString pict(0);
|
|
real r = f->curr().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(' ');
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
// 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(toprint.len());
|
|
else if (ft->_align == 'c')
|
|
toprint.center_just(toprint.len());
|
|
else if (ft->_align == 'l')
|
|
toprint.left_just(toprint.len());
|
|
}
|
|
}
|
|
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();
|
|
}
|
|
else if (t->tag() == 2)
|
|
{
|
|
// printf by reference
|
|
_PrintfRef* pr = (_PrintfRef*)t;
|
|
TString ps;
|
|
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 ? *((int*)(pr->_what)) :
|
|
*((long*)(pr->_what)));
|
|
break;
|
|
case 'f':
|
|
case 'e':
|
|
ps.format(pr->_fmt, islong ? *((float*)(pr->_what)) :
|
|
*((double*)(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 'r':
|
|
{
|
|
real* rrr = (real*)pr->_what;
|
|
if (pr->_fmt.len() == 2 && *_picture)
|
|
{
|
|
strcpy(__tmp_string, rrr->string(_picture));
|
|
}
|
|
else
|
|
{
|
|
char* fff = (char*)((const char*)pr->_fmt);
|
|
dsprintf(__tmp_string, fff,
|
|
// (DEC*)*((real*)(pr->_what)));
|
|
((real*)pr->_what)->ptr());
|
|
}
|
|
ps = __tmp_string;
|
|
if (rrr->is_zero() && !_print_zero)
|
|
ps.fill(' ');
|
|
break;
|
|
}
|
|
}
|
|
|
|
ps = fill_str(ps,_fillchar);
|
|
((TPrintrow*)(&rw[pr->row()]))->
|
|
put(ps,pos[pr->row()]);
|
|
if (pos[pr->row()] != -1)
|
|
pos[pr->row()] += ps.len();
|
|
}
|
|
}
|
|
}
|
|
|
|
// print!
|
|
for (i = 0; i <= _maxrow; i++)
|
|
{
|
|
TPrintrow* pr = (TPrintrow*)&rw[i];
|
|
if (!(printer().print(*pr)))
|
|
break;
|
|
}
|
|
if (_auto_ff && _maxrow < printer().formlen())
|
|
printer().formfeed();
|
|
delete pos;
|
|
|
|
// TRUE if all rows have been printed
|
|
// if stopped by preprocess_page returns ok
|
|
return i == _maxrow+1;
|
|
}
|
|
|
|
bool TPrint_application::menu(MENU_TAG m)
|
|
{
|
|
// funziona da se' fino a 20 voci della menubar
|
|
if (m >= BAR_ITEM(1) && m <= BAR_ITEM(20))
|
|
{
|
|
_last_choice = m;
|
|
do_print((m - BAR_ITEM(0))/100);
|
|
}
|
|
|
|
// Se non esistono altre voci di menu termina l'applicazione
|
|
return !xvt_test_menu_tag(BAR_ITEM(2));
|
|
}
|
|
|
|
bool TPrint_application::create()
|
|
{
|
|
TApplication::create();
|
|
printer().setfooterhandler(_pp_footer);
|
|
printer().setheaderhandler(_pp_header);
|
|
printer().setlinkhandler(_pp_link);
|
|
user_create();
|
|
dispatch_e_menu(_last_choice);
|
|
return TRUE;
|
|
}
|
|
|
|
bool TPrint_application::destroy()
|
|
{
|
|
user_destroy();
|
|
TApplication::destroy();
|
|
return TRUE;
|
|
}
|
|
|
|
void TPrint_application::do_print(int n)
|
|
{
|
|
while (set_print(n))
|
|
{
|
|
print();
|
|
enable_print_menu();
|
|
}
|
|
}
|
|
|
|
void TPrint_application::enable_print_menu()
|
|
{
|
|
enable_menu_item(M_FILE_PRINT,TRUE);
|
|
}
|
|
|
|
void TPrint_application::disable_print_menu()
|
|
{
|
|
enable_menu_item(M_FILE_PRINT,FALSE);
|
|
}
|
|
|
|
void TPrint_application::enable_setprint_menu()
|
|
{
|
|
enable_menu_item(BAR_ITEM(1),TRUE);
|
|
}
|
|
|
|
void TPrint_application::disable_setprint_menu()
|
|
{
|
|
enable_menu_item(BAR_ITEM(1),FALSE);
|
|
}
|
|
|
|
TPrint_application::TPrint_application() : TApplication(), _transtab(10),
|
|
_cursors(10), _header(10),
|
|
_footer(10), _rows(100)
|
|
{
|
|
_cur = NULL;
|
|
_currow = _maxrow = 0;
|
|
_auto_ff = FALSE;
|
|
_wbar = _wcancel = TRUE;
|
|
_wmess = "Stampa in corso\nPrego attendere";
|
|
_wthr = 5;
|
|
_confpr = "printer.ini";
|
|
_fillchar = ' ';
|
|
_pr_tree = NULL;
|
|
_print_defined = FALSE;
|
|
_force_progind = FALSE;
|
|
_force_setpage = FALSE;
|
|
_prind = NULL;
|
|
_cur_file = 0;
|
|
_picture = "";
|
|
_print_zero = FALSE;
|
|
_last_choice = BAR_ITEM(1);
|
|
}
|
|
|
|
|
|
TPrint_application::~TPrint_application()
|
|
{
|
|
reset_files();
|
|
}
|