Files correlati : ba8.exe Ricompilazione Demo : [ ] Commento : Risolti conflitti vari e spostate funzioni in cpp piu' consoni git-svn-id: svn://10.65.10.50/trunk@11862 c028cbd2-c16b-5b4b-a496-9718f37d4682
705 lines
15 KiB
C++
Executable File
705 lines
15 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 "ba8301.h"
|
|
#include <bagn003.h>
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_tree
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TReport_tree_node : public TObject
|
|
{
|
|
TReport_section& _sec;
|
|
|
|
public:
|
|
TReport_section& section() { return _sec; }
|
|
TReport_tree_node(TReport_section& sec) : _sec(sec) { }
|
|
};
|
|
|
|
class TReport_tree : public TObject_tree
|
|
{
|
|
TReport& _report;
|
|
|
|
protected:
|
|
bool get_description(TString& str) const;
|
|
TImage* image(bool selected) const;
|
|
|
|
public:
|
|
TReport_section& curr_section() const { return ((TReport_tree_node*)curr_node())->section(); }
|
|
|
|
void add_node(char t, int l = 0)
|
|
{ add_son(new TReport_tree_node(_report.section(t, l))); }
|
|
void add_rnode(char t, int l = 0)
|
|
{ add_rbrother(new TReport_tree_node(_report.section(t, l))); }
|
|
|
|
int image_height() const;
|
|
TReport_tree(TReport& r) : _report(r) { }
|
|
};
|
|
|
|
bool TReport_tree::get_description(TString& str) const
|
|
{
|
|
curr_section().description(str);
|
|
str.insert(" ");
|
|
return true;
|
|
}
|
|
|
|
TImage* TReport_tree::image(bool selected) const
|
|
{
|
|
const TReport_section& rs = curr_section();
|
|
|
|
int id = 0;
|
|
switch (rs.type())
|
|
{
|
|
case 'H': id = 1810; break;
|
|
case 'B': id = 1811; break;
|
|
case 'F': id = 1812; break;
|
|
default : break;
|
|
}
|
|
if (id > 0)
|
|
return get_res_image(id);
|
|
return TObject_tree::image(selected);
|
|
}
|
|
|
|
int TReport_tree::image_height() const
|
|
{
|
|
const TImage* img = image(false);
|
|
return img != NULL ? img->height() : 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_window
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TReport_window : public TField_window
|
|
{
|
|
TReport* _report;
|
|
PNT _dpi;
|
|
|
|
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_square(int x, int y, int dx, int dy);
|
|
void draw_field(const TReport_field& f);
|
|
void draw_grid();
|
|
void draw_fields();
|
|
void snap_drag(PNT& pnt) const;
|
|
void draw_dragster();
|
|
|
|
int cpi() const;
|
|
int lpi() const;
|
|
|
|
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;
|
|
TReport_section& curr_section() const;
|
|
|
|
bool get_selection_rect(RCT& rct) const;
|
|
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_section& TReport_window::curr_section() const
|
|
{
|
|
TMask& m = owner().mask();
|
|
TTree_field& sections = m.tfield(F_SECTIONS);
|
|
sections.goto_selected();
|
|
TReport_tree& tree = *(TReport_tree*)sections.tree();
|
|
return tree.curr_section();
|
|
}
|
|
|
|
void TReport_window::draw_square(int x, int y, int dx, int dy)
|
|
{
|
|
RCT rct; rct.left = x; rct.top = y; rct.right = x+dx; rct.bottom = y+dy;
|
|
xvt_dwin_draw_rect(win(), &rct);
|
|
}
|
|
|
|
void TReport_window::draw_field(const TReport_field& f)
|
|
{
|
|
set_pen(f.color());
|
|
RCT r; f.get_rect(r);
|
|
log2dev(r, r);
|
|
|
|
if (f.type() != 'L')
|
|
{
|
|
set_brush(COLOR_WHITE, PAT_HOLLOW);
|
|
xvt_dwin_draw_rect(win(), &r);
|
|
}
|
|
|
|
switch (f.type())
|
|
{
|
|
case 'L':
|
|
break;
|
|
case 'D':
|
|
case 'N':
|
|
case 'S':
|
|
case 'T':
|
|
{
|
|
set_color(f.color(), COLOR_WHITE);
|
|
XVT_FNTID fid = f.font().get_xvt_font(win(), _dpi.h);
|
|
xvt_dwin_set_font(win(), fid);
|
|
const int delta = (r.bottom-r.top)/4;
|
|
xvt_dwin_draw_text(win(), r.left, r.bottom-delta, f.picture(), -1);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (f.type() != 'L' && f.selected())
|
|
{
|
|
set_pen(COLOR_BLACK);
|
|
set_brush(COLOR_BLACK);
|
|
const int s = 5;
|
|
draw_square(r.left, r.top, s, s);
|
|
draw_square(r.right-s, r.top, s, s);
|
|
draw_square(r.right-s, r.bottom-s, s, s);
|
|
draw_square(r.left, r.bottom-s, s, s);
|
|
}
|
|
}
|
|
|
|
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;
|
|
draw_field(f);
|
|
}
|
|
}
|
|
|
|
bool TReport_window::pick(const PNT& p) const
|
|
{
|
|
TReport_section& rs = curr_section();
|
|
RCT rct;
|
|
|
|
const TPoint ptlog = dev2log(p);
|
|
const PNT pt = { short(ptlog.y), short(ptlog.x) };
|
|
FOR_EACH_ARRAY_ITEM(rs, i, o)
|
|
{
|
|
TReport_field& f = *(TReport_field*)o;
|
|
f.get_rect(rct);
|
|
if (xvt_rect_has_point(&rct, pt))
|
|
{
|
|
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::snap_drag(PNT& pnt) const
|
|
{
|
|
const int kx = _dpi.h / cpi();
|
|
const int ky = _dpi.v / lpi();
|
|
pnt.h = (pnt.h / kx) * kx;
|
|
pnt.v = (pnt.v / ky) * ky;
|
|
}
|
|
|
|
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;
|
|
XinCursor hand = xi_get_pref(XI_PREF_HAND_CURSOR_RID);
|
|
xvt_win_set_cursor(win, (CURSOR)hand);
|
|
}
|
|
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:
|
|
{
|
|
TMask& m = owner().mask();
|
|
const TPoint p = dev2log(ep->v.mouse.where);
|
|
m.set(F_X, p.x/100);
|
|
m.set(F_Y, p.y/100);
|
|
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)
|
|
snap_drag(pt);
|
|
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;
|
|
if (!ep->v.mouse.shift)
|
|
snap_drag(pt);
|
|
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();
|
|
xvt_win_set_cursor(win, CURSOR_ARROW);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
TField_window::handler(win, ep);
|
|
}
|
|
|
|
PNT TReport_window::log2dev(long x, long y) const
|
|
{
|
|
x -= origin().x*100;
|
|
y -= origin().y*100;
|
|
PNT p;
|
|
p.h = short((x * _dpi.h) / (cpi() * 100L));
|
|
p.v = short((y * _dpi.v) / (lpi() * 100L));
|
|
return p;
|
|
}
|
|
|
|
TPoint TReport_window::dev2log(const PNT& pt) const
|
|
{
|
|
TPoint p;
|
|
p.x = pt.h * 100L * cpi() / _dpi.h;
|
|
p.y = pt.v * 100L * lpi() / _dpi.v;
|
|
p.x += origin().x * 100L;
|
|
p.y += origin().y * 100L;
|
|
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()
|
|
{
|
|
clear(COLOR_WHITE);
|
|
set_pen(MAKE_COLOR(232,232,232));
|
|
|
|
RCT rct; xvt_vobj_get_client_rect(win(), &rct);
|
|
const int max = 192;
|
|
const int kx = 100;
|
|
const int ky = 100;
|
|
for (int i = 1; i < max; i++)
|
|
{
|
|
line(0, i*ky, max*kx, i*ky);
|
|
line(i*kx, 0, i*kx, max*ky);
|
|
}
|
|
}
|
|
|
|
void TReport_window::update()
|
|
{
|
|
draw_grid();
|
|
draw_fields();
|
|
}
|
|
|
|
int TReport_window::cpi() const
|
|
{ return _report ? _report->cpi() : 12; }
|
|
|
|
int TReport_window::lpi() const
|
|
{ return _report ? _report->lpi() : 6; }
|
|
|
|
|
|
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), _dragging(0), _report(NULL)
|
|
{
|
|
_dpi.h = _dpi.v = 96;
|
|
_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_mask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TReport_mask : public TAutomask
|
|
{
|
|
TReport _report;
|
|
TReport_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:
|
|
TReport_tree& sections() { return _tree; }
|
|
|
|
TReport_mask();
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// 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;
|
|
}
|
|
|
|
void TReport_mask::on_print()
|
|
{
|
|
}
|
|
|
|
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() : _tree(_report)
|
|
{
|
|
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('R', 0);
|
|
|
|
for (int i = 1; i <= 4; i++)
|
|
{
|
|
if (body_id.not_empty())
|
|
_tree.goto_node(body_id);
|
|
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
switch(j)
|
|
{
|
|
case 0:
|
|
_tree.add_node('H', i);
|
|
break;
|
|
case 1:
|
|
_tree.add_rnode('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('F', i);
|
|
if (tail_id.empty())
|
|
_tree.curr_id(tail_id);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
_tree.goto_node(tail_id);
|
|
_tree.add_rnode('P', 0);
|
|
_tree.add_node('H', 0);
|
|
_tree.add_rnode('B', 0);
|
|
_tree.add_rnode('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;
|
|
}
|