campo-sirio/ba/ba8300.cpp
guy 2e17ac6800 Patch level : 2.1 nopatch
Files correlati     : ba8.exe
Ricompilazione Demo : [ ]
Commento            :

Aggiunta possibilita' di selezionae e spostare campi in giro per la pagina


git-svn-id: svn://10.65.10.50/trunk@11831 c028cbd2-c16b-5b4b-a496-9718f37d4682
2004-03-11 16:36:30 +00:00

1014 lines
23 KiB
C++
Executable File

#include <xi.h>
#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <execp.h>
#include <image.h>
#include <prefix.h>
#include <printer.h>
#include <tree.h>
#include <xml.h>
#include "ba8201.h"
#include "ba8300.h"
#include <bagn003.h>
///////////////////////////////////////////////////////////
// TXVT_font
///////////////////////////////////////////////////////////
class TXVT_font : public TObject
{
public:
XVT_FNTID _fontid;
void create(const TString& name, int size, XVT_FONT_STYLE_MASK style);
void destroy();
TXVT_font() : _fontid(NULL) { }
virtual ~TXVT_font() { destroy(); }
};
void TXVT_font::create(const TString& name, int size, XVT_FONT_STYLE_MASK style)
{
destroy();
_fontid = xvt_font_create();
xvt_font_set_family(_fontid, (char*)(const char*)name);
xvt_font_set_size(_fontid, size);
xvt_font_set_style(_fontid, style);
}
void TXVT_font::destroy()
{
if (_fontid != NULL)
{
xvt_font_destroy(_fontid);
_fontid = NULL;
}
}
///////////////////////////////////////////////////////////
// TReport_font
///////////////////////////////////////////////////////////
class TReport_font : public TObject
{
enum { DEFAULT_FONT_SIZE = 12 };
TString _name;
int _size;
bool _bold, _italic, _underline;
TArray _physical;
public:
const TString& name() const { return _name; }
int size() const { return _size; }
XVT_FNTID get_xvt_font(WINDOW win, int size) const;
TReport_font();
virtual ~TReport_font() { }
};
XVT_FNTID TReport_font::get_xvt_font(WINDOW win, int charx) const
{
TXVT_font* font = (TXVT_font*)_physical.objptr(charx);
if (font == NULL)
{
const int quanteM = 8;
const int target_width = quanteM * _size * charx / DEFAULT_FONT_SIZE;
int mi = 4, me = 0, ma = 4*charx;
int best = 0, best_error = 0;
TXVT_font f;
while (mi < ma)
{
me = (mi+ma)/2;
f.create(XVT_FFN_FIXED, me, XVT_FS_NONE);
xvt_dwin_set_font(win, f._fontid);
const int width = xvt_dwin_get_text_width(win, "MMMMMMMM", quanteM);
const int error = abs(width - target_width);
if (best == 0 || error < best_error)
{
best = me;
best_error = error;
if (error == 0)
break;
}
if (width > target_width)
ma = me-1;
else
mi = me+1;
}
XVT_FONT_STYLE_MASK style = 0;
if (_bold) style |= XVT_FS_BOLD;
if (_italic) style |= XVT_FS_ITALIC;
if (_underline) style |= XVT_FS_UNDERLINE;
font = new TXVT_font;
font->create(_name, best, style);
((TArray&)_physical).add(font, charx);
}
return font->_fontid;
}
TReport_font::TReport_font()
: _name("Courier New"), _size(DEFAULT_FONT_SIZE),
_bold(false), _italic(false), _underline(false)
{ }
///////////////////////////////////////////////////////////
// TReport_section
///////////////////////////////////////////////////////////
class TReport_section : public TArray
{
const TReport_section* _father;
TString _str; // Description
char _type; // Head,Body,Tail
int _level; // 0,1,2,...
TReport_font* _font;
public:
const TString& description() const { return _str; }
int image_id() const;
const TReport_font& font() const;
TReport_section(const TReport_section* f, const char* s, char t, int l);
virtual ~TReport_section();
};
int TReport_section::image_id() const
{
int id = 0;
switch (_type)
{
case 'H': id = 1810; break;
case 'B': id = 1811; break;
case 'F': id = 1812; break;
default : break;
}
return id;
}
const TReport_font& TReport_section::font() const
{
const TReport_font* f = _font;
if (f == NULL)
{
if (_father == NULL)
{
(TReport_font*)_font = new TReport_font;
f = _font;
}
else
f = &_father->font();
}
return *f;
}
TReport_section::TReport_section(const TReport_section* f, const char* s, char t, int l)
: _father(f), _str(s), _type(t), _level(l), _font(NULL)
{ }
TReport_section::~TReport_section()
{
if (_font)
delete _font;
}
///////////////////////////////////////////////////////////
// TReport_window
///////////////////////////////////////////////////////////
const int REPORT_SCALE = 100;
class TReport_window : public TField_window
{
int _zoom; // [8,32]
int _dragging;
TPoint _pt_drag_start;
PNT _pt_drag_offset;
RCT _rct_drag;
protected:
virtual void handler(WINDOW win, EVENT* ep);
virtual void update();
void draw_grid();
void draw_dragster();
public:
virtual PNT log2dev(long x, long y) const;
virtual TPoint dev2log(const PNT& pt) const;
void log2dev(const RCT& rctlog, RCT& rctdev) const;
void dev2log(const RCT& rctdev, RCT& rctlog) const;
void scaling(int& k, int& kx, int& ky) const { k = REPORT_SCALE; kx = _zoom; ky = _zoom*2; }
TReport_section& curr_section() const;
bool get_selection_rect(RCT& rct) const;
void draw_fields();
bool pick(const PNT& p) const;
void clear_selection();
void select(const RCT& rct);
void offset_selection(const TPoint& p);
TReport_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner);
virtual ~TReport_window() { }
};
///////////////////////////////////////////////////////////
// TReport_field
///////////////////////////////////////////////////////////
class TReport_field : public TObject
{
TReport_section* _section;
char _type; // Text, String, Numeric, Date, Line, Rectangle, Image
short _x, _y; // Coordinate in centesimi
short _width, _height; // Dimensioni in centesimi
TString _picture, _field;
TReport_font* _font;
bool _selected;
protected:
const TReport_font& font() const;
public:
void get_client_rect(const TWindow& win, RCT& r) const;
void set_pos(short x, short y);
void set_size(short w, short h);
void draw(TReport_window& win) const;
void get_rect(RCT& rct) const;
void select(bool ok = true) { _selected = ok; }
bool selected() const { return _selected; }
void offset(const TPoint& pt);
bool contains(const TPoint& pt) const;
TReport_field(TReport_section* sec);
};
void TReport_field::set_pos(short x, short y)
{
_x = x;
_y = y;
}
void TReport_field::set_size(short w, short h)
{
_width = w;
_height = h;
}
void TReport_field::get_rect(RCT& r) const
{
r.left = _x; r.top = _y;
r.right = _x + _width; r.bottom = _y+_height;
}
void TReport_field::get_client_rect(const TWindow& win, RCT& r) const
{
const PNT f = win.log2dev(_x,_y);
const PNT t = win.log2dev(_x+_width,_y+_height);
r.top = f.v; r.left = f.h;
r.bottom = t.v; r.right = t.h;
}
void TReport_field::draw(TReport_window& win) const
{
win.set_pen(selected() ? COLOR_RED : COLOR_BLACK);
RCT r; get_client_rect(win, r);
if (_type != 'L')
xvt_dwin_draw_rect(win.win(), &r);
switch (_type)
{
case 'L':
{
xvt_dwin_draw_set_pos(win.win(), win.log2dev(_x,_y));
xvt_dwin_draw_line(win.win(), win.log2dev(_x+_width,_y+_height));
}
break;
case 'D':
case 'N':
case 'S':
case 'T':
{
int k, kx, ky; win.scaling(k, kx, ky);
XVT_FNTID fid = font().get_xvt_font(win.win(), kx);
xvt_dwin_set_font(win.win(), fid);
const int delta = (r.bottom-r.top)/4;
xvt_dwin_draw_text(win.win(), r.left, r.bottom-delta, _picture, -1);
}
break;
default:
break;
}
}
bool TReport_field::contains(const TPoint& pt) const
{
return pt.x >= _x && pt.y >= _y && pt.x < _x+_width && pt.y < _y+_height;
}
void TReport_field::offset(const TPoint& pt)
{
_x += short(pt.x); _y += short(pt.y);
}
const TReport_font& TReport_field::font() const
{
return _font != NULL ? *_font : _section->font();
}
TReport_field::TReport_field(TReport_section* sec)
: _section(sec), _type('T'), _selected(false), _font(NULL)
{
set_pos(0,0);
set_size(1200,100);
}
///////////////////////////////////////////////////////////
// TSection_tree
///////////////////////////////////////////////////////////
class TSection_tree : public TObject_tree
{
protected:
bool get_description(TString& str) const;
TImage* image(bool selected) const;
public:
TReport_section& curr_section() const { return *(TReport_section*)curr_node(); }
void add_node(const char* d, char t = 0, int l = 0)
{ add_son(new TReport_section(&curr_section(), d, t, l)); }
void add_rnode(const char* d, char t = 0, int l = 0)
{ add_rbrother(new TReport_section(&curr_section(), d, t, l)); }
int image_height() const;
};
bool TSection_tree::get_description(TString& str) const
{
const TReport_section* rn = (const TReport_section*)curr_node();
if (rn != NULL)
{
str = rn->description();
return true;
}
return false;
}
TImage* TSection_tree::image(bool selected) const
{
int id = 0;
const TReport_section* rn = (const TReport_section*)curr_node();
if (rn != NULL)
{
id = rn->image_id();
if (id > 0)
return get_res_image(id);
}
return TObject_tree::image(selected);
}
int TSection_tree::image_height() const
{
const TImage* img = image(false);
return img != NULL ? img->height() : 0;
}
///////////////////////////////////////////////////////////
// TReport_mask
///////////////////////////////////////////////////////////
class TReport_mask : public TAutomask
{
TSection_tree _tree;
protected:
virtual TMask_field* parse_field(TScanner& scanner);
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
protected:
bool select_query();
bool select_report();
void on_print();
public:
TSection_tree& sections() { return _tree; }
TReport_mask();
};
///////////////////////////////////////////////////////////
// TReport_window
///////////////////////////////////////////////////////////
TReport_section& TReport_window::curr_section() const
{
TReport_mask& m = (TReport_mask&)owner().mask();
TTree_field& sections = m.tfield(F_SECTIONS);
sections.goto_selected();
return m.sections().curr_section();
}
void TReport_window::draw_fields()
{
TReport_section& rs = curr_section();
FOR_EACH_ARRAY_ITEM(rs, i, o)
{
const TReport_field& f = *(const TReport_field*)o;
f.draw(*this);
}
}
bool TReport_window::pick(const PNT& p) const
{
TReport_section& rs = curr_section();
RCT rct;
FOR_EACH_ARRAY_ITEM(rs, i, o)
{
TReport_field* f = (TReport_field*)o;
f->get_client_rect(*this, rct);
rct.left -= 2; rct.top -= 2;
rct.right += 2; rct.bottom += 2;
if (xvt_rect_has_point(&rct, p))
{
f->select();
return true;
}
}
return false;
}
void TReport_window::clear_selection()
{
TReport_section& rs = curr_section();
FOR_EACH_ARRAY_ITEM(rs, i, o)
{
TReport_field* f = (TReport_field*)o;
f->select(false);
}
}
bool TReport_window::get_selection_rect(RCT& rct) const
{
TReport_section& rs = curr_section();
bool full = false;
FOR_EACH_ARRAY_ITEM(rs, i, o)
{
const TReport_field& f = *(const TReport_field*)o;
if (f.selected())
{
if (!full)
{
f.get_rect(rct);
full = true;
}
else
{
RCT r; f.get_rect(r);
if (r.left < rct.left) rct.left = r.left;
if (r.right > rct.right) rct.right = r.right;
if (r.top < rct.top) rct.top = r.top;
if (r.bottom > rct.bottom) rct.bottom = r.bottom;
}
}
}
return full;
}
void TReport_window::offset_selection(const TPoint& p)
{
TReport_section& rs = curr_section();
FOR_EACH_ARRAY_ITEM(rs, i, o)
{
TReport_field& f = *(TReport_field*)o;
if (f.selected())
f.offset(p);
}
}
void TReport_window::select(const RCT& rct)
{
clear_selection();
TReport_section& rs = curr_section();
FOR_EACH_ARRAY_ITEM(rs, i, o)
{
TReport_field& f = *(TReport_field*)o;
RCT r; f.get_rect(r);
if (xvt_rect_intersect(NULL, (RCT*)&rct, &r))
f.select();
}
}
void TReport_window::draw_dragster()
{
set_mode(M_XOR);
set_pen(COLOR_CYAN);
xvt_dwin_draw_rect(win(), &_rct_drag);
set_mode(M_COPY);
}
void TReport_window::handler(WINDOW win, EVENT* ep)
{
switch (ep->type)
{
case E_MOUSE_DOWN:
{
const TPoint pt = dev2log(ep->v.mouse.where);
const PNT p = { short(pt.y), short(pt.x) };
RCT rct;
bool full = get_selection_rect(rct);
if (!full || !xvt_rect_has_point(&rct, p))
{
if (full)
clear_selection();
pick(ep->v.mouse.where);
full = get_selection_rect(rct);
}
if (full)
{
log2dev(rct, _rct_drag);
_pt_drag_offset.h = ep->v.mouse.where.h - _rct_drag.left;
_pt_drag_offset.v = ep->v.mouse.where.v - _rct_drag.top;
_dragging = 2;
}
else
{
const PNT& pnt = ep->v.mouse.where;
xvt_rect_set(&_rct_drag, pnt.h, pnt.v, pnt.h, pnt.v);
_dragging = 1;
}
_pt_drag_start.x = rct.left;
_pt_drag_start.y = rct.top;
draw_dragster();
xvt_win_trap_pointer(win);
}
break;
case E_MOUSE_MOVE:
{
int k, kx, ky; scaling(k, kx, ky);
TMask& m = owner().mask();
const TPoint p = dev2log(ep->v.mouse.where);
m.set(F_X, p.x/k+1);
m.set(F_Y, p.y/k+1);
if (_dragging != 0)
{
draw_dragster();
PNT pt = ep->v.mouse.where;
switch (_dragging)
{
case 1:
_rct_drag.right = pt.h;
_rct_drag.bottom = pt.v;
break;
case 2:
pt.h -= _pt_drag_offset.h; pt.v -= _pt_drag_offset.v;
if (!ep->v.mouse.shift)
{
pt.h = (pt.h / kx) * kx;
pt.v = (pt.v / ky) * ky;
}
xvt_rect_set_pos(&_rct_drag, pt);
break;
default:
break;
}
draw_dragster();
}
}
break;
case E_MOUSE_UP:
if (_dragging != 0)
{
draw_dragster();
PNT pt = ep->v.mouse.where;
switch (_dragging)
{
case 1:
{
_rct_drag.right = pt.h;
_rct_drag.bottom = pt.v;
RCT rct; dev2log(_rct_drag, rct);
select(rct);
}
break;
case 2:
{
pt.h -= _pt_drag_offset.h; pt.v -= _pt_drag_offset.v;
int k, kx, ky; scaling(k, kx, ky);
if (!ep->v.mouse.shift)
{
pt.h = (pt.h / kx) * kx;
pt.v = (pt.v / ky) * ky;
}
TPoint offset = dev2log(pt);
offset.x -= _pt_drag_start.x;
offset.y -= _pt_drag_start.y;
offset_selection(offset);
}
break;
default:
break;
}
force_update();
_dragging = 0;
xvt_win_release_pointer();
}
break;
default:
break;
}
TField_window::handler(win, ep);
}
PNT TReport_window::log2dev(long x, long y) const
{
int k, kx, ky; scaling(k, kx, ky);
x -= k*origin().x;
y -= k*origin().y;
PNT p;
p.h = short(x * kx / k);
p.v = short(y * ky / k);
return p;
}
TPoint TReport_window::dev2log(const PNT& pt) const
{
int k, kx, ky; scaling(k, kx, ky);
TPoint p;
p.x = pt.h * k / kx + k*origin().x;
p.y = pt.v * k / ky + k*origin().y;
return p;
}
void TReport_window::log2dev(const RCT& rctlog, RCT& rctdev) const
{
const PNT f = log2dev(rctlog.left, rctlog.top);
const PNT t = log2dev(rctlog.right, rctlog.bottom);
rctdev.left = f.h; rctdev.top = f.v;
rctdev.right = t.h; rctdev.bottom = t.v;
}
void TReport_window::dev2log(const RCT& rctdev, RCT& rctlog) const
{
const PNT pf = { rctdev.top, rctdev.left };
const PNT pt = { rctdev.bottom, rctdev.right };
const TPoint f = dev2log(pf);
const TPoint t = dev2log(pt);
rctlog.left = short(f.x); rctlog.top = short(f.y);
rctlog.right = short(t.x); rctlog.bottom = short(t.y);
}
void TReport_window::draw_grid()
{
int k, kx, ky; scaling(k, kx, ky);
// Draw grid
clear(COLOR_WHITE);
set_pen(MAKE_COLOR(232,232,232));
RCT rct; xvt_vobj_get_client_rect(win(), &rct);
const int max = rct.right / kx;
const int x = origin().x;
const int y = origin().y;
for (int i = 1; i < max; i++)
{
line(x*k, (y+i)*k, (x+max)*k, (y+i)*k);
line((x+i)*k, y*k, (x+i)*k, (y+max)*k);
}
}
void TReport_window::update()
{
draw_grid();
draw_fields();
}
TReport_window::TReport_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner)
: TField_window(x, y, dx, dy, parent, owner), _zoom(10), _dragging(0)
{
_pixmap = true;
set_scroll_max(196,196);
}
class TReport_drawer : public TWindowed_field
{
protected:
virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent);
public:
TReport_drawer(TMask* m) : TWindowed_field(m) { }
};
TField_window* TReport_drawer::create_window(int x, int y, int dx, int dy, WINDOW parent)
{
return new TReport_window(x, y, dx, dy, parent, this);
}
///////////////////////////////////////////////////////////
// TReport_printer
///////////////////////////////////////////////////////////
class TReport_printer : public TObject
{
const TString& _name;
const TString& _sql;
TSection_tree& _tree;
long _pw, _ph, _phr, _pvr; // Printer width, height, horizontal and vertical resolution
word _copies;
word _pagefrom;
word _pageto;
bool _aborted;
public:
bool print_copies(); // caallback do NOT use;
bool aborted() const { return _aborted; }
bool edit();
bool print();
TReport_printer(const TString& name, const TString& sql, TSection_tree& t);
virtual ~TReport_printer();
};
bool TReport_printer::edit()
{
_tree.goto_root();
TReport_section& rs = _tree.curr_section();
TPrinter& p = printer();
TMask msk("bagn003");
msk.set(F_PRINTER, p.printername());
msk.set(F_FORM, _name);
msk.set(F_FONT, rs.font().name());
msk.set(F_SIZE, rs.font().size());
msk.set(F_ISGRAPHICS, p.isgraphics() ? "X" : "");
msk.set(F_FROMPAGE, _pagefrom);
msk.set(F_TOPAGE, _pageto);
msk.set(F_COPIES, _copies);
const bool ok = msk.run() == K_ENTER;
if (ok)
{
_copies = msk.get_int(F_COPIES);
_pagefrom = msk.get_int(F_FROMPAGE);
_pageto = msk.get_int(F_TOPAGE);
if (_pageto < _pagefrom)
_pageto = 0;
}
return ok;
}
bool TReport_printer::print_copies()
{
TSQL_query qry(_sql);
const TRecnotype items = qry.items();
bool ok = items > 0;
for (int copia = 0; ok && copia < _copies; copia++)
{
xvt_print_open();
xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, printer().get_printrcd(), &_ph, &_pw, &_pvr, &_phr);
xvt_print_close();
}
return ok;
}
BOOLEAN print_callback(long jolly)
{
TReport_printer* rp = (TReport_printer*)jolly;
return rp->print_copies();
}
bool TReport_printer::print()
{
_aborted = false;
xvt_print_start_thread(print_callback, (long)this);
return !aborted();
}
TReport_printer::TReport_printer(const TString& n, const TString& sql, TSection_tree& t)
: _name(n), _sql(sql), _tree(t), _copies(1), _pagefrom(1), _pageto(0), _aborted(false)
{
}
TReport_printer::~TReport_printer()
{
}
///////////////////////////////////////////////////////////
// TReport_mask
///////////////////////////////////////////////////////////
TMask_field* TReport_mask::parse_field(TScanner& scanner)
{
if (scanner.token().starts_with("RE"))
return new TReport_drawer(this);
return TAutomask::parse_field(scanner);
}
bool TReport_mask::select_report()
{
TFilename path;
const bool ok = select_sql_file(path, "rep");
if (ok)
{
path = path.name(); path.ext("");
set(F_CODICE, path);
}
return ok;
}
bool TReport_mask::select_query()
{
TFilename path;
bool ok = select_sql_file(path, "qry");
if (ok)
{
TXmlItem item; item.Load(path);
const TXmlItem* sql = item.FindFirst("sql");
ok = sql != NULL;
if (ok)
{
TString str; sql->GetEnclosedText(str);
set(F_SQL, str, true);
}
}
return ok;
}
static BOOLEAN print_page(long jolly)
{
return FALSE;
}
void TReport_mask::on_print()
{
TReport_printer rp(get(F_CODICE), get(F_SQL), _tree);
if (rp.edit())
{
xvt_print_start_thread(print_page, long(&rp));
}
}
bool TReport_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_CODICE:
if (e == fe_button)
select_report();
break;
case F_SECTIONS:
if (e == fe_modify)
((TReport_drawer&)field(F_REPORT)).win().force_update();
break;
case F_SQL:
if (e == fe_init || e == fe_modify)
enable(F_SHOW_QRY, !o.empty());
break;
case F_NEW_QRY:
if (e == fe_button)
{
TExternal_app q("ba8 -1");
q.run();
}
break;
case F_IMPORT_QRY:
if (e == fe_button)
select_query();
break;
case F_SHOW_QRY:
if (e == fe_button)
{
TSQL_query qry(get(F_SQL));
if (qry.columns() > 0)
{
TQuery_sheet sheet(qry);
sheet.run();
}
}
break;
case DLG_PRINT:
if (e == fe_button)
{
on_print();
return false;
}
break;
default:
break;
}
return true;
}
TReport_mask::TReport_mask()
{
read_mask("ba8300a", 0, -1);
set_handlers();
TTree_field& albero = tfield(F_SECTIONS);
RCT rct_sec; albero.get_rect(rct_sec);
RCT rct_rep; field(F_REPORT).get_rect(rct_rep);
rct_rep.left = rct_sec.right+ROWY;
rct_rep.right -= ROWY;
rct_rep.bottom -= ROWY;
field(F_REPORT).set_rect(rct_rep);
TString body_id, tail_id;
_tree.add_node("Report");
for (int i = 1; i <= 4; i++)
{
if (body_id.not_empty())
_tree.goto_node(body_id);
const char* name[3] = { "Testa", "Corpo", "Coda" };
TString16 bodyn;
for (int j = 0; j < 3; j++)
{
bodyn.format(" %s %d", name[j], i);
switch(j)
{
case 0:
_tree.add_node(bodyn, 'H', i);
break;
case 1:
_tree.add_rnode(bodyn, 'B', i);
_tree.curr_id(body_id);
if (i == 1)
{
TReport_section& sec = _tree.curr_section();
for (short k = 0; k < 12; k+=1)
{
TReport_field* rf = new TReport_field(&sec);
rf->set_pos(k*100, k*100);
sec.add(rf);
}
}
break;
case 2:
_tree.add_rnode(bodyn, 'F', i);
if (tail_id.empty())
_tree.curr_id(tail_id);
break;
default:
break;
}
}
}
_tree.goto_node(tail_id);
_tree.add_rnode(" Pagina");
_tree.add_node(" Testa", 'H', 0);
_tree.add_rnode(" Corpo", 'B', 0);
_tree.add_rnode(" Coda", 'F', 0);
const int ih = _tree.image_height();
if (ih > CHARY)
albero.set_row_height(ih);
albero.set_tree(&_tree);
_tree.goto_root();
_tree.expand();
}
///////////////////////////////////////////////////////////
// TReporter_app
///////////////////////////////////////////////////////////
class TReporter_app : public TSkeleton_application
{
protected:
virtual void main_loop();
};
void TReporter_app::main_loop()
{
TReport_mask* msk = new TReport_mask;
msk->run();
delete msk;
}
int ba8300(int argc, char* argv[])
{
TReporter_app app;
app.run(argc, argv, TR("Report Generator"));
return 0;
}