2e17ac6800
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
1014 lines
23 KiB
C++
Executable File
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;
|
|
}
|