Files correlati : ba8.exe Ricompilazione Demo : [ ] Commento : Salvataggio situazione attuale generazione report: stato avanzamento lavori 50% git-svn-id: svn://10.65.10.50/trunk@11899 c028cbd2-c16b-5b4b-a496-9718f37d4682
1715 lines
37 KiB
C++
Executable File
1715 lines
37 KiB
C++
Executable File
#include <xi.h>
|
|
|
|
#include <applicat.h>
|
|
#include <automask.h>
|
|
#include <colors.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 : public TBidirectional_tree
|
|
{
|
|
TReport& _report;
|
|
TString4 _curr;
|
|
|
|
protected:
|
|
virtual bool get_description(TString& str) const;
|
|
virtual TImage* image(bool selected) const;
|
|
virtual void node2id(const TObject* node, TString& id) const;
|
|
|
|
public:
|
|
virtual bool goto_root();
|
|
virtual bool goto_firstson();
|
|
virtual bool goto_rbrother();
|
|
virtual bool goto_node(const TString &id);
|
|
virtual bool has_son() const;
|
|
virtual bool has_rbrother() const;
|
|
virtual TObject* curr_node() const { return (TObject*)&_curr; }
|
|
|
|
virtual bool has_root() const;
|
|
virtual bool has_father() const;
|
|
virtual bool has_lbrother() const;
|
|
virtual bool goto_father();
|
|
virtual bool goto_lbrother();
|
|
|
|
TReport_section& curr_section() const;
|
|
bool goto_node(char type, int level);
|
|
|
|
int image_height() const;
|
|
TReport_tree(TReport& r) : _report(r) { goto_root(); }
|
|
};
|
|
|
|
bool TReport_tree::get_description(TString& str) const
|
|
{
|
|
str.cut(0);
|
|
switch (_curr[0])
|
|
{
|
|
case 'H': str << " " << TR("Testa"); break;
|
|
case 'B': str << " " << TR("Corpo"); break;
|
|
case 'F': str << " " << TR("Coda"); break;
|
|
case 'P': str << TR("Pagina"); break; // Virtual section
|
|
case 'R': str << TR("Report"); break; // Virtual section
|
|
default : break;
|
|
}
|
|
if (_curr[1] > '0')
|
|
str << ' ' << _curr[1];
|
|
return true;
|
|
}
|
|
|
|
bool TReport_tree::goto_node(char type, int level)
|
|
{
|
|
const bool ok = type > ' ' && level >= 0;
|
|
if (ok)
|
|
_curr.format("%c%d", type, level);
|
|
return ok;
|
|
}
|
|
|
|
void TReport_tree::node2id(const TObject* node, TString& id) const
|
|
{
|
|
id = *(TString*)node;
|
|
}
|
|
|
|
TReport_section& TReport_tree::curr_section() const
|
|
{
|
|
char type = _curr[0];
|
|
const int level = _curr[1]-'0';
|
|
if (type == 'R' || type == 'P')
|
|
type = 'B';
|
|
return _report.section(type, level);
|
|
}
|
|
|
|
bool TReport_tree::goto_root()
|
|
{
|
|
return goto_node('P', 0);
|
|
}
|
|
|
|
bool TReport_tree::goto_firstson()
|
|
{
|
|
int nlevel = -1;
|
|
switch (_curr[0])
|
|
{
|
|
case 'P': nlevel = 0; break;
|
|
case 'R': nlevel = _report.find_max_level(); break;
|
|
default : break;
|
|
}
|
|
return goto_node('H', nlevel);
|
|
}
|
|
|
|
bool TReport_tree::goto_rbrother()
|
|
{
|
|
const char type = _curr[0];
|
|
const int level = _curr[1]-'0';
|
|
char ntype = ' ';
|
|
int nlevel = -1;
|
|
if (level <= 0) // Page
|
|
{
|
|
switch (type)
|
|
{
|
|
case 'H': ntype = 'B'; break;
|
|
case 'B': ntype = 'F'; break;
|
|
case 'P': ntype = 'R'; break;
|
|
default : break;
|
|
}
|
|
nlevel = level;
|
|
}
|
|
else // Report
|
|
{
|
|
switch (type)
|
|
{
|
|
case 'H':
|
|
if (level > 1)
|
|
{
|
|
ntype = type;
|
|
nlevel = level-1;
|
|
}
|
|
else
|
|
{
|
|
ntype = 'B';
|
|
nlevel = 1;
|
|
}
|
|
break;
|
|
case 'B':
|
|
ntype = 'F';
|
|
nlevel = 1;
|
|
break;
|
|
case 'F':
|
|
if (level < _report.find_max_level())
|
|
{
|
|
ntype = 'F';
|
|
nlevel = level+1;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return goto_node(ntype, nlevel);
|
|
}
|
|
|
|
bool TReport_tree::goto_node(const TString &id)
|
|
{
|
|
return goto_node(id[0], id[1]-'0');
|
|
}
|
|
|
|
bool TReport_tree::has_son() const
|
|
{
|
|
const char type = _curr[0];
|
|
return type == 'P' || type == 'R';
|
|
}
|
|
|
|
bool TReport_tree::has_rbrother() const
|
|
{
|
|
const TString4 old = _curr;
|
|
TReport_tree* myself = (TReport_tree*)this;
|
|
const bool ok = myself->goto_rbrother();
|
|
myself->_curr = old;
|
|
return ok;
|
|
}
|
|
|
|
bool TReport_tree::has_root() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool TReport_tree::has_father() const
|
|
{
|
|
return !has_son();
|
|
}
|
|
|
|
bool TReport_tree::goto_father()
|
|
{
|
|
return has_father() && goto_node(_curr[1] == '0' ? 'P' : 'R', 0);
|
|
}
|
|
|
|
bool TReport_tree::has_lbrother() const
|
|
{
|
|
const TString4 old = _curr;
|
|
TReport_tree* myself = (TReport_tree*)this;
|
|
const bool ok = myself->goto_lbrother();
|
|
myself->_curr = old;
|
|
return ok;
|
|
}
|
|
|
|
bool TReport_tree::goto_lbrother()
|
|
{
|
|
const char type = _curr[0];
|
|
const int level = _curr[1]-'0';
|
|
char ntype = ' ';
|
|
int nlevel = -1;
|
|
if (level == 0) // Page
|
|
{
|
|
if (type == 'B')
|
|
ntype = 'H'; else
|
|
if (type == 'F')
|
|
ntype = 'B'; else
|
|
if (type == 'R')
|
|
ntype = 'P';
|
|
}
|
|
else // Report
|
|
{
|
|
switch (type)
|
|
{
|
|
case 'F':
|
|
if (level > 1)
|
|
{
|
|
ntype = type;
|
|
nlevel = level-1;
|
|
}
|
|
else
|
|
{
|
|
ntype = 'B';
|
|
nlevel = 1;
|
|
}
|
|
break;
|
|
case 'B':
|
|
ntype = 'H';
|
|
nlevel = 1;
|
|
break;
|
|
case 'H':
|
|
if (level < _report.find_max_level())
|
|
{
|
|
ntype = 'F';
|
|
nlevel = level+1;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return goto_node(ntype, nlevel);
|
|
}
|
|
|
|
TImage* TReport_tree::image(bool selected) const
|
|
{
|
|
int id = 0;
|
|
switch (_curr[0])
|
|
{
|
|
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 TTree::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;
|
|
|
|
TArray _clipboard;
|
|
|
|
protected:
|
|
virtual void handler(WINDOW win, EVENT* ep);
|
|
virtual void update();
|
|
virtual bool on_key(KEY k);
|
|
|
|
protected:
|
|
void draw_square(int x, int y, int s);
|
|
void draw_field(const TReport_field& f);
|
|
void draw_grid();
|
|
void draw_fields();
|
|
void snap_drag(PNT& pnt) const;
|
|
void draw_dragster();
|
|
|
|
void popup_menu(EVENT* ep);
|
|
void popup_cut();
|
|
void popup_copy();
|
|
void popup_paste();
|
|
|
|
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 TPoint& ptlog) const;
|
|
void clear_selection();
|
|
void select(const RCT& rct);
|
|
void offset_selection(const TPoint& p);
|
|
|
|
void set_report(TReport* rep) { _report = rep; }
|
|
|
|
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 s)
|
|
{
|
|
RCT rct; rct.left = x; rct.top = y; rct.right = x+s; rct.bottom = y+s;
|
|
xvt_dwin_draw_rect(win(), &rct);
|
|
}
|
|
|
|
void TReport_window::draw_field(const TReport_field& f)
|
|
{
|
|
RCT r; f.get_rect(r);
|
|
log2dev(r, r);
|
|
|
|
switch (f.type())
|
|
{
|
|
case 'D':
|
|
case 'N':
|
|
case 'S':
|
|
case 'T':
|
|
if (f.border() <= 0)
|
|
{
|
|
set_pen(COLOR_LTGRAY);
|
|
set_brush(f.back_color(), PAT_NONE);
|
|
xvt_dwin_draw_rect(win(), &r);
|
|
}
|
|
f.draw_text(*this, f.picture());
|
|
break;
|
|
default : f.draw(*this); break;
|
|
}
|
|
|
|
if (f.selected())
|
|
{
|
|
set_pen(COLOR_BLACK);
|
|
set_brush(COLOR_BLACK);
|
|
const int s = 5;
|
|
draw_square(r.left, r.top, s);
|
|
draw_square(r.right-s, r.bottom-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 TPoint& ptlog) const
|
|
{
|
|
TReport_section& rs = curr_section();
|
|
RCT rct;
|
|
|
|
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);
|
|
set_brush(COLOR_WHITE, PAT_NONE);
|
|
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;
|
|
}
|
|
|
|
bool TReport_window::on_key(KEY k)
|
|
{
|
|
switch (k)
|
|
{
|
|
case K_ENTER:
|
|
owner().mask().send_key(K_SPACE, F_FLD_PROPERTIES);
|
|
break;
|
|
case K_ESC:
|
|
{
|
|
TReport_section& rs = curr_section();
|
|
FOR_EACH_ARRAY_ITEM(rs, i, o)
|
|
{
|
|
TReport_field& f = *(TReport_field*)o;
|
|
if (f.selected())
|
|
f.select(false);
|
|
}
|
|
force_update();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return TField_window::on_key(k);
|
|
}
|
|
|
|
#define POPUP_CUT 20883
|
|
#define POPUP_COPY 20884
|
|
#define POPUP_PASTE 20885
|
|
#define POPUP_DUP 20886
|
|
#define POPUP_CLEAR 20887
|
|
#define POPUP_PROPERTIES 20888
|
|
|
|
void TReport_window::popup_menu(EVENT* ep)
|
|
{
|
|
MENU_ITEM menu[8];
|
|
memset(menu, 0, sizeof(menu));
|
|
|
|
RCT rct;
|
|
const bool sel = get_selection_rect(rct);
|
|
const bool clp = _clipboard.items() > 0;
|
|
|
|
menu[0].tag = POPUP_CUT; menu[0].text = "Taglia"; menu[0].enabled = sel;
|
|
menu[1].tag = POPUP_COPY; menu[1].text = "Copia"; menu[1].enabled = sel;
|
|
menu[2].tag = POPUP_PASTE; menu[2].text = "Incolla"; menu[2].enabled = clp;
|
|
menu[3].tag = POPUP_DUP; menu[3].text = "Duplica"; menu[3].enabled = sel;
|
|
menu[4].tag = POPUP_CLEAR; menu[4].text = "Cancella"; menu[4].enabled = sel;
|
|
menu[5].tag = -1; menu[5].separator = true;
|
|
menu[6].tag = POPUP_PROPERTIES; menu[6].text = "Proprieta'"; menu[6].enabled = true;
|
|
|
|
const PNT& p = ep->v.mouse.where;
|
|
_pt_drag_start = dev2log(p);
|
|
xvt_menu_popup(menu, win(), p, XVT_POPUP_CENTER, 0);
|
|
}
|
|
|
|
void TReport_window::popup_cut()
|
|
{
|
|
_clipboard.destroy();
|
|
TReport_section& rs = curr_section();
|
|
FOR_EACH_ARRAY_ITEM_BACK(rs, i, o)
|
|
{
|
|
TReport_field& f = *(TReport_field*)o;
|
|
if (f.selected())
|
|
{
|
|
TObject* obj = rs.remove(i, true);
|
|
_clipboard.add(obj);
|
|
}
|
|
}
|
|
force_update();
|
|
}
|
|
|
|
void TReport_window::popup_copy()
|
|
{
|
|
_clipboard.destroy();
|
|
TReport_section& rs = curr_section();
|
|
FOR_EACH_ARRAY_ITEM(rs, i, o)
|
|
{
|
|
TReport_field& f = *(TReport_field*)o;
|
|
if (f.selected())
|
|
_clipboard.add(f);
|
|
}
|
|
}
|
|
|
|
void TReport_window::popup_paste()
|
|
{
|
|
if (_clipboard.items() > 0)
|
|
{
|
|
RCT rct;
|
|
((TReport_field&)_clipboard[0]).get_rect(rct);
|
|
const TPoint off(_pt_drag_start.x-rct.left, _pt_drag_start.y-rct.top);
|
|
clear_selection();
|
|
TReport_section& rs = curr_section();
|
|
FOR_EACH_ARRAY_ITEM(_clipboard, i, o)
|
|
{
|
|
TReport_field& f = *(TReport_field*)o;
|
|
f.set_section(&rs);
|
|
f.select();
|
|
f.offset(off);
|
|
rs.add(f);
|
|
}
|
|
force_update();
|
|
}
|
|
}
|
|
|
|
void TReport_window::handler(WINDOW win, EVENT* ep)
|
|
{
|
|
switch (ep->type)
|
|
{
|
|
case E_MOUSE_DOWN:
|
|
if (ep->v.mouse.button == 0)
|
|
{
|
|
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(pt);
|
|
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);
|
|
}
|
|
else
|
|
{
|
|
popup_menu(ep);
|
|
}
|
|
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;
|
|
case E_MOUSE_DBL:
|
|
owner().mask().send_key(K_SPACE, F_FLD_PROPERTIES);
|
|
break;
|
|
case E_COMMAND:
|
|
switch(ep->v.cmd.tag)
|
|
{
|
|
case POPUP_CUT:
|
|
case POPUP_CLEAR:
|
|
popup_cut();
|
|
break;
|
|
case POPUP_COPY:
|
|
popup_copy();
|
|
break;
|
|
case POPUP_PASTE:
|
|
popup_paste();
|
|
break;
|
|
case POPUP_DUP:
|
|
popup_copy();
|
|
popup_paste();
|
|
break;
|
|
case POPUP_PROPERTIES:
|
|
{
|
|
clear_selection();
|
|
const bool full = pick(_pt_drag_start);
|
|
if (full)
|
|
owner().mask().send_key(K_SPACE, F_FLD_PROPERTIES);
|
|
else
|
|
owner().mask().send_key(K_SPACE, F_SEC_PROPERTIES);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
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 k = 100;
|
|
for (int i = 1; i < max; i++)
|
|
{
|
|
line(0, i*k, max*k, i*k);
|
|
line(i*k, 0, i*k, max*k);
|
|
}
|
|
}
|
|
|
|
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:
|
|
void set_report(TReport* rep);
|
|
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);
|
|
}
|
|
|
|
void TReport_drawer::set_report(TReport* rep)
|
|
{
|
|
TReport_window* w = (TReport_window*)_win;
|
|
w->set_report(rep);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Utility
|
|
///////////////////////////////////////////////////////////
|
|
|
|
const TString& num2str(int num)
|
|
{
|
|
static TString8 _str;
|
|
|
|
const real n(num / 100.0);
|
|
_str = n.stringa(0, 2);
|
|
const int comma = _str.find(',');
|
|
if (comma > 0)
|
|
{
|
|
if (_str[comma+2] == '0')
|
|
{
|
|
if (_str[comma+1] == '0')
|
|
_str.cut(comma);
|
|
else
|
|
_str.cut(comma+2);
|
|
}
|
|
}
|
|
return _str;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_field_mask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TReport_field_mask : public TAutomask
|
|
{
|
|
COLOR _fgcolor, _bgcolor;
|
|
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
virtual void handler(WINDOW win, EVENT* ep);
|
|
|
|
public:
|
|
void set_num(short id, short n);
|
|
short get_num(short id) const;
|
|
|
|
void set_field(const TReport_field& rf);
|
|
void get_field(TReport_field& rf) const;
|
|
|
|
TReport_field_mask() :TAutomask("ba8300b") { }
|
|
};
|
|
|
|
void TReport_field_mask::set_num(short id, short num)
|
|
{
|
|
set(id, num2str(num));
|
|
}
|
|
|
|
short TReport_field_mask::get_num(short id) const
|
|
{
|
|
TString8 str = get(id);
|
|
str.replace(',', '.');
|
|
real n(str);
|
|
n *= CENTO;
|
|
return (short)n.integer();
|
|
}
|
|
|
|
void TReport_field_mask::handler(WINDOW win, EVENT* ep)
|
|
{
|
|
if (ep->type == E_UPDATE)
|
|
{
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
RCT rct; field(i == 0 ? F_FGCOLOR : F_BGCOLOR).get_rect(rct);
|
|
xvt_rect_offset(&rct, rct.right-rct.left + 4*CHARX, 0);
|
|
xi_draw_3d_rect((XinWindow)win, (XinRect*)&rct, TRUE, 2, MASK_LIGHT_COLOR,
|
|
i == 0 ? _fgcolor : _bgcolor, MASK_DARK_COLOR);
|
|
}
|
|
}
|
|
TAutomask::handler(win, ep);
|
|
}
|
|
|
|
bool TReport_field_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch(o.dlg())
|
|
{
|
|
case F_X:
|
|
case F_Y:
|
|
case F_DX:
|
|
case F_DY:
|
|
if (e == fe_modify)
|
|
{
|
|
const int num = get_num(o.dlg());
|
|
set_num(o.dlg(), num); // Reformat
|
|
}
|
|
break;
|
|
case F_FGCOLOR:
|
|
if (e == fe_button)
|
|
{
|
|
_fgcolor = xvt_dm_post_choose_color(win(), _fgcolor);
|
|
force_update();
|
|
}
|
|
break;
|
|
case F_BGCOLOR:
|
|
if (e == fe_button)
|
|
{
|
|
_bgcolor = xvt_dm_post_choose_color(win(), _bgcolor);
|
|
force_update();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void TReport_field_mask::set_field(const TReport_field& rf)
|
|
{
|
|
const char str[2] = { rf.type(), '\0' };
|
|
set(F_TYPE, str);
|
|
|
|
RCT r; rf.get_rect(r);
|
|
set_num(F_X, r.left);
|
|
set_num(F_Y, r.top);
|
|
set_num(F_DX, r.right-r.left);
|
|
set_num(F_DY, r.bottom-r.top);
|
|
set(F_HALIGN, rf.horizontal_alignment());
|
|
set(F_VALIGN, rf.vertical_alignment());
|
|
set(F_BORDER, rf.border());
|
|
_fgcolor = rf.fore_color();
|
|
_bgcolor = rf.back_color();
|
|
set(F_TEXT, rf.picture());
|
|
set(F_SOURCE, rf.field());
|
|
}
|
|
|
|
void TReport_field_mask::get_field(TReport_field& rf) const
|
|
{
|
|
rf.set_type(get(F_TYPE)[0]);
|
|
rf.set_pos(get_num(F_X), get_num(F_Y));
|
|
rf.set_size(get_num(F_DX), get_num(F_DY));
|
|
rf.set_horizontal_alignment(get(F_HALIGN)[0]);
|
|
rf.set_vertical_alignment(get(F_VALIGN)[0]);
|
|
rf.set_border(get_int(F_BORDER));
|
|
rf.set_fore_color(_fgcolor);
|
|
rf.set_back_color(_bgcolor);
|
|
rf.set_picture(get(F_TEXT));
|
|
rf.set_field(get(F_SOURCE));
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_sheet
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TReport_sheet : public TSheet
|
|
{
|
|
TReport_section& _section;
|
|
|
|
protected:
|
|
virtual long get_items() const { return _section.items(); }
|
|
virtual void get_row(long r, TToken_string& row);
|
|
|
|
public:
|
|
virtual KEY run();
|
|
int selection(int& first, int& last) const;
|
|
TReport_sheet(TReport_section& sec);
|
|
};
|
|
|
|
void TReport_sheet::get_row(long r, TToken_string& row)
|
|
{
|
|
const TReport_field& rf = (const TReport_field&)_section[r];
|
|
RCT rect; rf.get_rect(rect);
|
|
row.cut(0);
|
|
row.add(checked(r) ? "X" : " ");
|
|
row.add(rf.type_name());
|
|
row.add(num2str(rect.top));
|
|
row.add(num2str(rect.left));
|
|
row.add(num2str(rect.right-rect.left));
|
|
row.add(num2str(rect.bottom-rect.top));
|
|
row.add(rf.picture());
|
|
row.add(rf.field());
|
|
}
|
|
|
|
int TReport_sheet::selection(int& first, int& last) const
|
|
{
|
|
int tot = 0;
|
|
first = items()+1;
|
|
last = -1;
|
|
FOR_EACH_ARRAY_ITEM_BACK(_section, i, o)
|
|
{
|
|
const TReport_field& rf = *(const TReport_field*)o;
|
|
if (rf.selected())
|
|
{
|
|
if (i < first) first = i;
|
|
if (i > last) last = i;
|
|
tot++;
|
|
}
|
|
}
|
|
return tot;
|
|
}
|
|
|
|
KEY TReport_sheet::run()
|
|
{
|
|
int first = -1;
|
|
uncheck(-1);
|
|
FOR_EACH_ARRAY_ITEM(_section, i, o)
|
|
{
|
|
const TReport_field& rf = *(const TReport_field*)o;
|
|
if (rf.selected())
|
|
{
|
|
check(i);
|
|
if (first < 0)
|
|
first = i;
|
|
}
|
|
}
|
|
if (first > 0)
|
|
select(first);
|
|
const KEY k = TSheet::run();
|
|
if (k != K_ESC)
|
|
{
|
|
FOR_EACH_ARRAY_ITEM(_section, i, o)
|
|
{
|
|
TReport_field& rf = *(TReport_field*)o;
|
|
rf.select(checked(i));
|
|
}
|
|
}
|
|
return k;
|
|
}
|
|
|
|
TReport_sheet::TReport_sheet(TReport_section& sec)
|
|
: TSheet(-1, -1, -2, -4, "Campi", "@1|Tipo@10|Riga@R|Col.@R|Larg.@R|Alt.@R|Testo@30|Campo@30", 0xE),
|
|
_section(sec)
|
|
{
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_section_mask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TReport_section_mask : public TAutomask
|
|
{
|
|
XVT_FNTID _font;
|
|
bool _font_changed;
|
|
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
void set_num(short id, short num);
|
|
short get_num(short id) const;
|
|
|
|
void vedo_non_vedo();
|
|
|
|
public:
|
|
void set_section(const TReport_section& rs);
|
|
void get_section(TReport_section& rs) const;
|
|
TReport_section_mask() : TAutomask("ba8300c"), _font(NULL), _font_changed(false) { }
|
|
};
|
|
|
|
void TReport_section_mask::set_num(short id, short num)
|
|
{
|
|
set(id, num2str(num));
|
|
}
|
|
|
|
short TReport_section_mask::get_num(short id) const
|
|
{
|
|
TString8 str = get(id);
|
|
str.replace(',', '.');
|
|
real n(str);
|
|
n *= CENTO;
|
|
return (short)n.integer();
|
|
}
|
|
|
|
void TReport_section_mask::vedo_non_vedo()
|
|
{
|
|
const char type = get(F_TYPE)[0];
|
|
const int level = get_int(F_LEVEL);
|
|
show(F_GROUP_BY, level > 1);
|
|
show(F_HIDE_IF_NEEDED, level == 0 && type != 'B');
|
|
enable(DLG_DELREC, level > 1);
|
|
}
|
|
|
|
bool TReport_section_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch(o.dlg())
|
|
{
|
|
case F_TYPE:
|
|
case F_LEVEL:
|
|
if (e == fe_modify)
|
|
vedo_non_vedo();
|
|
break;
|
|
case F_DX:
|
|
case F_DY:
|
|
if (e == fe_modify)
|
|
{
|
|
const int num = get_num(o.dlg());
|
|
set_num(o.dlg(), num); // Reformat
|
|
}
|
|
break;
|
|
case F_FONT_SELECT:
|
|
if (e == fe_button)
|
|
{
|
|
if (xvt_dm_post_font_sel(win(), _font, NULL, 0))
|
|
_font_changed = true;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void TReport_section_mask::set_section(const TReport_section& rs)
|
|
{
|
|
char s[2] = { rs.type(), '\0' };
|
|
set(F_TYPE, s);
|
|
set(F_LEVEL, rs.level());
|
|
|
|
set_num(F_DX, rs.width());
|
|
set_num(F_DY, rs.height());
|
|
|
|
set(F_GROUP_BY, rs.grouped_by());
|
|
set(F_HIDE_IF_NEEDED, rs.hidden_if_needed() ? "X" : "");
|
|
|
|
XVT_FNTID old_font = rs.font().get_xvt_font(*this);
|
|
_font = xvt_font_create();
|
|
xvt_font_copy(_font, old_font, ~0);
|
|
xvt_font_set_size(_font, rs.font().size());
|
|
|
|
vedo_non_vedo();
|
|
}
|
|
|
|
void TReport_section_mask::get_section(TReport_section& rs) const
|
|
{
|
|
rs.set_width(get_num(F_DX));
|
|
rs.set_height(get_num(F_DY));
|
|
rs.group_by(get(F_GROUP_BY));
|
|
rs.hide_if_needed(get_bool(F_HIDE_IF_NEEDED));
|
|
|
|
if (_font_changed)
|
|
{
|
|
TString name;
|
|
xvt_font_get_family(_font, name.get_buffer(), name.size());
|
|
const int size = xvt_font_get_size(_font);
|
|
const XVT_FONT_STYLE_MASK style = xvt_font_get_style(_font);
|
|
rs.set_font(name, size, style);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_mask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TReport_mask : public TAutomask
|
|
{
|
|
TReport _report;
|
|
TReport_tree _tree;
|
|
TFilename _curr_report;
|
|
bool _is_dirty;
|
|
|
|
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 update_report() const;
|
|
|
|
TReport_section& curr_section();
|
|
void add_field();
|
|
void edit_field(TReport_field& rf);
|
|
void fields_properties();
|
|
void section_properties();
|
|
void on_print();
|
|
|
|
bool get_rep_path(TFilename& path) const;
|
|
void set_num_attr(TXmlItem& item, const char* attr, short num, short def = 0) const;
|
|
void set_col_attr(TXmlItem& item, const char* attr, COLOR col, COLOR def) const;
|
|
void save_section(const TReport_section& rs, TXmlItem& item) const;
|
|
|
|
public:
|
|
bool save_report();
|
|
bool save_if_needed();
|
|
void global_reset();
|
|
bool delete_report();
|
|
bool load_report();
|
|
|
|
TReport_tree& sections() { return _tree; }
|
|
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;
|
|
}
|
|
|
|
bool TReport_mask::get_rep_path(TFilename& path) const
|
|
{
|
|
const TString& name = get(F_CODICE);
|
|
const bool ok = name.not_empty();
|
|
if (ok)
|
|
{
|
|
get_sql_directory(path);
|
|
path.add(name);
|
|
path.ext("rep");
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
void TReport_mask::set_num_attr(TXmlItem& item, const char* attr, short num, short def) const
|
|
{
|
|
if (num != def)
|
|
{
|
|
const real n = (num / 100.0);
|
|
item.SetAttr(attr, n.string());
|
|
}
|
|
}
|
|
|
|
void TReport_mask::set_col_attr(TXmlItem& item, const char* attr, COLOR col, COLOR def) const
|
|
{
|
|
if (color_distance(col, def) != 0)
|
|
{
|
|
TString16 str;
|
|
str.format("#%06X", col & 0xFFFFFF);
|
|
item.SetAttr(attr, str);
|
|
}
|
|
}
|
|
|
|
void TReport_mask::save_section(const TReport_section& rs, TXmlItem& item) const
|
|
{
|
|
char* tipo = NULL;
|
|
switch (rs.type())
|
|
{
|
|
case 'H': tipo = "Head"; break;
|
|
case 'F': tipo = "Foot"; break;
|
|
default : tipo = "Body"; break;
|
|
}
|
|
item.SetAttr("type", tipo);
|
|
item.SetAttr("level", rs.level());
|
|
item.SetAttr("hidden_if_needed", rs.hidden_if_needed());
|
|
item.AddChild("groupby") << rs.grouped_by();
|
|
|
|
for (int i = 0; i < rs.items(); i++)
|
|
{
|
|
const TReport_field& rf = rs.field(i);
|
|
TXmlItem& field = item.AddChild("field");
|
|
field.SetAttr("type", rf.type_name());
|
|
|
|
RCT rct; rf.get_rect(rct);
|
|
set_num_attr(field, "x", rct.left);
|
|
set_num_attr(field, "y", rct.top);
|
|
set_num_attr(field, "width", rct.right - rct.left);
|
|
set_num_attr(field, "height", rct.bottom - rct.top, 100);
|
|
set_col_attr(field, "bg_color", rf.back_color(), COLOR_WHITE);
|
|
set_col_attr(field, "fg_color", rf.fore_color(), COLOR_BLACK);
|
|
switch (rf.horizontal_alignment())
|
|
{
|
|
case 'C': field.SetAttr("align", "center"); break;
|
|
case 'R': field.SetAttr("align", "right"); break;
|
|
case 'J': field.SetAttr("align", "justify"); break;
|
|
default : break;
|
|
};
|
|
switch (rf.vertical_alignment())
|
|
{
|
|
case 'T': field.SetAttr("valign", "top"); break;
|
|
case 'C': field.SetAttr("valign", "center"); break;
|
|
default : break;
|
|
};
|
|
field.SetAttr("border", rf.border());
|
|
field.SetAttr("text", rf.picture());
|
|
if (rf.field().not_empty())
|
|
field.AddChild("source") << rf.field();
|
|
}
|
|
}
|
|
|
|
bool TReport_mask::save_report()
|
|
{
|
|
bool ok = _curr_report.not_empty();
|
|
if (!ok)
|
|
ok = get_rep_path(_curr_report);
|
|
if (!ok)
|
|
return field(F_CODICE).on_key(K_ENTER); // Segnala errore
|
|
|
|
char name[_MAX_FNAME];
|
|
xvt_fsys_parse_pathname (_curr_report, NULL, NULL, name, NULL, NULL);
|
|
ok = *name > ' ';
|
|
if (ok)
|
|
{
|
|
TXmlItem xml;
|
|
xml.SetTag("report");
|
|
xml.SetAttr("Name", name);
|
|
xml.AddChild("description") << get(F_DESCR);
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
const char* sectype = "HBF";
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
TReport_section* rs = _report.find_section(sectype[j], i);
|
|
if (rs != NULL && (rs->height() > 0 || rs->items() > 0))
|
|
{
|
|
TXmlItem& sec = xml.AddChild("section");
|
|
save_section(*rs, sec);
|
|
}
|
|
}
|
|
}
|
|
|
|
xml.AddChild("sql") << get(F_SQL);
|
|
xml.Save(_curr_report);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TReport_mask::save_if_needed()
|
|
{
|
|
if (!_is_dirty)
|
|
return true;
|
|
if (!yesno_box(TR("Si desidera registrare il report?")))
|
|
return false;
|
|
return save_report();
|
|
}
|
|
|
|
void TReport_mask::global_reset()
|
|
{
|
|
_report.destroy();
|
|
reset();
|
|
update_report();
|
|
}
|
|
|
|
bool TReport_mask::load_report()
|
|
{
|
|
TFilename path; get_rep_path(path);
|
|
bool ok = path.exist();
|
|
if (ok)
|
|
{
|
|
_curr_report = path;
|
|
global_reset();
|
|
ok = _report.load(path);
|
|
if (ok)
|
|
{
|
|
path = path.name(); path.ext("");
|
|
set(F_CODICE, path);
|
|
|
|
set(F_SQL, _report.sql(), true);
|
|
set(F_DESCR, _report.description());
|
|
field(F_SQL).set_dirty(false);
|
|
_is_dirty = false;
|
|
|
|
TTree_field& sections = tfield(F_SECTIONS);
|
|
_tree.goto_node('B', 1);
|
|
sections.select_current();
|
|
update_report();
|
|
}
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TReport_mask::delete_report()
|
|
{
|
|
TFilename path; get_rep_path(path);
|
|
const bool ok = yesno_box(FR("Si desidera eliminare il file %s"), (const char*)path);
|
|
if (ok)
|
|
{
|
|
::remove(path);
|
|
global_reset();
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
void TReport_mask::on_print()
|
|
{
|
|
}
|
|
|
|
TReport_section& TReport_mask::curr_section()
|
|
{
|
|
TTree_field& sections = tfield(F_SECTIONS);
|
|
sections.goto_selected();
|
|
return _tree.curr_section();
|
|
}
|
|
|
|
void TReport_mask::update_report() const
|
|
{
|
|
TTree_field& tf = tfield(F_SECTIONS);
|
|
tf.win().force_update();
|
|
|
|
TReport_drawer& rd = (TReport_drawer&)field(F_REPORT);
|
|
rd.win().force_update();
|
|
}
|
|
|
|
void TReport_mask::add_field()
|
|
{
|
|
TReport_section& rs = curr_section();
|
|
TReport_field_mask m;
|
|
m.set(F_DX, 10); m.set(F_DY, 1);
|
|
m.disable(DLG_DELREC);
|
|
if (m.run() == K_ENTER)
|
|
{
|
|
TReport_field* rf = new TReport_field;
|
|
m.get_field(*rf);
|
|
rs.add(rf);
|
|
update_report();
|
|
}
|
|
}
|
|
|
|
void TReport_mask::edit_field(TReport_field& rf)
|
|
{
|
|
TReport_field_mask m;
|
|
m.set_field(rf);
|
|
const KEY key = m.run();
|
|
switch(key)
|
|
{
|
|
case K_ENTER:
|
|
m.get_field(rf);
|
|
break;
|
|
case K_DEL:
|
|
{
|
|
TReport_section& rs = rf.section();
|
|
for (int i = rs.last(); i >= 0; i--) if (rs.objptr(i) == &rf)
|
|
{
|
|
rs.destroy(i, true);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
update_report();
|
|
}
|
|
|
|
void TReport_mask::fields_properties()
|
|
{
|
|
TReport_section& rs = curr_section();
|
|
TReport_sheet sheet(rs);
|
|
|
|
int first, last;
|
|
int selected = sheet.selection(first, last);
|
|
if (selected == 1)
|
|
{
|
|
TReport_field& rf = rs.field(first);
|
|
edit_field(rf);
|
|
return;
|
|
}
|
|
|
|
KEY key = K_ENTER;
|
|
while (key != K_ESC)
|
|
{
|
|
key = sheet.run();
|
|
selected = sheet.selection(first, last);
|
|
if (selected == 0 && (key == K_ENTER || key == K_DEL))
|
|
{
|
|
first = last = sheet.selected();
|
|
selected = 1;
|
|
sheet.check(first);
|
|
}
|
|
|
|
switch (key)
|
|
{
|
|
case K_INS:
|
|
add_field();
|
|
break;
|
|
case K_ENTER:
|
|
{
|
|
for (int i = first; i <= last; i++) if (sheet.checked(i))
|
|
{
|
|
TReport_field& rf = rs.field(i);
|
|
edit_field(rf);
|
|
}
|
|
}
|
|
break;
|
|
case K_DEL:
|
|
if (selected > 0 && yesno_box(FR("Comfermare la cancellazione di %d elementi"), selected))
|
|
{
|
|
for (int i = last; i >= first; i--) if (sheet.checked(i))
|
|
rs.destroy(i, true);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
update_report();
|
|
}
|
|
}
|
|
|
|
void TReport_mask::section_properties()
|
|
{
|
|
TReport_section& rs = curr_section();
|
|
TReport_section_mask m;
|
|
m.set_section(rs);
|
|
switch (m.run())
|
|
{
|
|
case K_ENTER:
|
|
m.get_section(rs);
|
|
_is_dirty = true;
|
|
break;
|
|
case K_DEL:
|
|
rs.report().kill_section(rs.type(), rs.level());
|
|
_is_dirty = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (_is_dirty)
|
|
update_report();
|
|
}
|
|
|
|
bool TReport_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
case F_CODICE:
|
|
if (e == fe_button)
|
|
{
|
|
if (select_report())
|
|
e = fe_modify;
|
|
}
|
|
if (e == fe_modify)
|
|
{
|
|
save_if_needed();
|
|
load_report();
|
|
}
|
|
break;
|
|
case F_SECTIONS:
|
|
if (e == fe_init || e == fe_modify)
|
|
{
|
|
update_report();
|
|
const TReport_section& rs = _tree.curr_section();
|
|
const bool ok = strchr("HBF", rs.type()) != NULL;
|
|
enable(-1, ok);
|
|
}
|
|
break;
|
|
case F_TYPE:
|
|
if (e == fe_button && o.active())
|
|
add_field();
|
|
break;
|
|
case F_FLD_PROPERTIES:
|
|
if (e == fe_button && o.active())
|
|
fields_properties();
|
|
break;
|
|
case F_SEC_PROPERTIES:
|
|
if (e == fe_button && o.active())
|
|
section_properties();
|
|
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_recordset qry(get(F_SQL));
|
|
if (qry.columns() > 0)
|
|
{
|
|
TRecordset_sheet sheet(qry);
|
|
sheet.run();
|
|
}
|
|
}
|
|
break;
|
|
case DLG_PRINT:
|
|
if (e == fe_button)
|
|
{
|
|
on_print();
|
|
return false;
|
|
}
|
|
break;
|
|
case DLG_NEWREC:
|
|
if (e == fe_button)
|
|
{
|
|
save_if_needed();
|
|
global_reset();
|
|
}
|
|
break;
|
|
case DLG_FINDREC:
|
|
if (e == fe_button)
|
|
send_key(K_F9, F_CODICE);
|
|
case DLG_SAVEREC:
|
|
if (e == fe_button)
|
|
{
|
|
get_rep_path(_curr_report);
|
|
save_report();
|
|
}
|
|
break;
|
|
case DLG_DELREC:
|
|
if (e == fe_button && jolly == 0) // Elimina della Toolbar
|
|
{
|
|
delete_report();
|
|
return false; // Do not exit!
|
|
}
|
|
break;
|
|
case DLG_QUIT:
|
|
save_if_needed();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
TReport_mask::TReport_mask() : _tree(_report), _is_dirty(false)
|
|
{
|
|
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);
|
|
|
|
_tree.goto_node('B',1);
|
|
const int ih = _tree.image_height();
|
|
if (ih > CHARY)
|
|
albero.set_row_height(ih);
|
|
albero.set_tree(&_tree);
|
|
|
|
_tree.goto_root();
|
|
_tree.expand_all();
|
|
|
|
TReport_drawer& rd = (TReport_drawer&)field(F_REPORT);
|
|
rd.set_report(&_report);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// 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;
|
|
}
|