55a36762ef
checks.cpp Tolto include windows.h colors.cpp Tolto include windows.h controls.cpp Aggiunto cambiamento del font runtime dei TText_control execp.cpp Tolto include windows.h form.cpp Tolto include windows.h mask.cpp Corretta formattazione di due righe maskfld.cpp Aggiunto messaggio CHECK msksheet.cpp Tolto include windows.h relapp.cpp Tolto include windows.h strings.pp Corretto CHECK della TFixed_string::format() viswin.cpp Tolto include windows.h window.cpp Tolto include windows.h xvtility.cpp Corretto calcolo altezza righe delle maschere git-svn-id: svn://10.65.10.50/trunk@4085 c028cbd2-c16b-5b4b-a496-9718f37d4682
4385 lines
111 KiB
C++
Executable File
4385 lines
111 KiB
C++
Executable File
#include <ctype.h>
|
||
#include <stdlib.h>
|
||
|
||
#define STRICT
|
||
#define XVT_INCL_NATIVE
|
||
|
||
#include <applicat.h>
|
||
#include <form.h>
|
||
#include <msksheet.h>
|
||
#include <printer.h>
|
||
#include <relation.h>
|
||
#include <sheet.h>
|
||
#include <utility.h>
|
||
#include <spool.h>
|
||
|
||
#ifndef __DEFMASK_H
|
||
#include <defmask.h>
|
||
#endif
|
||
|
||
#include "../ba/bafrm.h"
|
||
|
||
// per lo sheet di edit campi
|
||
HIDDEN const int idt_id = 101;
|
||
HIDDEN const int dsc_id = 102;
|
||
HIDDEN const int prn_id = 103;
|
||
HIDDEN const int yps_id = 104;
|
||
HIDDEN const int xps_id = 105;
|
||
HIDDEN const int len_id = 106;
|
||
HIDDEN const int col_id = 107;
|
||
HIDDEN const int int_id = 108;
|
||
HIDDEN const int spc_id = 109;
|
||
HIDDEN const int fnl_id = 110;
|
||
HIDDEN const int fnr_id = 111;
|
||
HIDDEN const int typ_id = 112;
|
||
HIDDEN const int frm_id = 113;
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Utility functions
|
||
///////////////////////////////////////////////////////////
|
||
|
||
|
||
// Current form (edit, print)
|
||
HIDDEN TForm* _cur_form = NULL;
|
||
HIDDEN TPrint_section* _cur_sect = NULL;
|
||
HIDDEN TMask* _special_mask = NULL;
|
||
|
||
HIDDEN TForm& form()
|
||
{
|
||
CHECK(_cur_form, "Can't print NULL form");
|
||
return *_cur_form;
|
||
}
|
||
|
||
HIDDEN TPrint_section& section()
|
||
{
|
||
CHECK(_cur_sect, "Can't print NULL section");
|
||
return *_cur_sect;
|
||
}
|
||
|
||
HIDDEN TMask& special_mask()
|
||
{
|
||
CHECK(_special_mask, "Can't access NULL mask");
|
||
return *_special_mask;
|
||
}
|
||
|
||
|
||
// @doc INTERNAL
|
||
|
||
// @func Funzione che converte dalla notazione carattere al corrispondente
|
||
// enum <t pagetype>
|
||
//
|
||
// @rdesc Ritorna il <t pagetype> corrispondente
|
||
pagetype char2page(
|
||
char c) // @parm Notazione carattere del tipo di pagina
|
||
|
||
{
|
||
pagetype pt;
|
||
switch(c)
|
||
{
|
||
case '1':
|
||
case 'E':
|
||
pt = even_page; break;
|
||
case '2':
|
||
case 'F':
|
||
pt = first_page; break;
|
||
case '3':
|
||
case 'L':
|
||
pt = last_page; break;
|
||
default:
|
||
pt = odd_page; break;
|
||
}
|
||
return pt;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Gestione TFieldref su maschera
|
||
// ID CAMPO ATTIVO
|
||
// xx0 Stringa completa del TFieldref
|
||
// xx1 Descrizione file
|
||
// xx2 Bottone selezione file X
|
||
// xx3 Descrizione campo
|
||
// xx4 Bottone selezione campo X
|
||
// xx5 Primo carattere campo X
|
||
// xx6 Ultimo carattere campo X
|
||
///////////////////////////////////////////////////////////
|
||
|
||
HIDDEN void put_fieldref(const TFieldref& fr, TMask_field& f)
|
||
{
|
||
TRelation_description& rd = form().rel_desc();
|
||
rd.set_cur_file(fr.file());
|
||
|
||
TString80 desc; desc << fr;
|
||
f.set(desc);
|
||
|
||
TMask& m = f.mask();
|
||
const short id = f.dlg(); // Campo contenente il TFieldref
|
||
|
||
m.set(id+1, rd.file_desc());
|
||
m.set(id+3, rd.get_field_description(fr.name()));
|
||
m.set(id+5, (fr.from() > 0 || fr.to() > 0) ? fr.from()+1 : 0);
|
||
m.set(id+6, fr.to() > fr.from() ? fr.to() : 0);
|
||
}
|
||
|
||
|
||
// Handler of F_BUT_FILE field on mask
|
||
HIDDEN bool but_file_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_F9)
|
||
{
|
||
TRelation_description& r = form().rel_desc();
|
||
|
||
TEdit_field& e = f.mask().efield(f.dlg()-1);
|
||
TFieldref ref; ref = e.get();
|
||
if (r.choose_file(ref.file()))
|
||
{
|
||
ref.set_file(r.file_num());
|
||
put_fieldref(ref, e);
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
HIDDEN bool but_file_handler_sub(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
TRelation_description& r = form().rel_desc();
|
||
|
||
TEdit_field& e = f.mask().efield(f.dlg()-2);
|
||
TFieldref ref; ref = e.get();
|
||
if (r.choose_file(ref.file()))
|
||
{
|
||
ref.set_file(r.file_num());
|
||
f.mask().set(F_FILE1,r.file_desc());
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
// Handler of F_BUT_FIELD field on mask
|
||
HIDDEN bool but_field_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_F9)
|
||
{
|
||
TRelation_description& r = form().rel_desc();
|
||
TEdit_field& e = f.mask().efield(f.dlg()-3); // TBC
|
||
TFieldref ref; ref = e.get();
|
||
if (r.choose_field(ref.name()))
|
||
{
|
||
ref.set_name(r.field_name());
|
||
put_fieldref(ref, e);
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// Handler of F_FROM field on mask
|
||
HIDDEN bool from_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (f.to_check(k))
|
||
{
|
||
TEdit_field& e = f.mask().efield(f.dlg()-5);
|
||
TFieldref ref; ref = e.get();
|
||
ref.set_from(atoi(f.get()));
|
||
put_fieldref(ref, e);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// Handler of F_TO field on mask
|
||
HIDDEN bool to_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (f.to_check(k))
|
||
{
|
||
TEdit_field& e = f.mask().efield(f.dlg()-6);
|
||
TFieldref ref; ref = e.get();
|
||
ref.set_to(atoi(f.get()));
|
||
put_fieldref(ref, e);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
HIDDEN bool dateformat_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
TMask& m = f.mask();
|
||
|
||
char fmt[8];
|
||
fmt[0] = m.get(F_DFORMAT)[0];
|
||
fmt[1] = m.get(F_DDAY)[0];
|
||
fmt[2] = m.get(F_DMONTH)[0];
|
||
fmt[3] = m.get(F_DYEAR)[0];
|
||
fmt[4] = m.get(F_DSEP)[0];
|
||
fmt[5] = '\0';
|
||
|
||
const TDate d(TODAY);
|
||
const TFormatted_date ex(d,fmt);
|
||
m.set(F_DEXAMPLE, ex.string());
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
HIDDEN bool fmt_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k==K_ENTER || k==K_TAB)
|
||
{
|
||
TMask& m = f.mask();
|
||
TPrint_section& s = ::section();
|
||
if (s.columnwise())
|
||
{
|
||
const int fmt_len = m.get(F_PICTURE).len(); // length of picture
|
||
m.set(F_LENFMT,fmt_len);
|
||
m.set(F_NUMCOL,s.fields());
|
||
}
|
||
else
|
||
m.set(F_NUMCOL,999);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_flags
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TForm_flags::TForm_flags()
|
||
{
|
||
automagic = dirty = finkr = finkl = memo = FALSE;
|
||
shown = enabled = TRUE;
|
||
}
|
||
|
||
// Read from string
|
||
// Certified 100%
|
||
bool TForm_flags::update(const char* s)
|
||
{
|
||
CHECK(s, "NULL flags string");
|
||
for (; *s; s++) switch(toupper(*s))
|
||
{
|
||
case 'A':
|
||
automagic = TRUE; break;
|
||
case 'D':
|
||
enabled = FALSE; break;
|
||
case 'H':
|
||
shown = FALSE; break;
|
||
case 'F':
|
||
finkl = TRUE; break;
|
||
case 'K':
|
||
finkr = TRUE; break;
|
||
case 'M':
|
||
memo = TRUE; break;
|
||
default :
|
||
error_box("Unknown form item flag '%c'", *s); break;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
// Print on stream
|
||
// Certified 100%
|
||
void TForm_flags::print_on(ostream& out) const
|
||
{
|
||
TString16 s;
|
||
|
||
if (automagic) s << "A";
|
||
if (!enabled) s << "D";
|
||
if (!shown) s << "H";
|
||
if (memo) s << "M";
|
||
if (finkl) s << "F";
|
||
if (finkr) s << "K";
|
||
|
||
if (s.not_empty())
|
||
out << " FLAGS \"" << s << '"' << endl;
|
||
}
|
||
|
||
// Set mask fields
|
||
// Certified 100%
|
||
void TForm_flags::print_on(TMask& m)
|
||
{
|
||
m.set(F_DISABLED, enabled ? " " : "X");
|
||
m.set(F_HIDDEN, shown ? " " : "X");
|
||
m.set(F_AUTOMAGIC, automagic ? "X" : " ");
|
||
m.set(F_FINKL, finkl ? " " : "X");
|
||
m.set(F_FINKR, finkr ? " " : "X");
|
||
}
|
||
|
||
|
||
// Get mask fields
|
||
// Certified 100%
|
||
void TForm_flags::read_from(const TMask& m)
|
||
{
|
||
shown = !m.get_bool(F_HIDDEN);
|
||
enabled = !m.get_bool(F_DISABLED);
|
||
automagic = m.get_bool(F_AUTOMAGIC);
|
||
finkl = !m.get_bool(F_FINKL);
|
||
finkr = !m.get_bool(F_FINKR);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_item
|
||
///////////////////////////////////////////////////////////
|
||
|
||
|
||
TForm_item::TForm_item(TPrint_section* section)
|
||
: _section(section), _x(-1), _y(-1), _width(0), _height(0), _id(0), _ofs(0),
|
||
_temp(FALSE)
|
||
{}
|
||
|
||
void TForm_item::copy_to_form_item(TForm_item* fi) const
|
||
{
|
||
fi->_flag = _flag; fi->_group = _group;
|
||
// come copiarlo facendo una cosa orrenda...
|
||
fi->_special.destroy();
|
||
specials().restart();
|
||
int items = special_items();
|
||
for (int k = 0; k < items; k++)
|
||
{
|
||
THash_object* ho = specials().get_hashobj();
|
||
fi->_special.add(ho->key(),ho->obj());
|
||
}
|
||
// fi->_special = _special; sarebbe utile avere un "operator =" per i TAssoc_array
|
||
|
||
fi->_temp = _temp; fi->_id = _id;
|
||
fi->_x = _x; fi->_y = _y;
|
||
fi->_width = _width; fi->_height = _height;
|
||
fi->_effective_height = _effective_height;
|
||
fi->_ofs = _ofs; fi->_prompt = _prompt;
|
||
fi->_desc = _desc; fi->_col_head = _col_head;
|
||
// Anche qui... copia uno alla volta
|
||
items = _message.items();
|
||
for (k = 0; k < items; k++)
|
||
fi->_message.add(_message.row(k),k);
|
||
// fi->_message = _message; sarebbe utile avere un "operator =" per i TString_array
|
||
}
|
||
|
||
TObject* TForm_item::dup() const
|
||
{
|
||
TForm_item * fi = new TForm_item(_section);
|
||
copy_to_form_item(fi);
|
||
return fi;
|
||
}
|
||
|
||
bool TForm_item::parse_head(TScanner& scanner)
|
||
{
|
||
_id = scanner.integer();
|
||
|
||
if (_id == 0) // Temporary
|
||
_id = _section->fields()+1;
|
||
|
||
_width = scanner.integer();
|
||
if (_width > 0)
|
||
_height = scanner.integer();
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
void TForm_item::print_on(ostream& out) const
|
||
{
|
||
out << class_name() << ' ' << id();
|
||
if (_width > 0)
|
||
{
|
||
out << ' ' << _width;
|
||
if (_height > 0)
|
||
out << ' ' << _height;
|
||
}
|
||
out << "\nBEGIN\n";
|
||
|
||
print_body(out);
|
||
|
||
out << "END\n" << endl;
|
||
}
|
||
|
||
|
||
void TForm_item::print_body(ostream& out) const
|
||
{
|
||
out << " KEY \"" << _desc << "\"\n";
|
||
|
||
if (_y >= 0)
|
||
out << " PROMPT " << _x << ' ' << _y << " \"" << _prompt << "\"\n";
|
||
|
||
if (_group.ones())
|
||
out << " GROUP " << _group << "\n";
|
||
|
||
out << _flag;
|
||
|
||
if (_message.items() == 1)
|
||
{
|
||
const TToken_string& m = _message.row(0);
|
||
if (!m.empty_items())
|
||
out << " MESSAGE " << m << endl;
|
||
}
|
||
|
||
if (_special.items() > 0)
|
||
{
|
||
TAssoc_array& aa = specials();
|
||
aa.restart();
|
||
|
||
THash_object* op;
|
||
|
||
while ((op = aa.get_hashobj()) != NULL)
|
||
{
|
||
TToken_string& t = (TToken_string&)op->obj();
|
||
TString typ(t.get(0));
|
||
TString val(t.get(1));
|
||
TString des(t.get(2));
|
||
out << " SPECIAL " << typ << " " << op->key()
|
||
<< " \"" << val << "\" \"" << des << "\"\n";
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
bool TForm_item::parse_item(TScanner& scanner)
|
||
{
|
||
if (scanner.key() == "PR")
|
||
{
|
||
_x = scanner.integer();
|
||
_y = scanner.integer();
|
||
_prompt = scanner.string();
|
||
return TRUE;
|
||
}
|
||
|
||
if (scanner.key() == "FL")
|
||
return _flag.update(scanner.string());
|
||
|
||
if (scanner.key() == "ME")
|
||
{
|
||
TFixed_string m(scanner.line());
|
||
m.strip_spaces();
|
||
int n = 0;
|
||
if (m.left(5) == "EMPTY")
|
||
{
|
||
n = 1;
|
||
m.ltrim(5);
|
||
}
|
||
if (!m.blank())
|
||
message(n).add(m);
|
||
return TRUE;
|
||
}
|
||
|
||
if (scanner.key() == "KE")
|
||
{
|
||
_desc = scanner.string();
|
||
return TRUE;
|
||
}
|
||
|
||
if (scanner.key() == "GR")
|
||
{
|
||
_group.set(scanner.line());
|
||
return TRUE;
|
||
}
|
||
|
||
if (scanner.key() == "SP")
|
||
{
|
||
TToken_string val(scanner.pop());
|
||
TString16 var = scanner.pop();
|
||
val.add(scanner.string());
|
||
val.add(scanner.string());
|
||
|
||
_special.add(var,val);
|
||
return TRUE;
|
||
}
|
||
|
||
yesnofatal_box("Unknown symbol in item '%s': '%s'",
|
||
(const char*)key(), (const char*)scanner.token());
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
bool TForm_item::parse(TScanner& scanner)
|
||
{
|
||
bool ok = parse_head(scanner);
|
||
|
||
if (ok && scanner.popkey() != "BE")
|
||
ok = yesnofatal_box("Missing BEGIN in form item %s", (const char*)key());
|
||
|
||
while (ok && scanner.popkey() != "EN")
|
||
ok = parse_item(scanner);
|
||
|
||
return ok;
|
||
}
|
||
|
||
bool TForm_item::read_from(const TRectype& prof)
|
||
{
|
||
CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
|
||
bool changed = FALSE;
|
||
|
||
int i = prof.get_int("X");
|
||
if (_x != i)
|
||
{
|
||
_x = i;
|
||
changed = TRUE;
|
||
}
|
||
i = prof.get_int("Y");
|
||
if (_y != i)
|
||
{
|
||
_y = i;
|
||
changed = TRUE;
|
||
}
|
||
i = prof.get_int("LEN");
|
||
if (_width != i)
|
||
{
|
||
_width = i;
|
||
changed = TRUE;
|
||
}
|
||
i = prof.get_int("HGT");
|
||
if (_height != i)
|
||
{
|
||
_height = i;
|
||
changed = TRUE;
|
||
}
|
||
TString p(prof.get("PROMPT"));
|
||
if (p.not_empty())
|
||
{
|
||
if (p[0] == '\xFE') p.cut(0);
|
||
const int l = p.len();
|
||
if (l > 0 && p[l-1] == '\xFF')
|
||
{
|
||
p[l-1] = ' ';
|
||
p << '\0';
|
||
}
|
||
_prompt = p;
|
||
changed = TRUE;
|
||
}
|
||
|
||
const bool s = prof.get_bool("ATTIVO");
|
||
if (_flag.shown != s)
|
||
{
|
||
_flag.shown = s;
|
||
changed = TRUE;
|
||
}
|
||
|
||
TToken_string special(prof.get("SPECIAL"),'\n');
|
||
special.rtrim();
|
||
const int sp_items = special.items();
|
||
for (i = 0; i < sp_items; i++)
|
||
{
|
||
TToken_string sp(special.get(i), '$');
|
||
TString key(sp.get(0));
|
||
TString val(sp.get(1));
|
||
|
||
if (!_special.is_key(key))
|
||
{
|
||
error_box("Variabile speciale non presente nel profilo: %s",
|
||
(const char*)key);
|
||
continue;
|
||
}
|
||
TToken_string& tt = (TToken_string&)_special[key];
|
||
tt.add(val,1);
|
||
// forza riscrittura su memo
|
||
if (tt.items() == 3) tt.add("X");
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void TForm_item::print_on(TRectype& prof)
|
||
{
|
||
CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
|
||
prof.put("ID", id());
|
||
prof.put("X", _x);
|
||
prof.put("Y", _y);
|
||
prof.put("LEN", width());
|
||
prof.put("HGT", height());
|
||
if (_prompt.empty()) _prompt << '\xFE' << '\0';
|
||
const int l = _prompt.len();
|
||
const char c = _prompt[l-1];
|
||
if (c==' ') _prompt[l-1]='\xFF';
|
||
prof.put("PROMPT", _prompt);
|
||
prof.put("ATTIVO", shown() ? "X" : " ");
|
||
|
||
// specials: se e' stato cambiato, la tokenstring del valore contiene
|
||
// una X alla fine (campo 3)
|
||
{
|
||
TToken_string special(128,'\n');
|
||
_special.restart();
|
||
|
||
for (int i = 0; i < _special.items(); i++)
|
||
{
|
||
THash_object* o = _special.get_hashobj();
|
||
|
||
TString key(o->key());
|
||
TToken_string& tt = (TToken_string&)o->obj();
|
||
|
||
if (tt.items() == 4)
|
||
{
|
||
TToken_string sp(key,'$');
|
||
TString val(tt.get(1));
|
||
sp.add(val);
|
||
special.add(sp);
|
||
}
|
||
}
|
||
special.rtrim();
|
||
prof.put("SPECIAL", special);
|
||
}
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Abilita/Disabilita il campo
|
||
void TForm_item::enable(
|
||
bool on) // @parm Operazione da svolgere sul campo:
|
||
// @flag TRUE | Il campo viene abiliato
|
||
// @flag FALSE | Il campo viene disabiliato
|
||
|
||
// @comm Viene automaticamente setta se il campo diventi visibile o nascosto (chiama <mf TForm_item::show>)
|
||
{
|
||
_flag.enabled = on;
|
||
show(on);
|
||
}
|
||
|
||
void TForm_item::set_special_value(const char* s, const char* val)
|
||
{
|
||
TToken_string& tt = (TToken_string&) _special[s];
|
||
tt.add(val,1);
|
||
if (tt.items()==3) tt.add("X");
|
||
}
|
||
|
||
const char* TForm_item::get_special_item(const char* s, int n) const
|
||
{
|
||
TAssoc_array& sp = (TAssoc_array&)_special;
|
||
if (sp.is_key(s))
|
||
{
|
||
TToken_string& tt = (TToken_string&) sp[s];
|
||
return tt.get(n);
|
||
} else return "";
|
||
}
|
||
|
||
void TForm_item::string_at(int x, int y, const char* s)
|
||
{
|
||
if (shown())
|
||
{
|
||
if (section().columnwise()) x += _ofs;
|
||
TPrintrow& row = section().row(y-1); // Seleziona riga di stampa
|
||
|
||
if (_width > 0 && strlen(s) > (word)_width) // Tronca testo se necessario
|
||
{
|
||
strncpy(__tmp_string, s, width());
|
||
__tmp_string[_width] = '\0';
|
||
s = __tmp_string;
|
||
}
|
||
row.put(s, x-1); // Stampa testo
|
||
}
|
||
}
|
||
|
||
|
||
TToken_string& TForm_item::message(int m)
|
||
{
|
||
TToken_string* t = (TToken_string*)_message.objptr(m);
|
||
if (t == NULL)
|
||
{
|
||
t = new TToken_string(16);
|
||
_message.add(t, m);
|
||
}
|
||
return *t;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Manda il messaggio al campo <p dest>
|
||
void TForm_item::send_message(
|
||
const TString& cmd, // @parm Messaggio di comando
|
||
TForm_item& des) const // @parm Campo a cui destinare il messaggio
|
||
{
|
||
if (cmd == "ADD" || cmd == "INC")
|
||
{
|
||
if (form().message_add_enabled())
|
||
{
|
||
const real n((cmd[0] == 'I') ? "1.0" : get());
|
||
real r(des.get());
|
||
r += n;
|
||
des.set(r.string());
|
||
}
|
||
} else
|
||
if (cmd == "COPY")
|
||
{
|
||
des.set(get());
|
||
} else
|
||
if (cmd == "APPEND")
|
||
{
|
||
TString256 val = des.get();
|
||
if (val.not_empty()) val << ' ';
|
||
val << get();
|
||
des.set(val);
|
||
} else
|
||
if (cmd == "DISABLE")
|
||
{
|
||
des.disable();
|
||
} else
|
||
if (cmd == "ENABLE")
|
||
{
|
||
des.enable();
|
||
} else
|
||
if (cmd == "HIDE")
|
||
{
|
||
des.hide();
|
||
} else
|
||
if (cmd == "RESET")
|
||
{
|
||
des.set("");
|
||
} else
|
||
if (cmd == "SHOW")
|
||
{
|
||
des.show();
|
||
} else
|
||
if (cmd[0] == '"')
|
||
{
|
||
TString256 val(cmd);
|
||
val.strip("\"");
|
||
des.set(val);
|
||
} else
|
||
error_box("Unknown message in item '%s': '%s'",
|
||
(const char*)key(), (const char*)cmd);
|
||
}
|
||
|
||
|
||
TForm_item& TForm_item::find_field(const TString& id) const
|
||
{
|
||
if (isdigit(id[0])) // Field in the same section
|
||
{
|
||
TForm_item& des = section().find_field(atoi(id));
|
||
return des;
|
||
}
|
||
|
||
const pagetype pt = (id[1] == '-') ? section().page_type() : char2page(id[1]);
|
||
const int freccia = id.find("->");
|
||
CHECKS(freccia > 0, "Non trovo la freccia nel campo ", (const char*)id);
|
||
TForm_item& des = form().find_field(id[0], pt, atoi(id.mid(freccia+2)));
|
||
return des;
|
||
}
|
||
|
||
bool TForm_item::do_message(int num)
|
||
{
|
||
TToken_string& messaggio = message(num);
|
||
if (messaggio.empty_items()) return FALSE;
|
||
|
||
TToken_string msg(16, ',');
|
||
for (const char* m = messaggio.get(0); m; m = messaggio.get())
|
||
{
|
||
msg = m;
|
||
if (*m == '_')
|
||
form().validate(*this, msg);
|
||
else
|
||
{
|
||
const TString16 cmd(msg.get()); // Get command
|
||
const TString16 id = msg.get(); // Get destination
|
||
|
||
if (id.right(1) == "@")
|
||
{
|
||
const word group = atoi(id);
|
||
// Send the message to all fields with the given group
|
||
for (word i = 0; i < section().fields(); i++)
|
||
{
|
||
TForm_item& des = section().field(i);
|
||
if (des.in_group(group))
|
||
send_message(cmd, des);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TForm_item& des = find_field(id);
|
||
send_message(cmd, des);
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
bool TForm_item::update()
|
||
{
|
||
if (_prompt.right(1) == "#")
|
||
{
|
||
TString prompt(_prompt);
|
||
for (int i = prompt.len()-2; i >= 0; i--)
|
||
if (prompt[i] != '#') break;
|
||
prompt.cut(i+1);
|
||
string_at(x(), _y, prompt);
|
||
}
|
||
else string_at(x(), _y, _prompt);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void TForm_item::print_on(TToken_string& row) const
|
||
{
|
||
row.cut(0);
|
||
row.add(id());
|
||
row.add(key());
|
||
row.add(_y);
|
||
row.add(_x);
|
||
row.add(shown() ? " " : "X");
|
||
|
||
if (form().edit_level() > 1)
|
||
{
|
||
const long fu = _group.first_one();
|
||
if (fu > 0) row.add(fu);
|
||
else row.add(" ");
|
||
}
|
||
}
|
||
|
||
void TForm_item::print_on_sheet_row(TToken_string& tt) const
|
||
{
|
||
TString tmp(80);
|
||
tt.add(_id, idt_id - 101);
|
||
tt.add(_desc, dsc_id - 101);
|
||
tt.add(_x, _section->columnwise() ? col_id - 101 : xps_id - 101);
|
||
tt.add(_width, len_id - 101);
|
||
if (!_section->columnwise())
|
||
tt.add(_y, yps_id - 101);
|
||
tt.add(class_name(), typ_id - 101);
|
||
tt.add(shown() ? " " : "X", prn_id - 101);
|
||
tmp = example(); tt.add(tmp, frm_id - 101);
|
||
|
||
if (_section->columnwise())
|
||
{
|
||
tt.add(_ofs, spc_id -101);
|
||
tt.add(finkl() ? " " : "X", fnl_id -101);
|
||
tt.add(finkr() ? " " : "X", fnr_id -101);
|
||
tt.add(_col_head, int_id - 101);
|
||
}
|
||
}
|
||
|
||
void TForm_item::print_on(TMask& m)
|
||
{
|
||
m.set(F_CLASS, class_name());
|
||
m.set(F_ID, id());
|
||
m.set(F_KEY, key());
|
||
m.set(F_X, _x);
|
||
m.set(F_Y, _y);
|
||
m.set(F_PROMPT, _prompt);
|
||
m.set(F_WIDTH, _width);
|
||
if (_section->columnwise())
|
||
m.set(F_INTEST, _col_head);
|
||
m.set(F_HEIGHT, _height);
|
||
m.set(F_SPACES, _ofs);
|
||
|
||
_flag.print_on(m);
|
||
|
||
for (int g = 1; g <= 24; g++)
|
||
m.set(F_GROUP+g, _group[g] ? "X" : " ");
|
||
}
|
||
|
||
void TForm_item::read_from(const TMask& m)
|
||
{
|
||
_desc = m.get(F_KEY);
|
||
_x = atoi(m.get(F_X));
|
||
_y = atoi(m.get(F_Y));
|
||
_prompt = m.get(F_PROMPT);
|
||
_width = atoi(m.get(F_WIDTH));
|
||
if (_section->columnwise())
|
||
_col_head = m.get(F_INTEST);
|
||
_height = atoi(m.get(F_HEIGHT));
|
||
_id = atoi(m.get(F_ID));
|
||
_ofs = atoi(m.get(F_SPACES));
|
||
|
||
_flag.read_from(m);
|
||
|
||
_group.reset();
|
||
for (int g = 1; g <= 24; g++)
|
||
_group.set(g, m.get_bool(F_GROUP+g));
|
||
}
|
||
|
||
void TForm_item::read_from(TToken_string& s)
|
||
{
|
||
_id = s.get_int(idt_id - 101);
|
||
_desc = s.get(dsc_id - 101);
|
||
_x = _section->columnwise() ? s.get_int(col_id - 101) : s.get_int(xps_id - 101);
|
||
_width = s.get_int(len_id - 101);
|
||
if (!_section->columnwise())
|
||
_y = s.get_int(yps_id - 101);
|
||
_flag.set_shown(s.get(prn_id - 101)[0] != 'X');
|
||
|
||
if (_section->columnwise())
|
||
{
|
||
_ofs = s.get_int(spc_id - 101);
|
||
_flag.set_finkl(s.get(fnl_id - 101)[0] != 'X');
|
||
_flag.set_finkr(s.get(fnr_id - 101)[0] != 'X');
|
||
_col_head = s.get(int_id - 101);
|
||
}
|
||
set_dirty();
|
||
}
|
||
|
||
bool TForm_item::edit(TMask& m)
|
||
{
|
||
m.enable(F_CLASS, m.insert_mode());
|
||
m.reset();
|
||
|
||
if (m.insert_mode())
|
||
{
|
||
short id = 0;
|
||
for (word i = 0; i < section().fields(); i++)
|
||
{
|
||
const TForm_item& f = section().field(i);
|
||
if (f.id() > id) id = f.id();
|
||
}
|
||
_id = id+1;
|
||
}
|
||
|
||
print_on(m);
|
||
|
||
const bool godmode = form().edit_level() > 1;
|
||
m.enable_page(1, godmode);
|
||
m.enable(-7, godmode);
|
||
m.enable(F_ID, godmode);
|
||
m.enable(F_KEY,godmode);
|
||
m.enable(F_Y,!_section->columnwise());
|
||
m.enable(F_INTEST,_section->columnwise());
|
||
if (_flag.memo)
|
||
{
|
||
m.disable(F_PROMPT);
|
||
m.hide(F_PROMPT);
|
||
m.enable(F_MEMO);
|
||
m.show(F_MEMO);
|
||
m.enable(F_HEIGHT);
|
||
m.show(F_HEIGHT);
|
||
}
|
||
else
|
||
{
|
||
m.hide(F_MEMO);
|
||
m.disable(F_MEMO);
|
||
}
|
||
const bool dirty = m.run() == K_ENTER;
|
||
if (dirty)
|
||
{
|
||
read_from(m);
|
||
set_dirty();
|
||
}
|
||
return dirty;
|
||
}
|
||
|
||
const TString& TForm_item::picture() const
|
||
{
|
||
CHECK(0, "Can't get the picture of a generic form item!");
|
||
return _prompt;
|
||
}
|
||
|
||
void TForm_item::set_picture(const char*)
|
||
{
|
||
CHECK(0, "Can't set the picture of a generic form item!");
|
||
}
|
||
|
||
TToken_string& TForm_item::memo_info()
|
||
{
|
||
CHECK(0, "Can't get a memo of a generic form item!");
|
||
return TToken_string();
|
||
}
|
||
|
||
short TForm_item::x()
|
||
{
|
||
if (_section == NULL || !_section->columnwise())
|
||
return _x;
|
||
return _section->tab(_x-1) + _section->ofspc();
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_subsection
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TForm_subsection : public TForm_item
|
||
{
|
||
TPrint_section _ssec;
|
||
TString _name;
|
||
|
||
int _file_id; // ID del file su cui iterare in stampa se previsto
|
||
|
||
protected:
|
||
virtual void print_on(ostream& out) const;
|
||
public:
|
||
virtual TObject* dup() const;
|
||
virtual bool parse(TScanner& s);
|
||
virtual bool update();
|
||
virtual bool edit(TMask& m);
|
||
|
||
virtual const char* class_name() const { return "SEZIONE"; }
|
||
|
||
TPrint_section& subsection() { return _ssec; }
|
||
|
||
virtual void show(bool on = TRUE);
|
||
virtual void enable(bool on = TRUE);
|
||
void hide() { show(FALSE); }
|
||
void disable() { enable(FALSE); }
|
||
|
||
void name(const char* s) { _name = s; _desc << "Sottosezione " << s; }
|
||
const char* name() const { return _name; }
|
||
|
||
TForm_subsection(TPrint_section* section, const char* name = "");
|
||
virtual ~TForm_subsection() {}
|
||
};
|
||
|
||
|
||
TForm_subsection::TForm_subsection(TPrint_section* s, const char* nm) :
|
||
TForm_item(s), _ssec(&(s->form()), s->section_type(), s->page_type(), TRUE), _file_id(-1), _name(nm)
|
||
{}
|
||
|
||
TObject* TForm_subsection::dup() const
|
||
{
|
||
TForm_subsection* fs = new TForm_subsection(_section);
|
||
copy_to_form_item(fs);
|
||
fs->_ssec = _ssec;
|
||
fs->_name = _name;
|
||
fs->_file_id = _file_id;
|
||
return fs;
|
||
}
|
||
|
||
bool TForm_subsection::parse(TScanner& s)
|
||
{
|
||
name(s.pop());
|
||
_width = s.integer();
|
||
_height = s.integer();
|
||
_x = s.integer();
|
||
_y = s.integer();
|
||
|
||
if (s.popkey() == "FI") // FILE su cui iterare con next_match
|
||
_file_id = s.integer(); // TBI controllo alias
|
||
else s.push();
|
||
|
||
return _ssec.parse(s);
|
||
}
|
||
|
||
|
||
bool TForm_subsection::update()
|
||
{
|
||
bool ok = FALSE;
|
||
TRelation* rel = form().relation();
|
||
|
||
if (rel == NULL || _file_id == -1)
|
||
ok = _ssec.update();
|
||
else
|
||
{
|
||
int i = 0;
|
||
if (rel->is_first_match(_file_id))
|
||
do {
|
||
if (!(ok = _ssec.update()))
|
||
break;
|
||
_ssec.set_repeat_count(++i);
|
||
}
|
||
while (rel->next_match(_file_id));
|
||
_ssec.set_repeat_count(0);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
|
||
bool TForm_subsection::edit(TMask& m)
|
||
{
|
||
// mask con nome e bottone edit contents / annulla
|
||
TMask mu("ba2100u");
|
||
mu.set(F_CAPTION, _name);
|
||
mu.set(F_WIDTH, _width);
|
||
mu.set(F_HEIGHT, _height);
|
||
mu.set(F_X, _x);
|
||
mu.set(F_Y, _y);
|
||
|
||
mu.set_handler(F_BUT_FILE1, but_file_handler_sub);
|
||
|
||
if (_file_id != -1)
|
||
{
|
||
// set file description
|
||
form().rel_desc().set_cur_file(_file_id);
|
||
TString80 desc; desc << form().rel_desc().file_desc();
|
||
mu.set(F_FILE1, desc);
|
||
}
|
||
|
||
KEY k;
|
||
|
||
// vedere se e' nuova etc.
|
||
// gestire aggiunta / modifica menu
|
||
|
||
while ((k = mu.run()) != K_ESC)
|
||
{
|
||
if (mu.field(F_CAPTION).dirty())
|
||
_name = mu.get(F_CAPTION);
|
||
|
||
if (mu.field(F_WIDTH).dirty())
|
||
_width = mu.get_int(F_WIDTH);
|
||
|
||
if (mu.field(F_HEIGHT).dirty())
|
||
_height = mu.get_int(F_HEIGHT);
|
||
|
||
if (mu.field(F_X).dirty())
|
||
_x = mu.get_int(F_X);
|
||
|
||
if (mu.field(F_Y).dirty())
|
||
_y = mu.get_int(F_Y);
|
||
|
||
if (mu.field(F_FILE1).dirty())
|
||
{
|
||
if (mu.get(F_FILE1).empty())
|
||
_file_id = -1;
|
||
else
|
||
_file_id = form().rel_desc().file_num();
|
||
}
|
||
|
||
if (k == K_INS)
|
||
_ssec.edit(_name);
|
||
else if (k == K_DEL)
|
||
{
|
||
// remove myself
|
||
|
||
}
|
||
else if (k == K_ENTER)
|
||
break;
|
||
}
|
||
|
||
return k != K_ESC;
|
||
}
|
||
|
||
|
||
void TForm_subsection::print_on(ostream& out) const
|
||
{
|
||
out << "SEZIONE " << _name << ' ' << _width << ' ' << _height
|
||
<< ' ' << _x << ' ' << _y;
|
||
|
||
if (_file_id != -1)
|
||
out << " FILE " << _file_id;
|
||
out << "\n";
|
||
|
||
for (word i = 0; i < _ssec.fields(); i++)
|
||
out << _ssec.field(i);
|
||
out << "\nEND" << "\n";
|
||
}
|
||
|
||
// ???
|
||
void TForm_subsection::show(bool on)
|
||
{
|
||
for (unsigned int i = 0; i < _ssec.fields(); i++)
|
||
_ssec.field(i).show(on);
|
||
}
|
||
|
||
// ???
|
||
void TForm_subsection::enable(bool on)
|
||
{
|
||
for (unsigned int i = 0; i < _ssec.fields(); i++)
|
||
_ssec.field(i).enable(on);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_string
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TForm_string : public TForm_item
|
||
{
|
||
TString _str, _picture;
|
||
TArray _field;
|
||
TToken_string _memo;
|
||
|
||
protected:
|
||
virtual const char* class_name() const { return "STRINGA"; }
|
||
virtual void print_body(ostream& out) const;
|
||
|
||
virtual void print_on(TMask& m);
|
||
virtual void read_from(const TMask& m);
|
||
|
||
virtual bool read_from(const TRectype& rform);
|
||
virtual void print_on(TRectype& rform);
|
||
|
||
virtual void print_on(TToken_string& row);
|
||
|
||
virtual bool parse_item(TScanner&);
|
||
virtual bool read();
|
||
virtual bool update();
|
||
virtual const char* example() const;
|
||
virtual void apply_format(TString& s, const TString& p) const;
|
||
|
||
virtual TToken_string& memo_info() { return _memo; }
|
||
|
||
virtual const char* get() const;
|
||
bool set(const char*);
|
||
|
||
TFieldref& field(int i) const { return (TFieldref&)_field[i]; }
|
||
|
||
public:
|
||
virtual TObject* dup() const;
|
||
virtual const int fields() { return _field.items();}
|
||
virtual const TString& picture() const { return _picture; }
|
||
virtual void set_picture(const char* p) { _picture = p; }
|
||
virtual void put_paragraph(const char* s);
|
||
|
||
virtual bool edit(TMask& m);
|
||
TForm_string(TPrint_section* section);
|
||
virtual ~TForm_string() {}
|
||
};
|
||
|
||
TForm_string::TForm_string(TPrint_section* section)
|
||
: TForm_item(section), _memo("",'\n')
|
||
{}
|
||
|
||
TObject* TForm_string::dup() const
|
||
{
|
||
TForm_string* fs = new TForm_string(_section);
|
||
copy_to_form_item(fs);
|
||
fs->_str = _str;
|
||
fs->_picture = _picture;
|
||
fs->_field = _field;
|
||
fs->_memo = _memo;
|
||
return fs;
|
||
}
|
||
|
||
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")
|
||
{
|
||
TFieldref* fr = new TFieldref(scanner.line(), 0);
|
||
_field.add(fr);
|
||
return TRUE;
|
||
}
|
||
|
||
if (scanner.key() == "PI")
|
||
{
|
||
set_picture(scanner.string());
|
||
return TRUE;
|
||
}
|
||
|
||
return TForm_item::parse_item(scanner);
|
||
}
|
||
|
||
void TForm_string::print_body(ostream& out) const
|
||
{
|
||
TForm_item::print_body(out);
|
||
if (_picture.not_empty())
|
||
out << " PICTURE \"" << _picture << "\"" << endl;
|
||
for (int i = 0; i < _field.items(); i++)
|
||
out << " FIELD " << field(i) << endl;
|
||
}
|
||
|
||
bool TForm_string::read_from(const TRectype& prof)
|
||
{
|
||
bool changed = TForm_item::read_from(prof);
|
||
|
||
const TString& pict = prof.get("PICT");
|
||
if (_picture != pict)
|
||
{
|
||
_picture = pict;
|
||
changed = TRUE;
|
||
}
|
||
|
||
if (has_memo())
|
||
{
|
||
const TString& m = prof.get("TESTO");
|
||
if (_memo != m)
|
||
{
|
||
_memo = m;
|
||
changed = TRUE;
|
||
}
|
||
}
|
||
|
||
return changed;
|
||
}
|
||
|
||
void TForm_string::print_on(TToken_string& row)
|
||
{
|
||
TForm_item::print_on(row);
|
||
if (_field.items() && form().edit_level() > 1)
|
||
row << '|' << field(0);
|
||
}
|
||
|
||
void TForm_string::print_on(TRectype& prof)
|
||
{
|
||
TForm_item::print_on(prof);
|
||
prof.put("PICT", _picture);
|
||
if (has_memo())
|
||
{
|
||
prof.put("TESTO", _memo);
|
||
}
|
||
}
|
||
|
||
void TForm_string::print_on(TMask& m)
|
||
{
|
||
TForm_item::print_on(m);
|
||
for (int i = 0; i < _field.items(); i++)
|
||
put_fieldref(field(i), m.field(i == 0 ? F_FIELDREF1 : F_FIELDREF2));
|
||
|
||
m.set(F_PICTURE, _picture);
|
||
m.set(F_MEMO, _memo);
|
||
|
||
TSheet_field& s = (TSheet_field&)m.field(F_ITEMS);
|
||
s.reset();
|
||
if (_message.items() > 0)
|
||
{
|
||
TToken_string& row = s.row(0);
|
||
row = " | ";
|
||
row.add(message(0));
|
||
}
|
||
}
|
||
|
||
void TForm_string::read_from(const TMask& m)
|
||
{
|
||
TForm_item::read_from(m);
|
||
_picture = m.get(F_PICTURE);
|
||
_memo = m.get(F_MEMO);
|
||
|
||
for (int i = 0; i < 2; i++)
|
||
{
|
||
const TString& f = m.get(i == 0 ? F_FIELDREF1 : F_FIELDREF2);
|
||
if (f.not_empty())
|
||
{
|
||
TFieldref* fr = (TFieldref*)_field.objptr(i);
|
||
if (fr == NULL)
|
||
{
|
||
fr = new TFieldref(f, 0);
|
||
_field.add(fr, i);
|
||
}
|
||
*fr = f;
|
||
}
|
||
else
|
||
_field.destroy(i);
|
||
}
|
||
|
||
TSheet_field& f = (TSheet_field&)m.field(F_ITEMS);
|
||
TToken_string& msg = f.row(0);
|
||
if (msg.empty_items())
|
||
_message.destroy(0);
|
||
else
|
||
_message.add(msg.get(2), 0);
|
||
}
|
||
|
||
bool TForm_string::set(const char* s)
|
||
{
|
||
_str = s;
|
||
return TRUE;
|
||
}
|
||
|
||
const char* TForm_string::get() const
|
||
{ return _str; }
|
||
|
||
|
||
// Se un campo e' abilitato ed ha almeno un riferimento su file leggilo
|
||
bool TForm_string::read()
|
||
{
|
||
const bool ok = enabled();
|
||
if (ok)
|
||
{
|
||
if (_field.items() != 0)
|
||
{
|
||
const char* s = "";
|
||
const TRelation* r = form().relation();
|
||
CHECK(r, "Can't read from null relation");
|
||
for (int i = 0; i < _field.items() && *s == '\0'; i++)
|
||
s = field(i).read(*r);
|
||
set(s);
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
void TForm_string::put_paragraph(const char* s)
|
||
{
|
||
if (hidden()) return;
|
||
const int h = height();
|
||
|
||
if (h > 1)
|
||
{
|
||
const int w = width();
|
||
TParagraph_string p(s, w);
|
||
int i = _prompt.not_empty() ? 1 : 0;
|
||
for (; (s = p.get()) != NULL && i < h; i++)
|
||
string_at(x(), _y+i, s);
|
||
_effective_height = i;
|
||
}
|
||
else
|
||
string_at(-1, _y, s);
|
||
}
|
||
|
||
|
||
void TForm_string::apply_format(TString& s, const TString& p) const
|
||
{
|
||
TString tmp(s);
|
||
if (!p.blank())
|
||
{
|
||
TToken_string delim(4, ','); // Stringa con i due delimitatori
|
||
const char* pic = p; // Picture senza delimitatori
|
||
|
||
if (pic[0] == '(') // Se ci sono i delimitatori ...
|
||
{
|
||
const int bra = p.find(')');
|
||
if (bra > 0) // ... cerca la parentesi chiusa
|
||
{
|
||
delim = p.sub(1, bra); // memorizza delimitatori
|
||
pic += bra+1; // toglili dalla picture
|
||
}
|
||
}
|
||
|
||
if (class_name() == "DATA" && s.empty())
|
||
tmp ="";
|
||
else
|
||
tmp.picture(pic, s); // riempi la stringa col valore pitturato
|
||
|
||
if (!delim.empty_items()) // Aggiungi delimitatori
|
||
{
|
||
TString16 d(delim.get(0));
|
||
const int ld = d.len();
|
||
|
||
if (ld > 0) // Se il primo delimitatore e' valido ...
|
||
{
|
||
for (int spc = 0;s[spc]==' ' ; spc++) ;
|
||
if (spc < ld)
|
||
{
|
||
TString16 spazi;
|
||
spazi.spaces(ld - spc);
|
||
tmp.insert(spazi,0);
|
||
spc = ld;
|
||
}
|
||
tmp.overwrite(d,spc - ld);
|
||
}
|
||
d = delim.get();
|
||
if (d.not_empty()) // Se il secondo delimitatore e' valido ...
|
||
tmp << d; // ... aggiungilo alla fine
|
||
}
|
||
s = tmp;
|
||
}
|
||
}
|
||
|
||
bool TForm_string::update()
|
||
{
|
||
if (read())
|
||
{
|
||
TString s;
|
||
TForm_item::update();
|
||
if (!picture().blank())
|
||
{
|
||
s = get();
|
||
apply_format(s, picture());
|
||
put_paragraph(s);
|
||
}
|
||
else
|
||
put_paragraph(s=get()); // Stampa immediata senza picture
|
||
const int n = (_message.objptr(1) != NULL && s.empty() ? 1 : 0);
|
||
do_message(n);
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
const char* TForm_string::example() const
|
||
{
|
||
TString prova("XXXXXXXXXXXXXXXXXXXXXXXXXX");
|
||
apply_format(prova, picture());
|
||
const int w = width();
|
||
if (prova.size() > w && w > 0) prova.cut(w);
|
||
return strcpy(__tmp_string, prova);
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_number
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TForm_number : public TForm_string
|
||
{
|
||
void apply_format(real& r, TString& s) const;
|
||
|
||
protected: // TForm_string
|
||
virtual const char* class_name() const { return "NUMERO"; }
|
||
virtual bool parse_head(TScanner& scanner);
|
||
virtual bool update();
|
||
//virtual int height() const { return 0; }
|
||
|
||
protected:
|
||
int decimals() const { return _height; }
|
||
|
||
public:
|
||
|
||
virtual TObject* dup() const;
|
||
void set_decimals(int d) { _height = d; }
|
||
virtual const char* example() const;
|
||
virtual void set_picture(const char* p);
|
||
virtual void put_paragraph(const char * s);
|
||
|
||
TForm_number(TPrint_section* section) : TForm_string(section) {}
|
||
virtual ~TForm_number() {}
|
||
};
|
||
|
||
bool TForm_number::parse_head(TScanner& scanner)
|
||
{
|
||
return TForm_item::parse_head(scanner);
|
||
}
|
||
|
||
TObject* TForm_number::dup() const
|
||
{
|
||
TForm_number *fn = new TForm_number(_section);
|
||
copy_to_form_item(fn);
|
||
return fn;
|
||
}
|
||
|
||
void TForm_number::put_paragraph(const char* s)
|
||
{
|
||
if (hidden()) return;
|
||
|
||
int gap = 0;
|
||
if (section().columnwise())
|
||
{
|
||
const int w = width();
|
||
const int l = strlen(s);
|
||
if (w>l) gap = w-l;
|
||
}
|
||
if (_prompt.empty())
|
||
string_at(x()+gap, _y, s);
|
||
else
|
||
string_at(-1, _y, s); // se ha il prompt stampa all'ultima posizione raggiunta
|
||
}
|
||
|
||
bool TForm_number::update()
|
||
{
|
||
if (read())
|
||
{
|
||
TForm_item::update();
|
||
real n(get());
|
||
n.round(decimals());
|
||
|
||
if (!n.is_zero())
|
||
{
|
||
TString s;
|
||
apply_format(n,s);
|
||
put_paragraph(s);
|
||
do_message();
|
||
}
|
||
else
|
||
{
|
||
const int n = (_message.objptr(1) != NULL ? 1 : 0);
|
||
do_message(n);
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void TForm_number::apply_format(real& n , TString& s) const
|
||
{
|
||
if (!picture().blank())
|
||
{
|
||
TToken_string delim(4, ','); // Stringa con i due delimitatori
|
||
TString pic(picture()); // Picture senza delimitatori
|
||
int maxlen = -1;
|
||
|
||
if (pic[0] == '(') // Se ci sono i delimitatori ...
|
||
{
|
||
const int bra = pic.find(')');
|
||
if (bra > 0) // ... cerca la parentesi chiusa
|
||
{
|
||
delim = pic.sub(1, bra); // memorizza delimitatori
|
||
pic.ltrim(bra + 1); // toglili dalla picture
|
||
}
|
||
}
|
||
|
||
const int at = pic.find('@');
|
||
if (at > 0)
|
||
{
|
||
const int len = atoi(&pic[at+1]);
|
||
if (len > 0)
|
||
{
|
||
maxlen = len;
|
||
pic.cut(at);
|
||
}
|
||
}
|
||
|
||
s=n.string(pic); // riempi la stringa col valore pitturato
|
||
|
||
if (maxlen >= 0 && maxlen < s.size())
|
||
s.cut(maxlen);
|
||
if (!delim.empty_items()) // Aggiungi delimitatori
|
||
{
|
||
TString16 d(delim.get(0));
|
||
const int ld = d.len();
|
||
|
||
if (ld > 0) // Se il primo delimitatore e' valido ...
|
||
{
|
||
for (int spc = 0;s[spc]==' ' ; spc++) ;
|
||
if (spc < ld)
|
||
{
|
||
TString16 spazi;
|
||
spazi.spaces(ld - spc);
|
||
s.insert(spazi,0);
|
||
spc = ld;
|
||
}
|
||
s.overwrite(d,spc - ld);
|
||
}
|
||
d = delim.get();
|
||
if (d.not_empty()) // Se il secondo delimitatore e' valido ...
|
||
s << d; // ... aggiungilo alla fine
|
||
}
|
||
}
|
||
else s = n.string();
|
||
}
|
||
|
||
void TForm_number::set_picture(const char *p)
|
||
{
|
||
TForm_string::set_picture(p);
|
||
const int comma = picture().find(',');
|
||
if (comma > 0) set_decimals(picture().len() - comma -1);
|
||
}
|
||
|
||
const char* TForm_number::example() const
|
||
{
|
||
real n("123456789120.00"); n.round(2);
|
||
TString s;
|
||
apply_format(n,s);
|
||
return strcpy(__tmp_string, s);
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_date
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TForm_date : public TForm_string
|
||
{
|
||
TString16 _format;
|
||
|
||
protected:
|
||
virtual const char* class_name() const { return "DATA"; }
|
||
virtual bool read();
|
||
virtual bool set(const char*);
|
||
bool set(const TDate& d);
|
||
virtual bool parse_item(TScanner& scanner);
|
||
virtual void print_body(ostream& out) const;
|
||
|
||
virtual void print_on(TMask& m);
|
||
virtual void read_from(const TMask& m);
|
||
|
||
virtual bool read_from(const TRectype& rform);
|
||
virtual void print_on(TRectype& rform);
|
||
|
||
public:
|
||
|
||
virtual TObject* dup() const;
|
||
void set_format(const char* f) { _format = f; }
|
||
virtual bool edit(TMask& m);
|
||
virtual const char* example() const;
|
||
TForm_date(TPrint_section* section);
|
||
virtual ~TForm_date() {}
|
||
};
|
||
|
||
|
||
TForm_date::TForm_date(TPrint_section* section)
|
||
: TForm_string(section), _format("1444-")
|
||
{}
|
||
|
||
TObject* TForm_date::dup() const
|
||
{
|
||
TForm_date* fd = new TForm_date(_section);
|
||
copy_to_form_item(fd);
|
||
fd->_format = _format;
|
||
return fd;
|
||
}
|
||
|
||
bool TForm_date::read()
|
||
{
|
||
bool ok = TForm_string::read();
|
||
if (ok && !get()[0] && automagic())
|
||
set(printer().getdate());
|
||
return ok;
|
||
}
|
||
|
||
void TForm_date::print_body(ostream& out) const
|
||
{
|
||
TForm_string::print_body(out);
|
||
out << " FORMAT \"" << _format << "\"\n";
|
||
}
|
||
|
||
bool TForm_date::parse_item(TScanner& scanner)
|
||
{
|
||
if (scanner.key() == "FO")
|
||
{
|
||
_format = scanner.string();
|
||
return TRUE;
|
||
}
|
||
return TForm_string::parse_item(scanner);
|
||
}
|
||
|
||
bool TForm_date::read_from(const TRectype& prof)
|
||
{
|
||
bool changed = TForm_string::read_from(prof);
|
||
|
||
const TString& df = prof.get("DATEFORM");
|
||
if (df.not_empty() && df != _format)
|
||
{
|
||
_format = df;
|
||
changed = TRUE;
|
||
}
|
||
|
||
return changed;
|
||
}
|
||
|
||
void TForm_date::print_on(TRectype& prof)
|
||
{
|
||
TForm_string::print_on(prof);
|
||
prof.put("DATEFORM", _format);
|
||
}
|
||
|
||
|
||
bool TForm_date::set(const char* s)
|
||
{
|
||
const TDate da(s);
|
||
return set(da);
|
||
}
|
||
|
||
bool TForm_date::set(const TDate& da)
|
||
{
|
||
TFormatted_date d(da); d.set_format(_format);
|
||
TForm_string::set(d.string());
|
||
return TRUE;
|
||
}
|
||
|
||
void TForm_date::print_on(TMask& m)
|
||
{
|
||
const TDate dd(TODAY);
|
||
TFormatted_date d(dd); d.set_format(_format);
|
||
m.set(F_DEXAMPLE, d.string());
|
||
|
||
m.set(F_DFORMAT, _format.mid(0,1));
|
||
m.set(F_DDAY, _format.mid(1,1));
|
||
m.set(F_DMONTH, _format.mid(2,1));
|
||
m.set(F_DYEAR, _format.mid(3,1));
|
||
m.set(F_DSEP, _format.mid(4,1));
|
||
|
||
TForm_string::print_on(m);
|
||
}
|
||
|
||
void TForm_date::read_from(const TMask& m)
|
||
{
|
||
TForm_string::read_from(m);
|
||
|
||
// adjust format string
|
||
_format[0] = m.get(F_DFORMAT)[0];
|
||
_format[1] = m.get(F_DDAY )[0];
|
||
_format[2] = m.get(F_DMONTH )[0];
|
||
_format[3] = m.get(F_DYEAR )[0];
|
||
_format[4] = m.get(F_DSEP )[0];
|
||
_format[5] = '\0';
|
||
}
|
||
|
||
|
||
|
||
bool TForm_date::edit(TMask& m)
|
||
{
|
||
return TForm_string::edit(m);
|
||
}
|
||
|
||
const char* TForm_date::example() const
|
||
{
|
||
const TDate dd(TODAY);
|
||
TFormatted_date d(dd); d.set_format(_format);
|
||
TString s(d.string());
|
||
return strcpy(__tmp_string, s);
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_list
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TForm_list : public TForm_string
|
||
{
|
||
TToken_string _codes;
|
||
TToken_string _values;
|
||
|
||
protected:
|
||
virtual const char* class_name() const { return "LISTA"; }
|
||
virtual bool parse_item(TScanner& scanner);
|
||
virtual void print_on(TMask& m);
|
||
virtual void read_from(const TMask& m);
|
||
virtual void print_body(ostream& out) const;
|
||
virtual bool update();
|
||
|
||
public:
|
||
virtual TObject* dup() const;
|
||
TForm_list(TPrint_section* section);
|
||
virtual ~TForm_list() {}
|
||
};
|
||
|
||
TForm_list::TForm_list(TPrint_section* section)
|
||
: TForm_string(section)
|
||
{}
|
||
|
||
TObject* TForm_list::dup() const
|
||
{
|
||
TForm_list* fl = new TForm_list(_section);
|
||
copy_to_form_item(fl);
|
||
fl->_codes = _codes;
|
||
fl->_values = _values;
|
||
return fl;
|
||
}
|
||
|
||
bool TForm_list::parse_item(TScanner& scanner)
|
||
{
|
||
if (scanner.key() == "IT")
|
||
{
|
||
TToken_string s(scanner.string());
|
||
_codes.add(s.get());
|
||
_values.add(s.get());
|
||
|
||
while (scanner.popkey() == "ME")
|
||
{
|
||
TFixed_string m(scanner.line());
|
||
m.strip_spaces();
|
||
message(_values.items()-1).add(m);
|
||
}
|
||
scanner.push();
|
||
return TRUE;
|
||
}
|
||
|
||
return TForm_string::parse_item(scanner);
|
||
}
|
||
|
||
void TForm_list::print_on(TMask& m)
|
||
{
|
||
TForm_string::print_on(m);
|
||
TSheet_field& s = (TSheet_field&)m.field(F_ITEMS);
|
||
s.reset();
|
||
_codes.restart(); _values.restart();
|
||
for (int i = 0; i < _codes.items(); i++)
|
||
{
|
||
TToken_string& row = s.row(i);
|
||
row = _codes.get();
|
||
row.add(_values.get());
|
||
row.add(message(i));
|
||
}
|
||
// s.force_update();
|
||
}
|
||
|
||
void TForm_list::read_from(const TMask& m)
|
||
{
|
||
TForm_string::read_from(m);
|
||
|
||
TSheet_field& s = (TSheet_field&)m.field(F_ITEMS);
|
||
|
||
_codes = _values = "";
|
||
for (int i = 0; i < s.items(); i++)
|
||
{
|
||
TToken_string& row = s.row(i);
|
||
_codes.add(row.get(0));
|
||
_values.add(row.get());
|
||
message(i) = row.get();
|
||
}
|
||
}
|
||
|
||
void TForm_list::print_body(ostream& out) const
|
||
{
|
||
TForm_string::print_body(out);
|
||
|
||
TToken_string& cod = (TToken_string&)_codes; // Trick to skip const
|
||
TToken_string& val = (TToken_string&)_values;
|
||
|
||
int i = 0;
|
||
TString c(cod.get(0));
|
||
TString v(val.get(0));
|
||
|
||
for (; c[0]; c = cod.get(), v = val.get(), i++)
|
||
{
|
||
out << " ITEM \"" << c;
|
||
if (v.not_empty()) out << '|' << v;
|
||
out << '"';
|
||
|
||
const char* m = ((TForm_list*)this)->message(i);
|
||
if (*m) out << " MESSAGE " << m;
|
||
|
||
out << endl;
|
||
}
|
||
}
|
||
|
||
|
||
bool TForm_list::update()
|
||
{
|
||
bool ok = TRUE;
|
||
|
||
if (!read()) return ok;
|
||
|
||
const TString& val =get();
|
||
int pos = _codes.get_pos(val);
|
||
if (pos < 0)
|
||
{
|
||
TString def= _codes.get(0);
|
||
def.trim();
|
||
if (val == def) pos = 0; // Test default (first & empty) value
|
||
else
|
||
{
|
||
ok = yesno_box("Il campo '%s' non puo' valere '%s': continuare ugualmente",
|
||
(const char*)key(), (const char*)val);
|
||
set(_codes.get(pos = 0));
|
||
}
|
||
}
|
||
if (ok)
|
||
{
|
||
do_message(pos);
|
||
|
||
if (!hidden())
|
||
{
|
||
const char* c = _values.get(pos);
|
||
if (c == NULL) c = val;
|
||
if (c) string_at(x(), _y, c);
|
||
}
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_group
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TForm_group : public TForm_item
|
||
{
|
||
protected:
|
||
virtual const char* class_name() const { return "GRUPPO"; }
|
||
virtual bool update() { return TRUE; }
|
||
|
||
public:
|
||
TForm_group(TPrint_section* section) : TForm_item(section) {};
|
||
virtual ~TForm_group() {}
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TGraphic_section
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TGraphic_section : public TPrint_section
|
||
{
|
||
TString _back;
|
||
|
||
protected:
|
||
TForm_item* parse_item(const TString& s);
|
||
bool update();
|
||
|
||
public:
|
||
void append(const char* s) { _back << s; }
|
||
|
||
TGraphic_section(TForm* f, pagetype pt) : TPrint_section(f, 'G', pt) {}
|
||
virtual ~TGraphic_section() {}
|
||
};
|
||
|
||
class TForm_picture : public TForm_item
|
||
{
|
||
protected:
|
||
virtual const char* class_name() const { return "FIGURA"; }
|
||
virtual bool update();
|
||
|
||
public:
|
||
TForm_picture(TGraphic_section* section) : TForm_item(section) {}
|
||
virtual ~TForm_picture() {}
|
||
};
|
||
|
||
class TForm_line : public TForm_item
|
||
{
|
||
protected:
|
||
virtual const char* class_name() const { return "LINEA"; }
|
||
virtual bool update();
|
||
|
||
public:
|
||
TForm_line(TGraphic_section* section) : TForm_item(section) {}
|
||
virtual ~TForm_line() {}
|
||
};
|
||
|
||
class TForm_box : public TForm_item
|
||
{
|
||
protected:
|
||
virtual const char* class_name() const { return "BOX"; }
|
||
virtual bool update();
|
||
|
||
public:
|
||
TForm_box(TGraphic_section* section) : TForm_item(section) {}
|
||
virtual ~TForm_box() {}
|
||
};
|
||
|
||
bool TForm_picture::update()
|
||
{
|
||
const bool ok = _prompt.not_empty();
|
||
if (ok)
|
||
{
|
||
TString80 i;
|
||
i << "i{" << _prompt << ',' << _x << ',' << _y << ','
|
||
<< (_x+width()-1) << ',' << (_y+height()-1) << '}';
|
||
((TGraphic_section&)section()).append(i);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TForm_line::update()
|
||
{
|
||
int spessore = 1;
|
||
char codice = 'l';
|
||
for (int j = _prompt.len()-1; j >= 0; j--)
|
||
{
|
||
switch (_prompt[j])
|
||
{
|
||
case 'B':
|
||
case 'b':
|
||
spessore = 3; break;
|
||
case 'R':
|
||
case 'r':
|
||
codice = 'r'; break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
TString80 i;
|
||
i << 'W' << spessore << codice
|
||
<< '{' << _x << ',' << _y << ','
|
||
<< (_x+width()-1) << ',' << (_y+height()-1) << '}';
|
||
|
||
((TGraphic_section&)section()).append(i);
|
||
return TRUE;
|
||
}
|
||
|
||
bool TForm_box::update()
|
||
{
|
||
TString80 i;
|
||
const int w = _prompt[0] == '@' ? 3 : 1;
|
||
i << 'W' << w << "b{" << _x << ',' << _y << ','
|
||
<< (_x+width()-1) << ',' << (_y+height()-1) << '}';
|
||
|
||
((TGraphic_section&)section()).append(i);
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
TForm_item* TGraphic_section::parse_item(const TString& s)
|
||
{
|
||
if (s == "FI")
|
||
return new TForm_picture(this);
|
||
else if (s == "LI")
|
||
return new TForm_line(this);
|
||
else if (s == "BO")
|
||
return new TForm_box(this);
|
||
|
||
error_box("Campo di stampa non ammesso per lo sfondo: %s", (const char*)s);
|
||
return NULL;
|
||
}
|
||
|
||
bool TGraphic_section::update()
|
||
{
|
||
_back = "";
|
||
const bool ok = TPrint_section::update();
|
||
printer().setbackground(_back);
|
||
return ok;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TPrint_section
|
||
///////////////////////////////////////////////////////////
|
||
|
||
HIDDEN bool font_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_SPACE)
|
||
{
|
||
main_app().begin_wait();
|
||
|
||
const char* family = f.get();
|
||
const int MAXSIZES = 16;
|
||
long sizes[MAXSIZES];
|
||
BOOLEAN scalable;
|
||
const int num_sizes = (int)xvt_fmap_get_family_sizes(printer().get_printrcd(),
|
||
(char*)family, sizes, &scalable, MAXSIZES);
|
||
|
||
TToken_string pn1(80), pn2(80);
|
||
if (scalable)
|
||
{
|
||
for (int i = 4; i <= 32; i++)
|
||
{
|
||
pn1.add(i);
|
||
pn2.add(i);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (num_sizes > 0)
|
||
{
|
||
for (int i = 0; i < num_sizes; i++)
|
||
pn1.add(sizes[i]);
|
||
}
|
||
else pn1.add(printer().get_char_size());
|
||
pn2 = pn1;
|
||
}
|
||
TList_field& lst = (TList_field&)f.mask().field(F_SIZE);
|
||
lst.replace_items(pn1, pn2);
|
||
lst.set(format("%d",printer().get_char_size()));
|
||
|
||
main_app().end_wait();
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
TMask* TPrint_section::_msk = NULL;
|
||
|
||
|
||
TPrint_section::TPrint_section(TForm* f, char st, pagetype pt, bool sub)
|
||
: _height(0), _form(f), _sec_type(st), _page_type(pt), _dirty(FALSE),
|
||
_subsection(sub), _repeat_count(0), _ofspc(0), _ofsvr(0), _nfld(0), _temp(0),
|
||
_columnwise(FALSE)
|
||
{
|
||
reset_tabs();
|
||
}
|
||
|
||
TPrint_section::~TPrint_section()
|
||
{
|
||
if (_msk)
|
||
{
|
||
delete _msk;
|
||
_msk = NULL;
|
||
}
|
||
}
|
||
|
||
void TPrint_section::change_field(int n, TForm_item* f)
|
||
{
|
||
_item.add(f,n);
|
||
}
|
||
|
||
void TPrint_section::insert_field(int n, TForm_item* f)
|
||
{
|
||
_item.insert(f,n);
|
||
}
|
||
|
||
void TPrint_section::add_field(TForm_item* f)
|
||
{
|
||
_item.add(f);
|
||
}
|
||
|
||
const TPrint_section& TPrint_section::copy(const TPrint_section& ps)
|
||
{
|
||
_msk = ps._msk; _height = ps._height; _ofspc = ps._ofspc;
|
||
_ofsvr = ps._ofsvr; _nfld = ps._nfld; _dirty = ps._dirty;
|
||
_columnwise = ps._columnwise; _temp = ps._temp; _form = ps._form;
|
||
_sec_type = ps._sec_type; _page_type = ps._page_type; _subsection = ps._subsection;
|
||
_item = ps._item; _repeat_count = ps._repeat_count;
|
||
for (int i = 0; i < MAXCOLUMNS; i++) _tab[i] = ps._tab[i];
|
||
return ps;
|
||
}
|
||
|
||
TPrintrow& TPrint_section::row(int num)
|
||
{
|
||
TPrintrow* pr = (TPrintrow*)objptr(num);
|
||
if (pr == NULL)
|
||
{
|
||
pr = new TPrintrow;
|
||
add(pr, num);
|
||
}
|
||
return *pr;
|
||
}
|
||
|
||
void TPrint_section::reset_tabs()
|
||
{
|
||
for (int i = 0; i < MAXCOLUMNS; i++)
|
||
_tab[i] = -1;
|
||
}
|
||
|
||
int TPrint_section::tab(int col)
|
||
{
|
||
int ret = -1;
|
||
if (_columnwise)
|
||
{
|
||
if (_tab[0] == -1)
|
||
{
|
||
// compute column offset
|
||
_nfld = 0;
|
||
_tab[0] = 2;
|
||
short maxcolreached = 0;
|
||
for (word i = 0; i < fields(); i++)
|
||
{
|
||
if (field(i).shown())
|
||
{
|
||
CHECKD (field(i)._x < MAXCOLUMNS, "Colonna ammessa e non concessa: ", field(i)._x);
|
||
_tab[field(i)._x] = field(i)._width + 1; // one is for separation
|
||
if (field(i)._x > maxcolreached) maxcolreached = field(i)._x;
|
||
_nfld++;
|
||
}
|
||
}
|
||
// cumulate offsets
|
||
int last = 0;
|
||
for (i = 1; i <= (word)maxcolreached; i++)
|
||
{
|
||
if (_tab[i - 1] != -1)
|
||
last = i - 1;
|
||
if (_tab[i] != -1)
|
||
_tab[i] += _tab[last];
|
||
}
|
||
}
|
||
// se manca la colonna, vai a prendere quella immediatamente prima
|
||
while (_tab[col] == -1 && col > 0)
|
||
col--;
|
||
ret = _tab[col];
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
void TPrint_section::offset(int& x, int& y)
|
||
{
|
||
if (x >= 0)
|
||
{
|
||
if (_columnwise) x = tab(x-1) + _ofspc;
|
||
x += form().offset_x();
|
||
}
|
||
if (y >= 0) y += form().offset_y() + (_height * _repeat_count);
|
||
}
|
||
|
||
|
||
TForm_item* TPrint_section::parse_item(const TString& s)
|
||
{
|
||
if (s == "ST")
|
||
return new TForm_string(this);
|
||
if (s == "NU")
|
||
return new TForm_number(this);
|
||
if (s == "DA")
|
||
return new TForm_date(this);
|
||
if (s == "LI")
|
||
return new TForm_list(this);
|
||
if (s == "GR")
|
||
return new TForm_group(this);
|
||
if (s == "SE")
|
||
return new TForm_subsection(this);
|
||
|
||
yesnofatal_box("Campo di stampa non ammesso per la sezione di stampa: %s", (const char*)s);
|
||
return NULL;
|
||
}
|
||
|
||
|
||
TForm_item* TPrint_section::parse_item(TScanner& scanner)
|
||
{
|
||
return parse_item(scanner.key());
|
||
}
|
||
|
||
bool TPrint_section::parse(TScanner& scanner)
|
||
{
|
||
_height = scanner.integer();
|
||
scanner.integer();scanner.integer(); // Eat offset X and Y of Print_section if present
|
||
|
||
if (scanner.popkey() == "CO") // COLUMNWISE attribute
|
||
_columnwise = TRUE;
|
||
else
|
||
{
|
||
_columnwise = FALSE;
|
||
scanner.push();
|
||
}
|
||
|
||
while (scanner.popkey() != "EN")
|
||
{
|
||
TForm_item *fi = parse_item(scanner);
|
||
if (fi == NULL) return FALSE;
|
||
|
||
if (fi->parse(scanner))
|
||
_item.add(fi);
|
||
else
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// Azzera tutte le righe della sezione di stampa
|
||
void TPrint_section::reset()
|
||
{
|
||
for (int i = last(); i >= 0; i--)
|
||
row(i).reset();
|
||
}
|
||
|
||
// Aggiorna tutti i campi e li stampa
|
||
bool TPrint_section::update()
|
||
{
|
||
bool ok = TRUE;
|
||
|
||
reset();
|
||
for (word i = 0; i < fields(); i++)
|
||
{
|
||
const bool esito = field(i).update();
|
||
if (!esito) ok = FALSE;
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Legge dal record <p rec> altezza e offset prima colonna della sezione
|
||
//
|
||
// @rdesc Ritorna se i valori letti hanno modificato quelli attuali
|
||
bool TPrint_section::read_from(
|
||
const TRectype& prof) // @parm Record dal quela leggere i valori
|
||
|
||
// @comm Nel caso il record non sia LF_RFORM viene dato un messaggio di <f CHECK>.
|
||
{
|
||
CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
|
||
|
||
bool changed = FALSE;
|
||
const word h = (word)prof.get_int("HGT");
|
||
const word l = (word)prof.get_int("LEN");
|
||
const word y = (word)prof.get_int("Y");
|
||
if (_height != h)
|
||
{
|
||
_height = h;
|
||
changed = TRUE;
|
||
}
|
||
if (_ofspc != l)
|
||
{
|
||
_ofspc = l;
|
||
changed = TRUE;
|
||
}
|
||
if (_ofsvr != y)
|
||
{
|
||
_ofsvr = y;
|
||
changed = TRUE;
|
||
}
|
||
return changed;
|
||
}
|
||
|
||
void TPrint_section::print_on(TRectype& prof)
|
||
{
|
||
CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
|
||
prof.put("ID", 0);
|
||
prof.put("X", 0);
|
||
prof.put("Y", _ofsvr);
|
||
prof.put("LEN", _ofspc);
|
||
prof.put("HGT", _height);
|
||
}
|
||
|
||
typedef struct {
|
||
char name_1[80]; // Fontname old
|
||
char name_2[80]; // Fontname new
|
||
int size_1; // size (height) of old font
|
||
int size_2; // size (height) of new font
|
||
real ratio; // ratio (width_old_font/width_new_font)
|
||
} s_data;
|
||
|
||
BOOLEAN XVT_CALLCONV1 wpr (long data)
|
||
{
|
||
s_data* st =(s_data*)data;
|
||
WINDOW prwin = xvt_print_create_win(printer().get_printrcd(),"");
|
||
long width_old,width_new;
|
||
TString spc(100);
|
||
spc.fill('m');
|
||
xvt_set_font(prwin,st->name_1, XVT_FS_NONE, st->size_1);
|
||
width_old = xvt_dwin_get_text_width(prwin,(char*)(const char*)spc, 100);
|
||
xvt_set_font(prwin,st->name_2, XVT_FS_NONE, st->size_2);
|
||
width_new = xvt_dwin_get_text_width(prwin,(char*)(const char*)spc, 100);
|
||
st->ratio = (double)width_old / (double)width_new;
|
||
xvt_vobj_destroy(prwin);
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
bool TPrint_section::special_field_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE && _special_mask != NULL)
|
||
_special_mask->run();
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrint_section::repos_fields(const char* name, int size)
|
||
{
|
||
TPrint_section& ps = ::section();
|
||
bool rt = FALSE;
|
||
if (ps.form().fontname() != name ||
|
||
ps.form().fontsize() != size)
|
||
{
|
||
if (!ps.form().dirty()) ps.form().set_dirty();
|
||
ps.set_dirty();
|
||
if (yesno_box("E' stato cambiato il font o la dimensione del carattere.\nSi desidera aggiornare le coordinate dei campi?"))
|
||
{
|
||
rt = TRUE;
|
||
s_data prm;
|
||
prm.size_1=ps.form().fontsize();
|
||
strcpy(prm.name_1,ps.form().fontname());
|
||
prm.size_2=size;
|
||
strcpy(prm.name_2,name);
|
||
prm.ratio = 1.0;
|
||
// Next 3 lines may be changed
|
||
xvt_print_open();
|
||
xvt_print_start_thread (wpr, (long)&prm);
|
||
xvt_print_close();
|
||
|
||
if (ps.form().edit_level() > 1)
|
||
{
|
||
TMask rm("Rapporto tra i caratteri", 1, 30, 4);
|
||
rm.add_number(DLG_USER, 0, "Rapporto ", 1, 1, 8, "", 4);
|
||
rm.add_button(DLG_OK, 0, "Conferma", -12, -1, 10, 2);
|
||
rm.add_button(DLG_CANCEL, 0, "Annulla", -22, -1, 10, 2);
|
||
real ratio = prm.ratio;
|
||
rm.set(DLG_USER, ratio);
|
||
if (rm.run() == K_ENTER)
|
||
{
|
||
ratio = rm.get_real(DLG_USER);
|
||
prm.ratio = ratio;
|
||
}
|
||
}
|
||
|
||
const char sechar[4] = { 'B', 'F', 'G', 'H' };
|
||
for (int sn = 0; sn < 4 ; sn++)
|
||
{
|
||
const char sc = sechar[sn];
|
||
for (pagetype pt = odd_page; pt <= last_page; pt = pagetype(pt+1))
|
||
{
|
||
TPrint_section* sec = ps.form().exist(sc, pt);
|
||
if (sec != NULL && !sec->columnwise())
|
||
{
|
||
sec->set_dirty();
|
||
for (word i = 0; i < sec->fields() ; i++)
|
||
{
|
||
TForm_item& fi = sec->field(i);
|
||
short value = fi.x();
|
||
if (value > 0 && (prm.ratio != 1.0))
|
||
{
|
||
real x_pos;
|
||
x_pos = value * prm.ratio;
|
||
x_pos.round();
|
||
fi.set_x((short)x_pos.integer());
|
||
fi.set_dirty();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
ps.form().fontname() = name;
|
||
ps.form().fontsize() = size;
|
||
// Aggiorna lo spreadsheet
|
||
TSheet_field& ms = (TSheet_field&)ps._msk->field(F_FIELDS);
|
||
TToken_string tt(128);
|
||
const word flds = ps.fields();
|
||
for (word i = 0; i < flds; i++)
|
||
{
|
||
TForm_item& f = ps.field(i);
|
||
ps.field(i).print_on_sheet_row(tt);
|
||
ms.row(i) = tt;
|
||
}
|
||
}
|
||
return rt;
|
||
}
|
||
|
||
// handlers for section editing
|
||
bool TPrint_section::detail_field_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
|
||
if (_cur_form && TString(_cur_form->section_mask()).left(2) == "ba")
|
||
{
|
||
TString80 name(_msk->get(F_FONT));
|
||
int size = _msk->get_int(F_SIZE);
|
||
repos_fields(name, size);
|
||
}
|
||
|
||
bool consider_sheet_mask = FALSE;
|
||
if (f.mask().is_running()) // Se la maschera di editing dello sheet e' running
|
||
consider_sheet_mask = TRUE; // allora deve tener conto anche di essa per l'I/O
|
||
|
||
// to avoid kasinations with recursion
|
||
TPrint_section& section = ::section();
|
||
TSheet_field& ms = *f.mask().get_sheet();
|
||
int field = ms.selected();
|
||
TToken_string& tt = ms.row(field);
|
||
TToken_string tt_mask(tt);
|
||
if (consider_sheet_mask)
|
||
{
|
||
TMask& msheet = f.mask();
|
||
tt_mask.add(msheet.get(idt_id), idt_id - 101);
|
||
tt_mask.add(msheet.get(dsc_id), dsc_id - 101);
|
||
tt_mask.add(msheet.get(len_id), len_id - 101);
|
||
tt_mask.add(msheet.get(prn_id), prn_id - 101);
|
||
|
||
if (section.columnwise())
|
||
{
|
||
tt_mask.add(msheet.get(col_id), col_id - 101);
|
||
tt_mask.add(msheet.get(spc_id), spc_id -101);
|
||
tt_mask.add(msheet.get(int_id), int_id - 101);
|
||
tt_mask.add(msheet.get(fnl_id), fnl_id -101);
|
||
tt_mask.add(msheet.get(fnr_id), fnr_id -101);
|
||
}
|
||
else
|
||
{
|
||
tt_mask.add(msheet.get(xps_id), xps_id - 101);
|
||
tt_mask.add(msheet.get(yps_id), yps_id - 101);
|
||
}
|
||
}
|
||
|
||
TMask msk("ba2100f");
|
||
|
||
msk.set_handler(F_DFORMAT, dateformat_handler);
|
||
msk.set_handler(F_DYEAR, dateformat_handler);
|
||
msk.set_handler(F_DMONTH, dateformat_handler);
|
||
msk.set_handler(F_DDAY, dateformat_handler);
|
||
msk.set_handler(F_DSEP, dateformat_handler);
|
||
|
||
msk.set_handler(F_FILE1, but_file_handler);
|
||
msk.set_handler(F_FIELD1, but_field_handler);
|
||
msk.set_handler(F_FROM1, from_handler);
|
||
msk.set_handler(F_TO1, to_handler);
|
||
msk.set_handler(F_FILE2, but_file_handler);
|
||
msk.set_handler(F_FIELD2, but_field_handler);
|
||
msk.set_handler(F_FROM2, from_handler);
|
||
msk.set_handler(F_TO2, to_handler);
|
||
msk.set_handler(F_PICTURE,fmt_handler);
|
||
// TBI set_mode etc, vedi sotto
|
||
|
||
// gna'
|
||
TForm_item& fi = section.field(field);
|
||
|
||
msk.enable(F_OPTIONS, fi.special_items() > 3);
|
||
msk.enable(F_SPACES, section.columnwise());
|
||
msk.enable(F_FINKL, section.columnwise());
|
||
msk.enable(F_FINKR, section.columnwise());
|
||
|
||
// build option mask
|
||
if (fi.special_items() > 3)
|
||
{
|
||
msk.set_handler(F_OPTIONS, special_field_handler);
|
||
|
||
CHECK(fi.special_items() < 18, "Quanti special! Non ho nessuna voglia di "
|
||
" farti una maschera a piu' pagine. Ripensaci e riprova");
|
||
|
||
_special_mask = new TMask("Variabili personalizzate", 1, 78, fi.special_items() + 3);
|
||
_special_mask->add_button(DLG_OK, 0, "", -12, -1, 10, 2);
|
||
_special_mask->add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
|
||
fi.specials().restart();
|
||
|
||
for (int k = 0; k < fi.special_items(); k++)
|
||
{
|
||
THash_object* ho = fi.specials().get_hashobj();
|
||
TToken_string& tt = (TToken_string&)(ho->obj());
|
||
TString type = tt.get(0);
|
||
TString val = tt.get(1);
|
||
TToken_string des(tt.get(2),'/');
|
||
TString prompt(des.get(0));
|
||
|
||
if (type == "STRINGA")
|
||
{
|
||
_special_mask->add_string(101+k, 0, prompt, 1, k+1, des.get_int(1),"");
|
||
_special_mask->set(101+k, val);
|
||
}
|
||
else if (type == "NUMERO")
|
||
{
|
||
_special_mask->add_number(101+k, 0, prompt, 1, k+1, des.get_int(1),"",des.get_int(2));
|
||
_special_mask->set(101+k, val);
|
||
}
|
||
else if (type == "LISTA")
|
||
{
|
||
TToken_string codes(128);
|
||
TToken_string value(128);
|
||
|
||
for (int jj = 2; jj < des.items(); jj++)
|
||
{
|
||
CHECK (jj < (des.items() - 1), "AAARGH! 'Sta LISTA special e' fatta male");
|
||
TString t1(des.get(jj++));
|
||
TString t2(des.get(jj));
|
||
codes.add(t1);
|
||
value.add(t2);
|
||
}
|
||
|
||
_special_mask->add_list(101+k, 0, prompt, 1, k+1, des.get_int(1), "", codes, value);
|
||
_special_mask->set(101+k, val);
|
||
}
|
||
else if (type == "BOOLEAN")
|
||
{
|
||
_special_mask->add_boolean(101+k, 0, prompt, 1, k+1);
|
||
_special_mask->set(101+k, val);
|
||
}
|
||
else if (type == "DATA")
|
||
{
|
||
_special_mask->add_date(101+k, 0, prompt, 1, k+1);
|
||
_special_mask->set(101+k, val);
|
||
}
|
||
}
|
||
}
|
||
if (consider_sheet_mask)
|
||
fi.read_from(tt_mask);
|
||
else
|
||
fi.read_from(tt);
|
||
fi.edit(msk);
|
||
|
||
// check specials
|
||
if (_special_mask != NULL)
|
||
{
|
||
if (_special_mask->last_key() == K_ENTER)
|
||
{
|
||
fi.specials().restart();
|
||
|
||
for (int k = 0; k < fi.special_items(); k++)
|
||
{
|
||
THash_object* ho = fi.specials().get_hashobj();
|
||
TToken_string& tt = (TToken_string&)(ho->obj());
|
||
TString val = tt.get(1);
|
||
TString nvl = _special_mask->get(k + 101);
|
||
if (nvl != val)
|
||
{
|
||
tt.add(nvl, 1);
|
||
if (tt.items() == 3) tt.add("X");
|
||
fi.set_dirty();
|
||
}
|
||
}
|
||
}
|
||
|
||
if (_special_mask != NULL)
|
||
{
|
||
delete _special_mask;
|
||
_special_mask = NULL;
|
||
}
|
||
}
|
||
|
||
if (!consider_sheet_mask)
|
||
fi.print_on_sheet_row(tt);
|
||
else
|
||
{
|
||
TMask& msheet = f.mask();
|
||
fi.print_on_sheet_row(tt_mask);
|
||
msheet.set(idt_id, tt_mask.get_int(idt_id - 101));
|
||
msheet.set(dsc_id, tt_mask.get(dsc_id - 101));
|
||
msheet.set(len_id, tt_mask.get_int(len_id - 101));
|
||
msheet.set(prn_id, tt_mask.get(prn_id - 101));
|
||
msheet.set(frm_id, fi.example());
|
||
|
||
if (section.columnwise())
|
||
{
|
||
msheet.set(spc_id, tt_mask.get_int(spc_id - 101));
|
||
msheet.set(col_id, tt_mask.get_int(col_id - 101));
|
||
msheet.set(int_id, tt_mask.get(int_id - 101));
|
||
msheet.set(fnl_id, tt_mask.get(fnl_id - 101));
|
||
msheet.set(fnr_id, tt_mask.get(fnr_id - 101));
|
||
}
|
||
else
|
||
{
|
||
msheet.set(xps_id, tt_mask.get_int(xps_id - 101));
|
||
msheet.set(yps_id, tt_mask.get_int(yps_id - 101));
|
||
}
|
||
}
|
||
|
||
ms.force_update();
|
||
|
||
_cur_sect = §ion;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrint_section::detail_field_notify (TSheet_field& s, int r, KEY k)
|
||
{
|
||
TPrint_section& sec = ::section();
|
||
if (k == K_DEL || k == K_INS)
|
||
{
|
||
if (::form().edit_level() <= 1)
|
||
return FALSE;
|
||
if (k == K_DEL)
|
||
{
|
||
// elimina campo
|
||
sec.destroy_field(r);
|
||
sec.set_dirty();
|
||
}
|
||
}
|
||
else if (k == (K_INS + K_CTRL))
|
||
{
|
||
// new field: set defaults and create field
|
||
TForm_string* f = new TForm_string(&sec);
|
||
sec.insert_field(r, f);
|
||
TToken_string& tt = s.row(r);
|
||
f->print_on_sheet_row(tt);
|
||
tt.add("Nuovo campo", sec.columnwise() ? int_id : dsc_id);
|
||
if (sec.columnwise()) tt.add(r+1, col_id - 101);
|
||
s.force_update();
|
||
sec.set_dirty();
|
||
}
|
||
else if (k == K_ENTER)
|
||
{
|
||
// modify field
|
||
TForm_item* fld = &sec.field(r);
|
||
TToken_string& tt = s.row(r);
|
||
|
||
if (sec.columnwise() && ((word)tt.get_int(col_id - 101) <= 0 ||
|
||
(word)tt.get_int(col_id - 101) > sec.fields()))
|
||
{
|
||
warning_box("Numero di colonna non accettabile (deve essere da 1 a %u)", sec.fields());
|
||
return FALSE;
|
||
}
|
||
// ??? type changed ???
|
||
if (strcmp(tt.get(typ_id - 101), fld->class_name()) != 0)
|
||
{
|
||
// so'ccazzi: crea nuovo campo del tipo dato e
|
||
// copia gli special (e il resto)
|
||
TString typ(tt.get(typ_id - 101));
|
||
TForm_item* fff = NULL;
|
||
if (typ == "NUMERO")
|
||
fff = new TForm_number(&sec);
|
||
else if (typ == "STRINGA")
|
||
fff = new TForm_string(&sec);
|
||
else if (typ == "DATA")
|
||
fff = new TForm_date(&sec);
|
||
else if (typ == "LISTA")
|
||
fff = new TForm_list(&sec);
|
||
else if (typ == "GRUPPO")
|
||
fff = new TForm_group(&sec);
|
||
else if (typ == "LINEA")
|
||
fff = new TForm_line((TGraphic_section*)&sec);
|
||
else if (typ == "BOX")
|
||
fff = new TForm_box((TGraphic_section*)&sec);
|
||
else if (typ == "FIGURA")
|
||
fff = new TForm_picture((TGraphic_section*)&sec);
|
||
|
||
// copia SPECIALS
|
||
TAssoc_array& aa = fld->specials();
|
||
TAssoc_array& bb = fff->specials();
|
||
THash_object* oo = NULL;
|
||
aa.restart();
|
||
|
||
for (int i = 0; i < aa.items(); i++)
|
||
{
|
||
oo = aa.get_hashobj();
|
||
bb.add(oo->key(), oo->obj());
|
||
}
|
||
sec.change_field(r, fld = fff);
|
||
fld->set_dirty();
|
||
}
|
||
// modifica valori
|
||
fld->read_from(tt);
|
||
}
|
||
else
|
||
if (k == K_SPACE)
|
||
{
|
||
if (_cur_form && TString(_cur_form->section_mask()).left(2) == "ba")
|
||
{
|
||
TString80 name(s.mask().get(F_FONT));
|
||
int size = s.mask().get_int(F_SIZE);
|
||
if (repos_fields(name,size))
|
||
s.force_update();
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Esegue l'edit della sezione di stampa
|
||
//
|
||
// @rdesc Ritorna TRUE se e' stata modificata effettivamente
|
||
bool TPrint_section::edit(
|
||
const char* title) // @parm Titolo della maschera di edit
|
||
{
|
||
const bool is_ba_editor = TString(_form->section_mask()).left(2) == "ba";
|
||
bool nstd_dirty = FALSE;
|
||
bool font_found = FALSE;
|
||
|
||
_cur_form = _form;
|
||
_cur_sect = this;
|
||
|
||
if (!_subsection)
|
||
{
|
||
TMask m(_form->section_mask());
|
||
_msk = &m;
|
||
m.set_caption(title);
|
||
m.set(F_HEIGHT, _height);
|
||
m.set(F_OFSPC, _ofspc);
|
||
m.set(F_OFSVR, _ofsvr);
|
||
if (is_ba_editor)
|
||
{
|
||
m.set(F_X, form().offset_x());
|
||
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());
|
||
}
|
||
else
|
||
_form->pre_edit_checks(m,_cur_sect);
|
||
TSheet_field& ms = (TSheet_field&)m.field(F_FIELDS);
|
||
|
||
m.hide(F_OFSVR);//Offset verticale, per _columnwise. Non ancora usato.
|
||
if (_columnwise)
|
||
{
|
||
m.disable(F_HEIGHT);
|
||
ms.delete_column(xps_id); ms.sheet_mask().hide(xps_id);
|
||
ms.delete_column(yps_id); ms.sheet_mask().hide(yps_id);
|
||
}
|
||
else
|
||
{
|
||
m.hide(F_OFSPC);
|
||
ms.delete_column(int_id); ms.sheet_mask().hide(int_id);
|
||
ms.delete_column(col_id); ms.sheet_mask().hide(col_id);
|
||
ms.delete_column(spc_id); ms.sheet_mask().hide(spc_id);
|
||
ms.delete_column(fnl_id); ms.sheet_mask().hide(fnl_id);
|
||
ms.delete_column(fnr_id); ms.sheet_mask().hide(fnr_id);
|
||
}
|
||
|
||
ms.enable_column(frm_id - 101, FALSE);
|
||
|
||
if (form().edit_level() <= 1)
|
||
{
|
||
ms.enable_column(idt_id - 101, FALSE);
|
||
ms.enable_column(typ_id - 101, FALSE);
|
||
}
|
||
|
||
// handlers
|
||
ms.set_notify(detail_field_notify);
|
||
ms.sheet_mask().set_handler(100, detail_field_handler);
|
||
if (_form->edit_level()<=1) ms.sheet_mask().disable(DLG_DELREC);
|
||
|
||
TToken_string tt(128);
|
||
const word flds = fields();
|
||
|
||
// fill sheet
|
||
for (word i = 0; i < flds; i++)
|
||
{
|
||
TForm_item& f = field(i);
|
||
field(i).print_on_sheet_row(tt);
|
||
// TBI colorare se specials (e vedi se colorare solo se non standard)
|
||
ms.row(-1) = tt;
|
||
}
|
||
|
||
if (is_ba_editor)
|
||
{
|
||
const int MAX_FAMILIES = 128;
|
||
char* family[MAX_FAMILIES];
|
||
const int num_families = (int)xvt_fmap_get_families(printer().get_printrcd(), family, MAX_FAMILIES);
|
||
TToken_string pn1(256), pn2(256);
|
||
|
||
for (int i = 0; i < num_families; i++)
|
||
{
|
||
pn1.add(family[i]);
|
||
pn2.add(family[i]);
|
||
if (!font_found)
|
||
if (form().fontname() == family[i]) font_found = TRUE;
|
||
xvt_mem_free(family[i]);
|
||
}
|
||
TList_field& lst = (TList_field&)m.field(F_FONT);
|
||
if (!font_found)
|
||
{
|
||
warning_box("Il font %s non esiste per la stampante di default.",(const char*) form().fontname());
|
||
pn1.add(form().fontname());
|
||
pn2.add(form().fontname());
|
||
}
|
||
lst.replace_items(pn1, pn2);
|
||
lst.set(form().fontname());
|
||
printer().set_char_size(form().fontsize());
|
||
m.set_handler(F_FONT,font_handler);
|
||
}
|
||
|
||
if(_columnwise)
|
||
{
|
||
bool ok = FALSE;
|
||
while (m.run() != K_ESC)
|
||
{
|
||
TSheet_field& ms = (TSheet_field&)m.field(F_FIELDS);
|
||
const int items = ms.items();
|
||
for (int i=0; i<items && !ok; i++)
|
||
{
|
||
TToken_string& tt = ms.row(i);
|
||
ok = tt.get_char(prn_id - 101)==' ';
|
||
}
|
||
if (i==items && !ok) error_box("Selezionare almeno una colonna stampabile.");
|
||
if (ok) break;
|
||
}
|
||
_msk = NULL;
|
||
if (!ok) return FALSE;
|
||
}
|
||
else
|
||
if (m.run() == K_ESC)
|
||
{
|
||
// Se premo Annulla ed il form e' nuovo lo devo cancellare.
|
||
if (form()._isnew)
|
||
{
|
||
TLocalisamfile frm(LF_FORM);
|
||
frm.zero();
|
||
frm.put("TIPOPROF",form().name());
|
||
frm.put("CODPROF",form().code());
|
||
frm.remove();
|
||
}
|
||
_msk = NULL;
|
||
return FALSE;
|
||
}
|
||
|
||
bool dirty = m.dirty() != 0;
|
||
|
||
if (dirty)
|
||
{
|
||
// Controlli da fare sempre a prescindere dal form editor
|
||
if (_height != (word)m.get_int(F_HEIGHT) )
|
||
{
|
||
_height = m.get_int(F_HEIGHT);
|
||
_dirty=TRUE;
|
||
}
|
||
if (_ofspc != (word)m.get_int(F_OFSPC) )
|
||
{
|
||
_ofspc = m.get_int(F_OFSPC);
|
||
_dirty=TRUE;
|
||
}
|
||
if (_ofsvr != (word)m.get_int(F_OFSVR) )
|
||
{
|
||
_ofsvr = m.get_int(F_OFSVR);
|
||
_dirty=TRUE;
|
||
}
|
||
if (is_ba_editor)
|
||
{ // Controlli solo se il form editor e' quello base
|
||
if (m.get_int(F_X) != form().offset_x() || m.get_int(F_Y) != form().offset_y())
|
||
{
|
||
form().offset_x() = m.get_int(F_X);
|
||
form().offset_y() = m.get_int(F_Y);
|
||
form().set_dirty();
|
||
_dirty = TRUE;
|
||
}
|
||
if (m.get(F_CTP)[0] != form().char_to_pos() ||
|
||
m.get_int(F_IPX) != form().ipx() ||
|
||
m.get_int(F_IPY) != form().ipy() ||
|
||
m.get_int(F_IPX) != form().fpx())
|
||
{
|
||
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));
|
||
int size = m.get_int(F_SIZE);
|
||
repos_fields(name,size);
|
||
} else // controlli se l'editor non e' quello base
|
||
nstd_dirty = _form->post_edit_checks(m,_cur_sect);
|
||
}
|
||
_msk = NULL;
|
||
}
|
||
|
||
if (is_ba_editor)
|
||
if (form()._isnew || (_dirty && yesno_box("Dati generali modificati. Salvare?")))
|
||
{
|
||
TLocalisamfile frm(LF_FORM);
|
||
frm.zero();
|
||
frm.put("TIPOPROF",form().name());
|
||
frm.put("CODPROF",form().code());
|
||
if (frm.read(_isequal,_lock) == NOERR)
|
||
{
|
||
frm.put("OFFY",form().offset_y());
|
||
frm.put("OFFX",form().offset_x());
|
||
frm.put("FONTNAME",form().fontname());
|
||
frm.put("FONTSIZE",form().fontsize());
|
||
frm.put("CTP",form().char_to_pos());
|
||
frm.put("IPX", form().ipx());
|
||
frm.put("IPY", form().ipy());
|
||
frm.put("FPX", form().fpx());
|
||
frm.rewrite();
|
||
_dirty = FALSE;
|
||
}
|
||
}
|
||
|
||
if (!_dirty)
|
||
for (word j = 0; j < fields(); j++)
|
||
_dirty |= field(j).dirty();
|
||
|
||
set_dirty(_dirty);
|
||
return (_dirty || nstd_dirty);
|
||
}
|
||
|
||
void TPrint_section::print_on(ostream& out) const
|
||
{
|
||
out << ' ';
|
||
switch (page_type())
|
||
{
|
||
case even_page:
|
||
out << "EVEN"; break;
|
||
case first_page:
|
||
out << "FIRST"; break;
|
||
case last_page:
|
||
out << "LAST"; break;
|
||
default:
|
||
out << "ODD"; break;
|
||
}
|
||
out << ' ' << _height;
|
||
if (_columnwise) out << " COLUMNWISE";
|
||
out << endl << endl;
|
||
for(word i = 0; i < fields(); i++)
|
||
if (!field(i).temp()) out << field(i);
|
||
}
|
||
|
||
TForm_item& TPrint_section::find_field(short id) const
|
||
{
|
||
for(word i = 0; i < fields(); i++)
|
||
{
|
||
TForm_item& f = field(i);
|
||
if (f.id() == id) return f;
|
||
}
|
||
yesnofatal_box("Can't find item with id %d", id);
|
||
return field(0);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TForm_editor& TForm::editor() const
|
||
{ return (TForm_editor&)main_app(); }
|
||
|
||
bool TForm::parse_use(TScanner& scanner)
|
||
{
|
||
const int logicnum = scanner.integer();
|
||
const char* tab = NULL;
|
||
|
||
if (logicnum > 0)
|
||
_relation = new TRelation(logicnum);
|
||
else
|
||
{
|
||
tab = scanner.pop();
|
||
_relation = new TRelation(tab);
|
||
}
|
||
|
||
int key = 1;
|
||
if (scanner.popkey() == "KE")
|
||
key = scanner.integer();
|
||
else
|
||
scanner.push();
|
||
|
||
_cursor = new TCursor(_relation, "", key);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
bool TForm::parse_join(TScanner& scanner)
|
||
{
|
||
TString16 j(scanner.pop()); // File or table
|
||
|
||
int to = 0;
|
||
if (scanner.popkey() == "TO") // TO keyword
|
||
{
|
||
const char* n = scanner.pop();
|
||
to = name2log(n);
|
||
}
|
||
else scanner.push();
|
||
|
||
int key = 1;
|
||
if (scanner.popkey() == "KE")
|
||
key = scanner.integer();
|
||
else scanner.push();
|
||
|
||
int alias = 0;
|
||
if (scanner.popkey() == "AL")
|
||
alias = scanner.integer();
|
||
else scanner.push();
|
||
|
||
TToken_string exp(80);
|
||
if (scanner.pop() == "INTO")
|
||
{
|
||
const char* r = scanner.pop();
|
||
while (strchr(r, '=') != NULL)
|
||
{
|
||
exp.add(r);
|
||
r = scanner.pop();
|
||
}
|
||
}
|
||
if (exp.empty())
|
||
yesnofatal_box("JOIN senza espressioni INTO");
|
||
scanner.push();
|
||
|
||
if (isdigit(j[0]))
|
||
_relation->add(atoi(j), exp, key, to, alias); // join file
|
||
else
|
||
_relation->add(j, exp, key, to, alias); // join table
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
TRelation_description& TForm::rel_desc() const
|
||
{
|
||
CHECK(_rel_desc, "No relation description");
|
||
return *_rel_desc;
|
||
}
|
||
|
||
bool TForm::parse_description(TScanner& scanner)
|
||
{
|
||
if (edit_level() > 0)
|
||
{
|
||
CHECK(_rel_desc == NULL, "Can't parse descriptions two times");
|
||
_rel_desc = new TRelation_description(*_relation);
|
||
}
|
||
|
||
bool ok = scanner.popkey() == "DE";
|
||
if (ok)
|
||
{
|
||
if (edit_level() > 0)
|
||
{
|
||
scanner.popkey(); // eat BEGIN
|
||
TFieldref fld;
|
||
while (scanner.pop() != "END")
|
||
{
|
||
fld = scanner.token();
|
||
_rel_desc->set_cur_file(fld.file());
|
||
if (fld.name() == "*")
|
||
_rel_desc->file_desc(scanner.string());
|
||
else
|
||
_rel_desc->set_field_description(fld.name(), scanner.string());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
while (scanner.line() != "END");
|
||
ok = FALSE;
|
||
}
|
||
}
|
||
else scanner.push();
|
||
|
||
return ok;
|
||
}
|
||
|
||
void TForm::print_description(ostream& out) const
|
||
{
|
||
out << "DESCRIPTION\nBEGIN\n";
|
||
out << rel_desc();
|
||
out << "END\n" << endl;
|
||
}
|
||
|
||
bool TForm::parse_general(TScanner &scanner)
|
||
{
|
||
bool ok = scanner.popkey() == "GE";
|
||
if (ok)
|
||
{
|
||
while (scanner.pop() != "END")
|
||
{
|
||
if (scanner.key() == "OF") // Offsets
|
||
{
|
||
_x = scanner.integer();
|
||
_y = scanner.integer();
|
||
}
|
||
if (scanner.key() == "FO") // Font name
|
||
_fontname = scanner.string();
|
||
if (scanner.key() == "SI") // Font size
|
||
_fontsize = scanner.integer();
|
||
if (scanner.key() == "CA") // Carattere di posizionamento
|
||
_char_to_pos = scanner.string()[0];
|
||
if (scanner.key() == "IN") // Riga e colonna del posizionamento iniziale
|
||
{
|
||
_ipx = scanner.integer();
|
||
_ipy = scanner.integer();
|
||
}
|
||
if (scanner.key() == "FI") // Riga e colonna del posizionamento finale
|
||
_fpx = scanner.integer();
|
||
|
||
if (scanner.key() == "GR") // Carattere di posizionamento
|
||
set_fincatura(scanner.string());
|
||
|
||
extended_parse_general(scanner); // Parse non-standard parameters
|
||
}
|
||
} else scanner.push();
|
||
|
||
return (ok);
|
||
}
|
||
|
||
void TForm::print_general(ostream& out) const
|
||
{
|
||
out << "GENERAL\nBEGIN\n";
|
||
out << " OFFSET " << _x << " " << _y << "\n";
|
||
out << " FONT " << "\"" << _fontname << "\"\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 << " GRID \"" << _fink << "\"\n";
|
||
out << "END\n" << endl;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Controlla se esiste una sezione di stampa
|
||
//
|
||
// @rdesc Ritorna la <c TPrint_section> trovata o creata
|
||
TPrint_section* TForm::exist(
|
||
char s, // @parm Indica in quale parte deve cercare:
|
||
//
|
||
// @flag F | Tra i footers
|
||
// @flag G | Tra gli sfondi
|
||
// @flag H | Tra gli headers
|
||
// @flag B | Tra i bodies (default)
|
||
pagetype t, // @parm Tipo di pagina (vedi <t pagetype>)
|
||
bool create) // @parm Indica se creare la sezione nel caso non esista
|
||
{
|
||
TArray* a;
|
||
switch (toupper(s))
|
||
{
|
||
case 'F':
|
||
a = &_foot; break;
|
||
case 'G':
|
||
a = &_back; break;
|
||
case 'H':
|
||
a = &_head; break;
|
||
default:
|
||
a = &_body; break;
|
||
}
|
||
|
||
TPrint_section* sec = (TPrint_section*)a->objptr(t);
|
||
if (sec == NULL && create)
|
||
{
|
||
sec = (s == 'G') ? new TGraphic_section(this, t) : new TPrint_section(this, s, t);
|
||
a->add(sec, t);
|
||
}
|
||
|
||
return sec;
|
||
}
|
||
|
||
TForm_item& TForm::find_field(char s, pagetype t, short id) const
|
||
{
|
||
const TPrint_section* ps = ((TForm*)this)->exist(s, t);
|
||
CHECKD(ps, "Can't find section for field ", id);
|
||
return ps->find_field(id);
|
||
}
|
||
|
||
TPrint_section& TForm::section(char s, pagetype pos)
|
||
{
|
||
TPrint_section* sec = exist(s, pos, TRUE);
|
||
return *sec;
|
||
}
|
||
|
||
TPrint_section& TForm::section(char s, word pagenum)
|
||
{
|
||
pagetype pt = odd_page;
|
||
if (pagenum == 0 && exist(s, last_page))
|
||
pt = last_page;
|
||
if (pagenum == 1 && exist(s, first_page))
|
||
pt = first_page;
|
||
if (pt == odd_page && (pagenum & 0x1) == 0 && exist(s, even_page))
|
||
pt = even_page;
|
||
|
||
return section(s, pt);
|
||
}
|
||
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Rilegge la sezione specificata
|
||
//
|
||
// @rdesc Ritorna se ce l'ha fatta
|
||
bool TForm::reread(
|
||
char sec, // @parm Sezione da rileggere
|
||
pagetype p, // @parm Posizione della pagina
|
||
bool force) // @parm Forza rilettura anche se nessun campo e' cambiato
|
||
{
|
||
TPrint_section* s = exist(sec,p);
|
||
bool ok = force;
|
||
if (s != NULL)
|
||
for (word j = 0; j < s->fields(); j++)
|
||
ok |= s->field(j).dirty();
|
||
if (s != NULL && ok)
|
||
{
|
||
s->destroy_fields(); // Distrugge tutti gli items...
|
||
// ...si posiziona nel file sorgente alla sezione opportuna...
|
||
TFilename n(_name); n.ext("frm");
|
||
TScanner scanner(n);
|
||
bool ok = FALSE;
|
||
while (!ok)
|
||
{
|
||
while (TRUE) // ...scans searching for a section...
|
||
{
|
||
const TString& key = scanner.popkey();
|
||
if (key == "SE" || key == "") // ..if section or end of file...
|
||
break;
|
||
}
|
||
const char secr = scanner.popkey()[0]; // Section name (GRAPH, HEAD, BODY, FOOT)
|
||
if (secr=='\0') break;
|
||
const pagetype pr = char2page(scanner.popkey()[0]); // Section type (odd, even, first, last)
|
||
if (secr==sec && pr==p) ok = TRUE; // L'ha trovata...
|
||
}
|
||
// ...riesegue la parse della sezione leggendo dal file sorgente
|
||
if(ok && s->parse(scanner))
|
||
{
|
||
// Legge le modifiche su archivio e poi e' finita.
|
||
s->set_dirty(FALSE);
|
||
TLocalisamfile rprof(LF_RFORM);
|
||
const char sez[3] = {sec,p+'0','\0'};
|
||
rprof.zero();
|
||
rprof.put("TIPOPROF", _name);
|
||
rprof.put("CODPROF", _code);
|
||
rprof.put("SEZ", sez);
|
||
const TRectype filter(rprof.curr());
|
||
|
||
for (int err = rprof.read(_isgteq); err == NOERR && rprof.curr() == filter; err = rprof.next())
|
||
{
|
||
const short id = rprof.get_int("ID");
|
||
|
||
if (id == 0)
|
||
{
|
||
TPrint_section& se = section(sec, p);
|
||
se.read_from(rprof.curr());
|
||
}
|
||
else
|
||
{
|
||
TForm_item& item = find_field(sec, p, id);
|
||
item.read_from(rprof.curr());
|
||
}
|
||
}
|
||
set_compulsory_specials();
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Cambia il formato di tutte le date nel form
|
||
//
|
||
// @rdesc Ritorna sempre TRUE
|
||
bool TForm::ps_change_date_format(
|
||
TPrint_section& s, // @parm Sezione nella quale modificare le date
|
||
const char* f) // @parm Nuovo formato delle date
|
||
|
||
// @comm Ha le stesse funzioni di <mf TForm::change_date_format>, ma per <c TPrint_section>,
|
||
// all'uopo di chiamarla con ricorsiva insistenza
|
||
|
||
{
|
||
for (word i = 0; i < s.fields(); i++)
|
||
{
|
||
TForm_item& fi = s.field(i);
|
||
if (strcmp(fi.class_name(), "SEZIONE") == 0)
|
||
{
|
||
TPrint_section& ps = ((TForm_subsection&)fi).subsection();
|
||
ps_change_date_format(ps, f);
|
||
}
|
||
else if (strcmp(fi.class_name(), "DATA") == 0)
|
||
{
|
||
((TForm_date&)fi).set_format(f);
|
||
if (!s.dirty()) s.set_dirty();
|
||
if (!fi.dirty()) fi.set_dirty();
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Cambia il formato di tutti i numeri nel form
|
||
//
|
||
// @rdesc Ritorna sempre TRUE
|
||
bool TForm::ps_change_number_format(
|
||
TPrint_section& s, // @parm Sezione nella quale modificare i numeri
|
||
int w, // @parm Dimensione massima del fomato numerico
|
||
int dec, // @parm Numero di decimali
|
||
const char* p) // @parm Picture del nuovo formato
|
||
|
||
// @comm Ha le stesse funzioni di <mf TForm::change_number_format>, ma per <c TPrint_section>,
|
||
// all'uopo di chiamarla con ricorsiva insistenza
|
||
{
|
||
for (word i = 0; i < s.fields(); i++)
|
||
{
|
||
TForm_item& fi = s.field(i);
|
||
if (strcmp(fi.class_name(), "SEZIONE") == 0)
|
||
{
|
||
TPrint_section& ps = ((TForm_subsection&)fi).subsection();
|
||
ps_change_number_format(ps, w, dec, p);
|
||
}
|
||
else if (strcmp(fi.class_name(), "NUMERO") == 0)
|
||
{
|
||
TForm_number& fn = (TForm_number&)fi;
|
||
fn.width() = w;
|
||
fn.set_decimals(dec);
|
||
fn.set_picture(p);
|
||
if (!s.dirty()) s.set_dirty();
|
||
if (!fn.dirty()) fn.set_dirty();
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
void TForm::change_date_format(const char* f)
|
||
{
|
||
char secs[] = { "FHGB" };
|
||
char ptyp[] = { "LOEF" };
|
||
TPrint_section* ps;
|
||
|
||
for (int sc = 0; sc < 4; sc++)
|
||
for (int pt = 0; pt < 4; pt++)
|
||
if ((ps = exist(secs[sc], char2page(ptyp[pt]), FALSE)) != NULL)
|
||
ps_change_date_format(*ps, f);
|
||
}
|
||
|
||
void TForm::change_number_format(int w, int dec, const char* p)
|
||
{
|
||
char secs[] = { "FHGB" };
|
||
char ptyp[] = { "LOEF" };
|
||
TPrint_section* ps;
|
||
|
||
for (int sc = 0; sc < 4; sc++)
|
||
for (int pt = 0; pt < 4; pt++)
|
||
if ((ps = exist(secs[sc], char2page(ptyp[pt]), FALSE)) != NULL)
|
||
ps_change_number_format(*ps, w, dec, p);
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Effettua l'update della sezione grafica background
|
||
//
|
||
// @rdesc Ritorna la lunghezza della pagina da stampare
|
||
word TForm::set_background(
|
||
word p, // @parm Numero pagina
|
||
bool u) // @parm Indica se aggiornare lo sfondo nella stampante corrente
|
||
|
||
// @xref <mf TForm::set_header> <mf TForm::set_body> <mf TForm::set_footer>
|
||
{
|
||
word len = 0;
|
||
|
||
if (u && _back.items())
|
||
{
|
||
TPrint_section& graph = section('G', p);
|
||
graph.update();
|
||
len = printer().formlen();
|
||
}
|
||
|
||
return len;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Effettua l'update della sezione header
|
||
//
|
||
// @rdesc Ritorna l'altezza dell'header settato
|
||
word TForm::set_header(
|
||
word p, // @parm Numero pagina
|
||
bool u) // @parm Indica se cambiare l'eventuale header corrente!!!
|
||
|
||
// @xref <mf TForm::set_background> <mf TForm::set_body> <mf TForm::set_footer>
|
||
{
|
||
TPrinter& pr = printer();
|
||
pr.resetheader();
|
||
|
||
TPrint_section& head = section('H', p);
|
||
|
||
if (u) head.update();
|
||
else
|
||
{
|
||
head.reset();
|
||
pr.headerlen(head.height());
|
||
}
|
||
|
||
for (word j = 0; j < head.height(); j++)
|
||
pr.setheaderline(j, head.row(j));
|
||
|
||
return head.height();
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Effettua l'update della sezione body
|
||
//
|
||
// @rdesc Ritorna l'altezza del body settato
|
||
word TForm::set_body(
|
||
word p, // @parm Numero pagina
|
||
bool u) // @parm Indica se cambiare l'eventuale body corrente!!!
|
||
|
||
// @xref <mf TForm::set_background> <mf TForm::set_header> <mf TForm::set_footer>
|
||
|
||
{
|
||
TPrint_section& body = section('B', p);
|
||
|
||
if (u) body.update();
|
||
else body.reset();
|
||
|
||
if (u)
|
||
{
|
||
TPrinter& pr = printer();
|
||
for (word j = 0; j < body.height(); j++)
|
||
pr.print(body.row(j));
|
||
}
|
||
|
||
return body.height();
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Effettua l'update della sezione footer
|
||
//
|
||
// @rdesc Ritorna l'altezza del footer settato
|
||
word TForm::set_footer(
|
||
word p, // @parm Numero pagina
|
||
bool u) // @parm Indica se cambiare l'eventuale footer corrente!!!
|
||
|
||
// @xref <mf TForm::set_background> <mf TForm::set_header> <mf TForm::set_body>
|
||
|
||
{
|
||
TPrinter& pr = printer();
|
||
pr.resetfooter();
|
||
|
||
TPrint_section& foot = section('F', p);
|
||
|
||
if (u) foot.update();
|
||
else
|
||
{
|
||
foot.reset();
|
||
pr.footerlen(foot.height());
|
||
}
|
||
|
||
for (word j = 0; j < foot.height(); j++)
|
||
pr.setfooterline(j, foot.row(j));
|
||
|
||
return foot.height();
|
||
}
|
||
|
||
void TForm::header_handler(TPrinter& p)
|
||
{
|
||
const word page = form().page(p);
|
||
form().set_background(page, TRUE);
|
||
form().set_header(page, TRUE);
|
||
form().set_footer(page, FALSE);
|
||
}
|
||
|
||
void TForm::footer_handler(TPrinter& p)
|
||
{
|
||
const word page = form().page(p);
|
||
form().set_footer(page, TRUE);
|
||
if (page)
|
||
form().set_header(page+1, FALSE);
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Ritorna il numero di pagina correntemente in stampa
|
||
//
|
||
// @rdesc Se <md _TForm::lastpage> e' TRUE (sta stampando l'ultima pagina)
|
||
// ritorna 0, altrimenti ritorna il numero della pagian corrente da stampare
|
||
// (chiam <mf TPrinter::getcurrentepage>).
|
||
word TForm::page(
|
||
const TPrinter& p) const // @parm Operazione corrente di stampa
|
||
{
|
||
return _lastpage ? 0 : p.getcurrentpage();
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Effettua il posizionamento manuale del modulo
|
||
void TForm::arrange_form()
|
||
|
||
// @comm 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.
|
||
// <nl>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!.
|
||
// <nl>Quindi, per ovviare a tutto cio, visto che <mf 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;
|
||
TMask m("ba2100c");
|
||
|
||
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
|
||
/*
|
||
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...
|
||
*/
|
||
#else
|
||
TString device(printer.printername());
|
||
FILE* lpt = fopen(device,"w");
|
||
|
||
if (lpt == NULL)
|
||
fatal_box("Impossibile aprire il device %s.",device);
|
||
#endif
|
||
|
||
// _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";
|
||
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
|
||
SpoolRow((char *) (const char *) str_pos, str_pos.len());
|
||
#else
|
||
|
||
fprintf(lpt,"%s",(const char*) str_pos);
|
||
fflush(lpt); // Salta le righe...
|
||
fclose(lpt);
|
||
#endif
|
||
str_pos = ""; //Azzera la stringa di posizionamento
|
||
for (i=1; i < _ipx; i++) str_pos << " "; //Aggiunge gli spazi necessari...
|
||
if (_ipx > 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
|
||
str_pos << '\r';
|
||
// TString bspc; bspc.fill('\b',str_pos.len()); // Questi servono per tornare indietro...
|
||
do
|
||
{
|
||
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
|
||
SpoolRow((char *)(const char *) str_pos, str_pos.len());
|
||
#else
|
||
lpt = fopen(device,"w");
|
||
if (lpt == NULL) fatal_box("Impossibile aprire il device %s.",device);
|
||
// fprintf(lpt,"%s",(const char*) bspc);
|
||
fprintf(lpt,"%s\r",(const char*) str_pos);
|
||
fflush(lpt);
|
||
fclose(lpt);
|
||
#endif
|
||
} 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";
|
||
lpt = fopen(device,"w");
|
||
if (lpt == NULL) fatal_box("Non rieso ad aprire il device %s.",device);
|
||
fprintf(lpt, "%s", (const char*) str_pos); // Salta tante righe quanto e' lungo il form standard
|
||
fclose (lpt); */
|
||
printer().set_offset(-(_ipy-1), printer().get_column_offset());
|
||
}
|
||
|
||
long TForm::records() const
|
||
{
|
||
const long r = cursor() ? cursor()->items() : 0;
|
||
return r;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Genera automaticamente la sezione grafica con colonne fincate
|
||
//
|
||
// @rdesc Ritorna FALSE se non c'e' il body per quella pagina
|
||
bool TForm::genera_fincatura(
|
||
pagetype p, // @parm Posizione della pagina (vedi <t pagetype>)
|
||
int y1, // @parm Prima y per le righe verticali
|
||
int y2, // @parm Ultima y per le righe verticali
|
||
const int* rows) // @parm Array di posizioni riga con 0 per finire
|
||
|
||
|
||
{
|
||
TPrint_section* body = exist('B', p);
|
||
if (body == NULL) return FALSE;
|
||
|
||
body->reset_tabs();
|
||
|
||
bool istemp = exist('G', p) == NULL;
|
||
|
||
TGraphic_section* grs = (TGraphic_section*)exist('G', p, TRUE);
|
||
grs->temp() = istemp;
|
||
|
||
int j = 0, start = 999, end = 0, wlast = 0;
|
||
int cols[MAXCOLUMNS];
|
||
|
||
for (word k = grs->fields(); k > 0; k--)
|
||
if (grs->field(k-1).temp())
|
||
grs->destroy_field(k-1);
|
||
|
||
for (int i = 0; i < (int)body->fields(); i++)
|
||
{
|
||
TForm_item& f = body->field(i);
|
||
if (!f.shown()) continue;
|
||
|
||
int x = f.x();
|
||
|
||
if (x < start) start = x;
|
||
if (x > end) { end = x; wlast = f.width(); }
|
||
cols[j++] = f.finkl() ? -x : x;
|
||
}
|
||
|
||
// inner lines
|
||
for (i = 0; i < j; i++)
|
||
{
|
||
if (cols[i] != start && cols[i] > 0)
|
||
{
|
||
TForm_line* l = new TForm_line(grs);
|
||
l->set_x(cols[i]-1);
|
||
l->y() = (word)y1;
|
||
l->id() = -1;
|
||
l->width() = 1;
|
||
l->height() = (int)(y2 - y1 + 1);
|
||
l->set("@R");
|
||
l->temp() = TRUE;
|
||
grs->add_field(l);
|
||
}
|
||
}
|
||
|
||
// box around
|
||
if (start != 999 && end != 0)
|
||
{
|
||
TForm_box* l = new TForm_box(grs);
|
||
l->set_x(start-1);
|
||
l->y() = (word)y1;
|
||
l->id() = -1;
|
||
l->width() = (int)(end + wlast - start + 2);
|
||
l->height() = (int)(y2 - y1 + 1);
|
||
l->set("@B@R");
|
||
l->temp() = TRUE;
|
||
grs->add_field(l);
|
||
}
|
||
|
||
// horizontal lines
|
||
if (start != 999 && end != 0)
|
||
for (i = 0; rows[i]; i++)
|
||
{
|
||
TForm_line* l = new TForm_line(grs);
|
||
l->set_x(start-1);
|
||
l->y() = (word)rows[i];
|
||
l->id() = -1;
|
||
l->width() = (int)(end + wlast - start + 2);
|
||
l->height() = 1;
|
||
l->set("@R");
|
||
l->temp() = TRUE;
|
||
grs->add_field(l);
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Genera le righe di intestazione colonna alla riga indicata, vale per COLUMNWISE
|
||
//
|
||
// @rdesc Ritorna FALSE se non esiste body (o non e' COLUMNWISE) o se non esiste l'header
|
||
bool TForm::genera_intestazioni(
|
||
pagetype p, // @parm Posizione della pgaina (vedi <t pagetype>)
|
||
short y) // @parm Riga dell'header in cui vanno inserite
|
||
|
||
// @comm I form_items di intestazione vengono aggiunti alla sezione header di tipo <p p> con ID -1
|
||
|
||
{
|
||
TPrint_section* body = exist('B', p);
|
||
if (body == NULL || !body->columnwise()) return FALSE;
|
||
|
||
TPrint_section* header = exist('H', p);
|
||
if (header == NULL) return FALSE;
|
||
body->reset_tabs();
|
||
const word items = body->fields();
|
||
for (word j=0;j<items;j++)
|
||
{// Scans all body items to print, and append header items...
|
||
TForm_item& fi = body->field(j);
|
||
if (!fi.shown())
|
||
continue;
|
||
TForm_string* s = new TForm_string(header);
|
||
s->id() = -1;
|
||
s->set_x(fi.x());
|
||
s->y() = y;
|
||
s->set_prompt(fi.col_head());
|
||
s->temp() = TRUE;
|
||
header->add_field(s);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
/*
|
||
void TForm::remove_temp_items(char sec, pagetype p)
|
||
{
|
||
TPrint_section* s = exist(sec,p);
|
||
if (s!=NULL)
|
||
{
|
||
const word items = s->fields();
|
||
for (word j=0;j<items; j++)
|
||
{
|
||
if (s->field(j).temp())
|
||
s->destroy_field(j,FALSE);
|
||
}
|
||
s->field_array().pack();
|
||
}
|
||
}
|
||
|
||
|
||
void TForm::put_examples(char sez, pagetype p)
|
||
{
|
||
TPrint_section* s = exist(sez,p);
|
||
if (s!=NULL)
|
||
{
|
||
const word items = s->fields();
|
||
for (word i=0;i<items;i++)
|
||
{
|
||
TForm_item& fi = s->field(i);
|
||
if (fi.fields()!=0) continue;
|
||
if (fi.memo())
|
||
fi.set(fi.memo_info());
|
||
else
|
||
if (fi.prompt().empty())
|
||
{
|
||
if (fi.class_name() == "DATA")
|
||
{
|
||
const TDate d(TODAY);
|
||
fi.set(d);
|
||
}
|
||
else
|
||
if (fi.class_name() == "NUMERO")
|
||
{
|
||
fi.set_prompt(fi.example());
|
||
fi.temp() = TRUE;
|
||
}
|
||
else
|
||
fi.set(fi.key());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TForm::remove_examples(char sez, pagetype p)
|
||
{
|
||
TPrint_section* s = exist(sez,p);
|
||
if (s!=NULL)
|
||
{
|
||
const word items = s->fields();
|
||
for (word i=0;i<items;i++)
|
||
{
|
||
TForm_item& fi = s->field(i);
|
||
if (fi.fields()!=0) continue;
|
||
if (fi.memo())
|
||
fi.set("");
|
||
else
|
||
if (fi.class_name() == "NUMERO" && fi.temp())
|
||
{
|
||
fi.set_prompt("");
|
||
fi.temp() = FALSE;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Stampa gli items da <p form> a <p to>
|
||
//
|
||
// @rdesc Ritorna se ha effettuato correttamente la stampa
|
||
bool TForm::print(
|
||
long from, // @parm Primo item da stampare (default 0l)
|
||
long to) // @parm Ultimo da stampare (se <lt>0 stampa fino alla fine del file, default -1l)
|
||
|
||
// @comm Se i parametri di posizionamento sono settati e cosi' pure gli offset genera un <f error_box>.
|
||
{
|
||
_cur_form = this;
|
||
|
||
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.
|
||
{
|
||
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 (_arrange && pr.printtype() == winprinter)
|
||
arrange_form();
|
||
}
|
||
else
|
||
pr.set_offset(_y,_x);
|
||
|
||
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());
|
||
}
|
||
pr.set_char_size(_fontsize); // Set font name and size
|
||
pr.set_fontname(_fontname); // according to current form
|
||
const bool was_open = pr.isopen();
|
||
|
||
set_last_page(FALSE); // non e' l'ultima pagina
|
||
|
||
set_background(1, TRUE);
|
||
|
||
if (!was_open && !pr.open())
|
||
return FALSE;
|
||
do_events();
|
||
|
||
long lastrec= records()-1;
|
||
|
||
if (to < 0) to = lastrec;
|
||
if (to == lastrec) to--; // l'ultima pagina <20> gestita come caso particolare
|
||
|
||
bool ok = TRUE;
|
||
|
||
for (long i = from; i <= to && ok; i++)
|
||
{
|
||
if (from < 0) to = from;
|
||
else if (cursor()) *cursor() = i;
|
||
|
||
if (pr.current_row() > pr.headersize()+1)
|
||
{
|
||
const word h = set_body(page(pr), FALSE);
|
||
if (h > pr.rows_left())
|
||
pr.formfeed();
|
||
}
|
||
|
||
set_body(page(pr), TRUE);
|
||
}
|
||
|
||
if (i == lastrec && from >= 0)
|
||
{
|
||
if (cursor()) *cursor() = i;
|
||
set_last_page(TRUE);
|
||
set_background(0, TRUE);
|
||
set_header(0, TRUE);
|
||
set_body(0, TRUE);
|
||
pr.formfeed();
|
||
}
|
||
|
||
if (!was_open)
|
||
pr.close();
|
||
|
||
pr.setheaderhandler(NULL);
|
||
pr.setfooterhandler(NULL);
|
||
|
||
return ok;
|
||
}
|
||
|
||
void TForm::print_section(ostream& out, char s) const
|
||
{
|
||
for (pagetype t = odd_page; t <= last_page; t = pagetype(t+1))
|
||
{
|
||
const TPrint_section* sec = ((TForm*)this)->exist(s, t);
|
||
if (sec && sec->ok() && !sec->temp())
|
||
{
|
||
const char* name;
|
||
switch (s)
|
||
{
|
||
case 'F':
|
||
name = "FOOTER"; break;
|
||
case 'G':
|
||
name = "GRAPHICS"; break;
|
||
case 'H':
|
||
name = "HEADER"; break;
|
||
default :
|
||
name = "BODY"; break;
|
||
}
|
||
out << "SECTION " << name;
|
||
out << *sec;
|
||
out << "END\n" << endl;
|
||
}
|
||
}
|
||
}
|
||
|
||
bool TForm::validate(TForm_item& f, TToken_string&)
|
||
{ return FALSE; }
|
||
|
||
void TForm::print_on(ostream& out) const
|
||
{
|
||
main_app().begin_wait();
|
||
|
||
if (relation())
|
||
{
|
||
out << *relation() << "\nEND" << endl;
|
||
print_description(out);
|
||
}
|
||
|
||
print_general(out);
|
||
|
||
print_section(out, 'G');
|
||
print_section(out, 'H');
|
||
print_section(out, 'B');
|
||
print_section(out, 'F');
|
||
|
||
out << "END" << endl;
|
||
|
||
main_app().end_wait();
|
||
}
|
||
|
||
|
||
word TForm::height(word page)
|
||
{
|
||
const pagetype t = (page == 1) ? first_page : ((page & 0x1) ? odd_page : even_page);
|
||
|
||
word h = 0;
|
||
if (_back.items() == 0)
|
||
{
|
||
if (_head.items() && exist('H', t) != NULL)
|
||
h += section('H', page).height();
|
||
if (_body.items() && exist('B', t) != NULL)
|
||
h += section('B', page).height();
|
||
if (_foot.items() && exist('F', t) != NULL)
|
||
h += section('F', page).height();
|
||
}
|
||
else
|
||
h = printer().formlen();
|
||
|
||
return h;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Legge un profilo
|
||
//
|
||
// @rdesc Ritorna se e' riuscito nell'operazione:
|
||
// @flag TRUE | E' riuscito a leggere il prfilo
|
||
// @flag FALSE | Non ha letto il profilo
|
||
bool TForm::read_profile()
|
||
// @comm Per la lettura del profilo procede leggendo prima la definizione del
|
||
// profilo base e successivamente le modifiche relative.
|
||
{
|
||
TLocalisamfile prof(LF_FORM);
|
||
TLocalisamfile rprof(LF_RFORM);
|
||
|
||
prof.zero();
|
||
prof.put("TIPOPROF",_name);
|
||
prof.put("CODPROF",_code);
|
||
if (prof.read(_isequal) == NOERR)
|
||
{
|
||
rprof.zero();
|
||
rprof.put("TIPOPROF", _name);
|
||
rprof.put("CODPROF", _code);
|
||
const TRectype filter(rprof.curr());
|
||
TString set("HGBF");
|
||
|
||
for (int err = rprof.read(_isgteq); err == NOERR && rprof.curr() == filter; err = rprof.next())
|
||
{
|
||
// controllo lingua per codici profilo
|
||
char cl = rprof.curr().get("CODPROF").right(1)[0];
|
||
char cp = _code.right(1)[0];
|
||
|
||
// stop se il codice letto e' di un profilo EC in lingua e
|
||
// il corrente e' ec non in lingua
|
||
if (!isdigit(cl) && cl != cp) break;
|
||
|
||
const TString& s = rprof.get("SEZ");
|
||
const char sec = s[0];
|
||
if (set.find(sec)<0) continue; // Se non fa parte di una sezione standard la salta
|
||
const pagetype pt = char2page(s[1]);
|
||
const short id = rprof.get_int("ID");
|
||
|
||
if (id == 0)
|
||
{
|
||
TPrint_section& se = section(sec, pt);
|
||
se.read_from(rprof.curr());
|
||
}
|
||
else
|
||
{
|
||
TForm_item& item = find_field(sec, pt, id);
|
||
item.read_from(rprof.curr());
|
||
}
|
||
}
|
||
if (_code.not_empty()&& !_isnew)
|
||
{
|
||
_x = prof.get_int("OFFX");
|
||
_y = prof.get_int("OFFY");
|
||
_fontname = prof.get("FONTNAME");
|
||
_fontsize = prof.get_int("FONTSIZE");
|
||
_char_to_pos = prof.get("CTP")[0];
|
||
_ipx = prof.get_int("IPX");
|
||
_ipy = prof.get_int("IPY");
|
||
_fpx = prof.get_int("FPX");
|
||
set_fincatura(prof.get("GRID"));
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TForm::write_profile()
|
||
{
|
||
const char sechar[4] = { 'B', 'F', 'G', 'H' };
|
||
|
||
get_compulsory_specials();
|
||
TLocalisamfile form(LF_FORM);
|
||
form.zero();
|
||
form.put("TIPOPROF",_name);
|
||
form.put("CODPROF",_code);
|
||
if (form.read(_isequal,_lock) == NOERR)
|
||
{
|
||
if (_dirty)
|
||
{
|
||
form.put("OFFY",_y);
|
||
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.put("GRID", _fink);
|
||
form.rewrite();
|
||
_dirty=FALSE;
|
||
}
|
||
}
|
||
|
||
TLocalisamfile rform(LF_RFORM);
|
||
TRectype& cur = rform.curr();
|
||
|
||
int err = NOERR;
|
||
for (int sn = 0; sn < 4 && err == NOERR; sn++) // For each section
|
||
{
|
||
const char sc = sechar[sn];
|
||
for (pagetype pt = odd_page; pt <= last_page; pt = pagetype(pt+1)) // For each section type
|
||
{
|
||
TPrint_section* sec = exist(sc, pt);
|
||
if (sec != NULL && sec->dirty())
|
||
{
|
||
const char codsez[3] = { sc, pt+'0', '\0' };
|
||
cur.zero();
|
||
cur.put("TIPOPROF", name());
|
||
cur.put("CODPROF", code());
|
||
cur.put("SEZ", codsez);
|
||
sec->print_on(cur);
|
||
sec->set_dirty(FALSE);
|
||
|
||
err = _isnew ? rform.write() : rform.rewrite();
|
||
if (err != NOERR)
|
||
err = _isnew ? rform.rewrite() : rform.write();
|
||
|
||
for (word i = 0; i < sec->fields() && err == NOERR; i++)
|
||
{
|
||
TForm_item& fi = sec->field(i);
|
||
if (fi.dirty())
|
||
{
|
||
fi.print_on(cur);
|
||
err = _isnew ? rform.write() : rform.rewrite();
|
||
if (err != NOERR)
|
||
err = _isnew ? rform.rewrite() : rform.write();
|
||
fi.set_dirty(FALSE);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
form.reread(_unlock);
|
||
if (err != NOERR)
|
||
return error_box("Errore di salvataggio profilo: %d", err);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void TForm::init()
|
||
{
|
||
_relation= NULL;
|
||
_cursor= NULL;
|
||
_rel_desc= NULL;
|
||
_isnew= FALSE;
|
||
_fontname= "Roman 17cpi";
|
||
_fontsize= 12;
|
||
_x= 0;
|
||
_y= 0;
|
||
_char_to_pos= '\0';
|
||
_ipx= 0;
|
||
_ipy= 0;
|
||
_fpx= 0;
|
||
_arrange= TRUE;
|
||
set_fincatura("+++++++++-|");
|
||
_dirty= FALSE;
|
||
_background_mode = printer().isgraphics() ? graphics : testo;
|
||
_msg_add_enabled = TRUE;
|
||
}
|
||
|
||
// @doc EXTERNAL
|
||
|
||
// @mfunc Carica il form dal file specificato
|
||
void TForm::read(
|
||
const char* name, // @parm Nome del profilo di stampa da leggere
|
||
const char* code, // @parm Codice del profilo di stampa da leggere
|
||
int lev, // @parm Permessi di stampa
|
||
const char* desc) // @parm Descrizione del formato da leggere
|
||
{
|
||
_name= name;
|
||
_code= code;
|
||
_editlevel= lev;
|
||
_desc= desc;
|
||
|
||
main_app().begin_wait();
|
||
|
||
if (_code.not_empty())
|
||
{
|
||
// extract base form name
|
||
TLocalisamfile forms(LF_FORM);
|
||
forms.zero();
|
||
|
||
forms.put("TIPOPROF", _name);
|
||
forms.put("CODPROF", _code);
|
||
_isnew = forms.read() != NOERR;
|
||
if (_isnew)
|
||
{
|
||
// create new form
|
||
forms.put("TIPOPROF", _name);
|
||
forms.put("CODPROF", _code);
|
||
forms.put("DESC", _desc);
|
||
forms.put("OFFY",_y);
|
||
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.put("GRID", _fink);
|
||
forms.write();
|
||
}
|
||
else
|
||
if (forms.status() == NOERR)
|
||
{
|
||
_desc = forms.get("DESC");
|
||
if (_desc != desc && desc != "") // Controlla se la descrizione e' diversa, in questo caso l'aggiorna
|
||
{
|
||
forms.reread(_lock);
|
||
forms.put("DESC",desc);
|
||
forms.rewrite();
|
||
}
|
||
}
|
||
}
|
||
|
||
// read base form
|
||
TFilename n(_name); n.ext("frm");
|
||
if (!fexist(n)) fatal_box("Il file %s non esiste.",(const char *) n);
|
||
TScanner scanner(n);
|
||
|
||
bool ok = TRUE;
|
||
if (scanner.popkey() == "US") // Parse relation
|
||
{
|
||
ok = parse_use(scanner);
|
||
while (ok && scanner.popkey() == "JO")
|
||
ok = parse_join(scanner);
|
||
|
||
parse_description(scanner); // Parse description
|
||
}
|
||
else scanner.push();
|
||
|
||
if (ok) parse_general(scanner); // Parse general
|
||
|
||
while (ok)
|
||
{
|
||
if (scanner.popkey() != "SE") // SECTION or END
|
||
break;
|
||
const char sec = scanner.popkey()[0]; // Section name (GRAPH, HEAD, BODY, FOOT)
|
||
const pagetype p = char2page(scanner.popkey()[0]); // Section type (odd, even, first, last)
|
||
TPrint_section* ps = exist(sec, p, TRUE); // Create section
|
||
ok = ps->parse(scanner); // Parse section
|
||
}
|
||
|
||
if (_code.not_empty())
|
||
read_profile(); // read from LF_RFORM file
|
||
|
||
set_compulsory_specials();
|
||
TPrinter& pr = printer();
|
||
pr.set_offset(_y,_x);
|
||
pr.set_char_size(_fontsize);
|
||
pr.set_fontname(_fontname);
|
||
set_mode(_background_mode);
|
||
|
||
main_app().end_wait();
|
||
}
|
||
|
||
void TForm::set_compulsory_specials()
|
||
{
|
||
const char sechar[3] = { 'B', 'F', 'H' };
|
||
|
||
for (int sn = 0; sn < 3; sn++)
|
||
{
|
||
const char sc = sechar[sn];
|
||
for (pagetype pt = odd_page; pt <= last_page; pt = pagetype(pt+1))
|
||
{
|
||
TPrint_section* sec = exist(sc, pt);
|
||
if (sec != NULL)
|
||
{
|
||
const word fields = sec->fields();
|
||
const bool col_wise = sec->columnwise();
|
||
for (word i = 0; col_wise && i < fields; i++)
|
||
{
|
||
TForm_item& fi = sec->field(i);
|
||
if (fi.special_items()>0)
|
||
{
|
||
fi.set_col_head(fi.get_special_value("INTESTAZIONE"));
|
||
fi.ofs() = (short)atoi(fi.get_special_value("OFFSET"));
|
||
TString fnk(fi.get_special_value("FINCATURA"));
|
||
fi.set_finkl(fnk[0]!='X'); // !finkl significa fincatura abilitata
|
||
fi.set_finkr(fnk[1]!='X'); // !finkr significa fincatura abilitata
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TForm::get_compulsory_specials()
|
||
{
|
||
const char sechar[3] = { 'B', 'F', 'H' };
|
||
|
||
for (int sn = 0; sn < 3; sn++)
|
||
{
|
||
const char sc = sechar[sn];
|
||
for (pagetype pt = odd_page; pt <= last_page; pt = pagetype(pt+1))
|
||
{
|
||
TPrint_section* sec = exist(sc, pt);
|
||
if (sec != NULL)
|
||
{
|
||
const word fields = sec->fields();
|
||
const bool col_wise = sec->columnwise();
|
||
for (word i = 0; col_wise && i < fields; i++)
|
||
{
|
||
TForm_item& fi = sec->field(i);
|
||
if (fi.special_items()>0)
|
||
{
|
||
fi.set_special_value("INTESTAZIONE", fi.col_head());
|
||
fi.set_special_value("OFFSET", format("%d",fi.ofs()));
|
||
TString fnk(fi.finkl()? " " : "X");
|
||
fnk << (fi.finkr() ? " " : "X");
|
||
fi.set_special_value("FINCATURA",fnk);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TForm::set_fincatura(const char* s)
|
||
{
|
||
_fink = s; _fink.cut(11);
|
||
printer().set_fincatura(_fink);
|
||
}
|
||
|
||
void TForm::set_mode(bkg_mode b)
|
||
{
|
||
_background_mode = b;
|
||
if (_background_mode == graphics && printer().is_generic()) _background_mode = testo;
|
||
printer().set_graphics(_background_mode == graphics ? TRUE : FALSE);
|
||
}
|
||
|
||
TForm::TForm()
|
||
{
|
||
init();
|
||
}
|
||
|
||
TForm::TForm(const char* name, const char* code, int lev, const char* desc)
|
||
{
|
||
init();
|
||
read(name, code, lev, desc);
|
||
}
|
||
|
||
TForm::~TForm()
|
||
{
|
||
if (_cursor)
|
||
{
|
||
delete _cursor;
|
||
delete _relation;
|
||
if (_rel_desc)
|
||
delete _rel_desc;
|
||
}
|
||
}
|
||
|
||
|