2569 lines
58 KiB
C++
Executable File
2569 lines
58 KiB
C++
Executable File
#include <ctype.h>
|
||
#include <stdlib.h>
|
||
|
||
#if XVT_OS == XVT_OS_WIN
|
||
#define STRICT
|
||
#include <windows.h>
|
||
#endif
|
||
|
||
#include <applicat.h>
|
||
#include <form.h>
|
||
#include <msksheet.h>
|
||
#include <printer.h>
|
||
#include <relation.h>
|
||
#include <sheet.h>
|
||
#include <utility.h>
|
||
|
||
#include "../ba/ba2100.h"
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Utility functions
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// Current form (edit, print)
|
||
HIDDEN TForm* _cur_form = NULL;
|
||
|
||
HIDDEN TForm& form()
|
||
{
|
||
CHECK(_cur_form, "Can't print NULL form");
|
||
return *_cur_form;
|
||
}
|
||
|
||
// Translate char to pagetype (visible outside here, no more HIDDEN)
|
||
pagetype char2page(char c)
|
||
{
|
||
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_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());
|
||
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_SPACE)
|
||
{
|
||
TRelation_description& r = form().rel_desc();
|
||
TEdit_field& e = f.mask().efield(f.dlg()-4);
|
||
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 TFormatted_date ex(TODAY, 0, 0, fmt);
|
||
m.set(F_DEXAMPLE, ex.string());
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_flags
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TForm_flags::TForm_flags()
|
||
{
|
||
automagic = dirty = 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;
|
||
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 (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" : " ");
|
||
}
|
||
|
||
|
||
// 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);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_item
|
||
///////////////////////////////////////////////////////////
|
||
|
||
|
||
TForm_item::TForm_item(TPrint_section* section)
|
||
: _section(section), _x(-1), _y(-1), _width(0), _height(0), _id(0)
|
||
{}
|
||
|
||
|
||
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;
|
||
}
|
||
}
|
||
|
||
|
||
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();
|
||
if (!m.blank())
|
||
message(0).add(m);
|
||
return TRUE;
|
||
}
|
||
|
||
if (scanner.key() == "KE")
|
||
{
|
||
_desc = scanner.string();
|
||
return TRUE;
|
||
}
|
||
|
||
if (scanner.key() == "GR")
|
||
{
|
||
_group.set(scanner.line());
|
||
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;
|
||
}
|
||
|
||
const bool s = prof.get_bool("ATTIVO");
|
||
if (_flag.shown != s)
|
||
{
|
||
_flag.shown = s;
|
||
changed = TRUE;
|
||
}
|
||
|
||
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());
|
||
prof.put("ATTIVO", shown() ? "X" : " ");
|
||
}
|
||
|
||
void TForm_item::enable(bool on)
|
||
{
|
||
_flag.enabled = on;
|
||
show(on);
|
||
}
|
||
|
||
void TForm_item::string_at(int x, int y, const char* s)
|
||
{
|
||
if (shown())
|
||
{
|
||
section().offset(x, y);
|
||
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;
|
||
}
|
||
|
||
|
||
void TForm_item::send_message(const TString& cmd, TForm_item& des) const
|
||
{
|
||
if (cmd == "ADD" || cmd == "INC")
|
||
{
|
||
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);
|
||
|
||
do_message();
|
||
return TRUE;
|
||
}
|
||
|
||
void TForm_item::print_on(TToken_string& row) const
|
||
{
|
||
row.cut(0);
|
||
row.add(id());
|
||
row.add(class_name());
|
||
row.add(_y);
|
||
row.add(_x);
|
||
row.add(key());
|
||
|
||
if (form().edit_level() > 1)
|
||
{
|
||
row.add(shown() ? " " : "X");
|
||
const long fu = _group.first_one();
|
||
if (fu > 0) row.add(fu);
|
||
else row.add(" ");
|
||
}
|
||
}
|
||
|
||
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);
|
||
m.set(F_HEIGHT, _height);
|
||
|
||
_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));
|
||
_height = atoi(m.get(F_HEIGHT));
|
||
_id = atoi(m.get(F_ID));
|
||
|
||
_flag.read_from(m);
|
||
|
||
_group.reset();
|
||
for (int g = 1; g <= 24; g++)
|
||
_group.set(g, m.get_bool(F_GROUP+g));
|
||
}
|
||
|
||
|
||
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);
|
||
|
||
const bool dirty = m.run() == K_ENTER;
|
||
if (dirty)
|
||
{
|
||
read_from(m);
|
||
set_dirty();
|
||
}
|
||
return dirty;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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 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)
|
||
{}
|
||
|
||
|
||
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;
|
||
|
||
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) const;
|
||
|
||
virtual bool parse_item(TScanner&);
|
||
virtual bool read();
|
||
virtual bool update();
|
||
|
||
virtual const char* get() const;
|
||
bool set(const char*);
|
||
|
||
const TString& picture() const { return _picture; }
|
||
|
||
TFieldref& field(int i) const { return (TFieldref&)_field[i]; }
|
||
void put_paragraph(const char* s);
|
||
|
||
public:
|
||
TForm_string(TPrint_section* section) : TForm_item(section) {}
|
||
virtual ~TForm_string() {}
|
||
};
|
||
|
||
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")
|
||
{
|
||
_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;
|
||
}
|
||
|
||
return changed;
|
||
}
|
||
|
||
void TForm_string::print_on(TToken_string& row) const
|
||
{
|
||
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);
|
||
}
|
||
|
||
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);
|
||
|
||
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);
|
||
|
||
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();
|
||
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;
|
||
|
||
if (height() > 1)
|
||
{
|
||
TParagraph_string p(s, width());
|
||
int i = _prompt.not_empty() ? 1 : 0;
|
||
for (; (s = p.get()) != NULL && i < height(); i++)
|
||
string_at(_x, _y+i, s);
|
||
}
|
||
else string_at(-1, _y, s);
|
||
}
|
||
|
||
|
||
bool TForm_string::update()
|
||
{
|
||
if (read())
|
||
{
|
||
TForm_item::update();
|
||
if (!picture().blank())
|
||
{
|
||
TToken_string delim(4, ','); // Stringa con i due delimitatori
|
||
const char* pic = picture(); // Picture senza delimitatori
|
||
|
||
if (pic[0] == '(') // Se ci sono i delimitatori ...
|
||
{
|
||
const int bra = picture().find(')');
|
||
if (bra > 0) // ... cerca la parentesi chiusa
|
||
{
|
||
delim = picture().sub(1, bra); // memorizza delimitatori
|
||
pic += bra+1; // toglili dalla picture
|
||
}
|
||
}
|
||
|
||
TString80 s;
|
||
s.picture(pic, get()); // riempi la stringa col valore pitturato
|
||
|
||
if (!delim.empty_items()) // Aggiungi delimitatori
|
||
{
|
||
char d = delim.get_char(0);
|
||
if (d > ' ') // Se il primo delimitatore e' valido ...
|
||
{
|
||
int spc = -1;
|
||
for (int i = 0; s[i]; i++)
|
||
if (s[i] != ' ') // Sostituiscilo all'ultimo spazio iniziale
|
||
{
|
||
spc = i-1;
|
||
break;
|
||
}
|
||
if (spc < 0)
|
||
{
|
||
s.insert(" ", 0); // ... inseriscilo all'inizio
|
||
spc = 0;
|
||
}
|
||
s[spc] = d;
|
||
}
|
||
d = delim.get_char();
|
||
if (d > ' ') // Se il secondo delimitatore e' valido ...
|
||
{
|
||
s.rtrim();
|
||
s << d; // ... aggiungilo alla fine
|
||
}
|
||
}
|
||
put_paragraph(s);
|
||
}
|
||
else
|
||
put_paragraph(get()); // Stampa immediata senza picture
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm_number
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TForm_number : public TForm_string
|
||
{
|
||
protected: // TForm_string
|
||
virtual const char* class_name() const { return "NUMERO"; }
|
||
virtual bool parse_head(TScanner& scanner);
|
||
virtual bool update();
|
||
virtual int height() const { return 0; }
|
||
|
||
protected:
|
||
int decimals() const { return _height; }
|
||
|
||
public:
|
||
TForm_number(TPrint_section* section) : TForm_string(section) {}
|
||
virtual ~TForm_number() {}
|
||
};
|
||
|
||
|
||
bool TForm_number::parse_head(TScanner& scanner)
|
||
{
|
||
TForm_item::parse_head(scanner);
|
||
_height = _width; // Decimals
|
||
_width = 0;
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
bool TForm_number::update()
|
||
{
|
||
if (read())
|
||
{
|
||
TForm_item::update();
|
||
|
||
real n(get());
|
||
n.round(decimals());
|
||
|
||
if (!n.is_zero())
|
||
{
|
||
if (!picture().blank())
|
||
{
|
||
TToken_string delim(4, ','); // Stringa con i due delimitatori
|
||
const char* pic = picture(); // Picture senza delimitatori
|
||
|
||
if (pic[0] == '(') // Se ci sono i delimitatori ...
|
||
{
|
||
const int bra = picture().find(')');
|
||
if (bra > 0) // ... cerca la parentesi chiusa
|
||
{
|
||
delim = picture().sub(1, bra); // memorizza delimitatori
|
||
pic += bra+1; // toglili dalla picture
|
||
}
|
||
}
|
||
|
||
TString80 s(n.string(pic)); // riempi la stringa col valore pitturato
|
||
|
||
if (!delim.empty_items()) // Aggiungi delimitatori
|
||
{
|
||
char d = delim.get_char(0);
|
||
if (d > ' ') // Se il primo delimitatore e' valido ...
|
||
{
|
||
int spc = -1;
|
||
for (int i = 0; s[i]; i++)
|
||
if (s[i] != ' ') // Sostituiscilo all'ultimo spazio iniziale
|
||
{
|
||
spc = i-1;
|
||
break;
|
||
}
|
||
if (spc < 0)
|
||
{
|
||
s.insert(" ", 0); // ... inseriscilo all'inizio
|
||
spc = 0;
|
||
}
|
||
s[spc] = d;
|
||
}
|
||
d = delim.get_char();
|
||
if (d > ' ') // Se il secondo delimitatore e' valido ...
|
||
{
|
||
s.rtrim();
|
||
s << d; // ... aggiungilo alla fine
|
||
}
|
||
}
|
||
put_paragraph(s);
|
||
}
|
||
else
|
||
put_paragraph(n.string());
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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 bool edit(TMask& m);
|
||
TForm_date(TPrint_section* section);
|
||
virtual ~TForm_date() {}
|
||
};
|
||
|
||
|
||
TForm_date::TForm_date(TPrint_section* section)
|
||
: TForm_string(section), _format("1444-")
|
||
{}
|
||
|
||
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::read_from(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 TFormatted_date d(TODAY, 0, 0, _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);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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:
|
||
TForm_list(TPrint_section* section);
|
||
virtual ~TForm_list() {}
|
||
};
|
||
|
||
TForm_list::TForm_list(TPrint_section* section)
|
||
: TForm_string(section)
|
||
{}
|
||
|
||
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() {}
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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)
|
||
{}
|
||
|
||
TPrint_section::~TPrint_section()
|
||
{
|
||
if (_msk)
|
||
{
|
||
delete _msk;
|
||
_msk = NULL;
|
||
}
|
||
}
|
||
|
||
const TPrint_section& TPrint_section::copy(const TPrint_section& ps)
|
||
{
|
||
_item = ps._item;
|
||
_height = ps._height;
|
||
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::offset(int& x, int& y) const
|
||
{
|
||
if (x >= 0) 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
|
||
|
||
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 (word i = 0; i < height(); 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;
|
||
}
|
||
|
||
bool TPrint_section::read_from(const TRectype& prof)
|
||
{
|
||
CHECK(prof.num() == LF_RFORM, "Il record deve essere del file LF_RFORM");
|
||
|
||
bool changed = FALSE;
|
||
const word h = (word)prof.get_int("HGT");
|
||
if (_height != h)
|
||
{
|
||
_height = h;
|
||
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", 0);
|
||
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
|
||
double 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::edit(const char* title)
|
||
{
|
||
_cur_form = _form;
|
||
|
||
if (!_subsection)
|
||
{
|
||
TMask m("ba2100s");
|
||
m.set_caption(title);
|
||
m.set(F_HEIGHT, _height);
|
||
m.set(F_X, form().offset_x());
|
||
m.set(F_Y, form().offset_y());
|
||
|
||
{
|
||
const int MAX_FAMILIES = 128;
|
||
char* family[MAX_FAMILIES];
|
||
const int num_families = (int)xvt_fmap_get_families(printer().get_printrcd(), family, MAX_FAMILIES);
|
||
bool font_found = FALSE;
|
||
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);
|
||
lst.replace_items(pn1, pn2);
|
||
if (!font_found) warning_box("Il font %s non esiste per la stampante di default.",(const char*) form().fontname());
|
||
lst.set(form().fontname());
|
||
}
|
||
printer().set_char_size(form().fontsize());
|
||
m.set_handler(F_FONT,font_handler);
|
||
if (m.run() == K_ESC)
|
||
return FALSE;
|
||
|
||
bool dirty = m.dirty() != 0;
|
||
|
||
if (dirty)
|
||
{
|
||
if (_height != (word)m.get_int(F_HEIGHT) )
|
||
{
|
||
_height = m.get_int(F_HEIGHT);
|
||
_dirty=TRUE;
|
||
}
|
||
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;
|
||
}
|
||
|
||
TString80 name(m.get(F_FONT));
|
||
int size = m.get_int(F_SIZE);
|
||
if (name != form().fontname() || size != form().fontsize())
|
||
{
|
||
if (!form().dirty()) form().set_dirty();
|
||
_dirty = TRUE;
|
||
s_data prm;
|
||
prm.size_1=form().fontsize();
|
||
strcpy(prm.name_1,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();
|
||
|
||
form().fontname() = name;
|
||
form().fontsize() = size;
|
||
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 = form().exist(sc, pt);
|
||
if (sec != NULL)
|
||
{
|
||
sec->set_dirty();
|
||
for (word i = 0; i < sec->fields() ; i++)
|
||
{
|
||
TForm_item& fi = sec->field(i);
|
||
if (fi.x() > 0 && (prm.ratio != 1.0))
|
||
{
|
||
real x_pos;
|
||
x_pos = fi.x() * prm.ratio;
|
||
x_pos.round();
|
||
fi.x() = (short)x_pos.integer();
|
||
fi.set_dirty();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
const word flags = 0x08 | (form().edit_level() > 1 ? 0x06 : 0x00);
|
||
|
||
TString80 caption("ID@4|Tipo@8|Riga@R|Col.@R|Descrizione@40|Nascosto");
|
||
if (form().edit_level() > 1) caption << "|Gr.@R|Campo@16";
|
||
|
||
TArray_sheet a(-1, -1, 0, 0, title, caption, flags);
|
||
|
||
for (word i = 0; i < fields(); i++)
|
||
{
|
||
TToken_string* s = new TToken_string(128);
|
||
field(i).print_on(*s);
|
||
a.add(s);
|
||
}
|
||
|
||
KEY k;
|
||
while ((k = a.run()) != K_ESC)
|
||
{
|
||
i = (word)a.selected();
|
||
|
||
if (_msk == NULL && (k == K_ENTER || k == K_INS || k == K_CTRL + 'N'))
|
||
{
|
||
_msk = new TMask("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_BUT_FILE1, but_file_handler);
|
||
_msk->set_handler(F_BUT_FIELD1, but_field_handler);
|
||
_msk->set_handler(F_FROM1, from_handler);
|
||
_msk->set_handler(F_TO1, to_handler);
|
||
_msk->set_handler(F_BUT_FILE2, but_file_handler);
|
||
_msk->set_handler(F_BUT_FIELD2, but_field_handler);
|
||
_msk->set_handler(F_FROM2, from_handler);
|
||
_msk->set_handler(F_TO2, to_handler);
|
||
}
|
||
|
||
TForm_string dummy(this);
|
||
|
||
switch(k)
|
||
{
|
||
case K_ENTER:
|
||
_msk->set_mode(MODE_MOD);
|
||
if (field(i).edit(*_msk))
|
||
{
|
||
field(i).print_on(a.row(i));
|
||
_dirty = TRUE;
|
||
}
|
||
break;
|
||
case K_CTRL + 'N':
|
||
case K_INS:
|
||
_msk->set_mode(MODE_INS);
|
||
if (dummy.edit(*_msk))
|
||
{
|
||
const TString& c = _msk->get(F_CLASS).left(2);
|
||
TForm_item* item = parse_item(c);
|
||
if (item != NULL)
|
||
{
|
||
item->read_from(*_msk);
|
||
_item.insert(item, i);
|
||
|
||
TToken_string s(128); item->print_on(s);
|
||
a.insert(s, i);
|
||
_dirty = TRUE;
|
||
}
|
||
}
|
||
break;
|
||
case K_DEL:
|
||
if (yesno_box("Confermare la cancellazione"))
|
||
{
|
||
_item.destroy(i, TRUE);
|
||
a.destroy(i);
|
||
_dirty = TRUE;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
set_dirty(_dirty);
|
||
return _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 << endl << endl;
|
||
for(word i = 0; i < fields(); i++)
|
||
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 whit id %d", id);
|
||
return field(0);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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() {}
|
||
};
|
||
|
||
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()
|
||
{
|
||
TString80 i;
|
||
const int w = _prompt[0] == '@' ? 3 : 1;
|
||
i << 'W' << w << "l{" << _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);
|
||
|
||
error_box("Campo di stampa non ammesso per lo sfondo: %s", (const char*)s);
|
||
return NULL;
|
||
}
|
||
|
||
bool TGraphic_section::update()
|
||
{
|
||
_back.cut(0);
|
||
const bool ok = TPrint_section::update();
|
||
printer().setbackground(_back);
|
||
return ok;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm
|
||
///////////////////////////////////////////////////////////
|
||
|
||
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.popkey() == "OF") // Offsets
|
||
{
|
||
_x = scanner.integer();
|
||
_y = scanner.integer();
|
||
}
|
||
else scanner.push();
|
||
if (scanner.popkey() == "FO") // Font name
|
||
_fontname = scanner.string();
|
||
else scanner.push();
|
||
if (scanner.popkey() == "SI") // Font size
|
||
_fontsize = scanner.integer();
|
||
else scanner.push();
|
||
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" ;
|
||
out << "END\n" << endl;
|
||
}
|
||
|
||
TPrint_section* TForm::exist(char s, pagetype t, bool create)
|
||
{
|
||
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 %d", id);
|
||
return ps->find_field(id);
|
||
}
|
||
|
||
TPrint_section& TForm::section(char s, word p)
|
||
{
|
||
pagetype pos = odd_page;
|
||
if (p == 0 && exist(s, last_page)) pos = last_page;
|
||
if (p == 1 && exist(s, first_page)) pos = first_page;
|
||
if (pos == odd_page && (p & 0x1) == 0 && exist(s, even_page)) pos = even_page;
|
||
|
||
TPrint_section* sec = exist(s, pos, TRUE);
|
||
return *sec;
|
||
}
|
||
|
||
word TForm::set_background(word p, bool u)
|
||
{
|
||
word len = 0;
|
||
|
||
if (u && _back.items())
|
||
{
|
||
TPrint_section& graph = section('G', p);
|
||
graph.update();
|
||
len = printer().formlen();
|
||
}
|
||
|
||
return len;
|
||
}
|
||
|
||
word TForm::set_header(word p, bool u)
|
||
{
|
||
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();
|
||
}
|
||
|
||
word TForm::set_body(word p, bool u)
|
||
{
|
||
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();
|
||
}
|
||
|
||
word TForm::set_footer(word p, bool u)
|
||
{
|
||
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);
|
||
}
|
||
|
||
|
||
word TForm::page(const TPrinter& p) const
|
||
{
|
||
return _lastpage ? 0 : p.getcurrentpage();
|
||
}
|
||
|
||
long TForm::records() const
|
||
{
|
||
const long r = _cursor ? _cursor->items() : 0;
|
||
return r;
|
||
}
|
||
|
||
// Stampa gli items dal from a to
|
||
// se to < 0 stampa fino alla fine del file
|
||
|
||
bool TForm::print(long from, long to)
|
||
{
|
||
_cur_form = this;
|
||
|
||
TPrinter& pr = printer(); // Setta handlers
|
||
pr.setheaderhandler(header_handler);
|
||
pr.setfooterhandler(footer_handler);
|
||
pr.set_char_size(_fontsize); // Set font name and size
|
||
pr.set_fontname(_fontname); // according to current form
|
||
const bool was_open = pr.isopen();
|
||
|
||
_lastpage = 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;
|
||
|
||
const word h = set_body(page(pr), FALSE);
|
||
if (h > pr.rows_left())
|
||
pr.formfeed();
|
||
|
||
set_body(page(pr), TRUE);
|
||
}
|
||
|
||
if (i == lastrec)
|
||
{
|
||
if (_cursor) *_cursor = i;
|
||
_lastpage = 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())
|
||
{
|
||
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 h = 0;
|
||
|
||
if (_back.items() == 0)
|
||
{
|
||
if (_head.items())
|
||
h += section('H', 1).height();
|
||
if (_body.items())
|
||
h += section('B', 1).height();
|
||
if (_foot.items())
|
||
h += section('F', 1).height();
|
||
}
|
||
else
|
||
h = printer().formlen();
|
||
|
||
return h;
|
||
}
|
||
|
||
|
||
bool TForm::read_profile()
|
||
{
|
||
TLocalisamfile prof(LF_FORM);
|
||
TLocalisamfile rprof(LF_RFORM);
|
||
|
||
prof.zero();
|
||
prof.put("TIPOPROF",_name);
|
||
prof.put("CODPROF",_code);
|
||
if (prof.read(_isequal) == NOERR)
|
||
{
|
||
bool complete = FALSE;
|
||
rprof.zero();
|
||
rprof.put("TIPOPROF", _name);
|
||
rprof.put("CODPROF", _code);
|
||
const TRectype filter(rprof.curr());
|
||
|
||
for (int err = rprof.read(_isgteq); err == NOERR && rprof.curr() == filter; err = rprof.next())
|
||
{
|
||
const TString& s = rprof.get("SEZ");
|
||
const char sec = s[0];
|
||
const pagetype pt = char2page(s[1]);
|
||
const short id = rprof.get_int("ID");
|
||
|
||
if (!complete) complete=TRUE;
|
||
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 (complete) // Get general data from header of form only if it's complete.
|
||
{ // Complete means that there's at least a row
|
||
_x = prof.get_int("OFFX");
|
||
_y = prof.get_int("OFFY");
|
||
_fontname = prof.get("FONTNAME");
|
||
_fontsize = prof.get_int("FONTSIZE");
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TForm::write_profile()
|
||
{
|
||
const char sechar[4] = { 'B', 'F', 'G', 'H' };
|
||
|
||
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.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;
|
||
}
|
||
|
||
TForm::TForm(const char* name, long code, int lev, const char* desc)
|
||
: _name(name), _code(code), _relation(NULL), _cursor(NULL), _rel_desc(NULL),
|
||
_isnew(FALSE), _editlevel(lev), _desc(desc), _fontname("Courier New"),
|
||
_fontsize(12), _x(0), _y(0), _dirty(FALSE)
|
||
{
|
||
main_app().begin_wait();
|
||
|
||
if (_code > 0)
|
||
{
|
||
// 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.write();
|
||
}
|
||
else _desc = forms.get("DESC");
|
||
}
|
||
|
||
// read base form
|
||
TFilename n(_name); n.ext("frm");
|
||
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 > 0)
|
||
read_profile(); // read from LF_RFORM file
|
||
|
||
main_app().end_wait();
|
||
}
|
||
|
||
|
||
TForm::~TForm()
|
||
{
|
||
if (_cursor)
|
||
{
|
||
delete _cursor;
|
||
delete _relation;
|
||
if (_rel_desc)
|
||
delete _rel_desc;
|
||
}
|
||
}
|
||
|
||
|