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
498 lines
12 KiB
C++
Executable File
498 lines
12 KiB
C++
Executable File
#include <colors.h>
|
|
#include <diction.h>
|
|
#include <mask.h>
|
|
#include <printer.h>
|
|
#include <xml.h>
|
|
|
|
#include "ba8301.h"
|
|
#include <bagn003.h>
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_font
|
|
///////////////////////////////////////////////////////////
|
|
|
|
XVT_FNTID TReport_font::get_xvt_font(const TWindow& win) const
|
|
{
|
|
if (win.win() != _win_mapped)
|
|
{
|
|
const int cpi = 120 / DEFAULT_FONT_SIZE;
|
|
const PNT pnt0 = win.log2dev(0,0);
|
|
const PNT pnt1 = win.log2dev(cpi*100,100);
|
|
const int ppi = pnt1.h - pnt0.h;
|
|
const TString emme(cpi, 'M');
|
|
|
|
int mi = 0, me = 0, ma = 2*(pnt1.v - pnt0.v);
|
|
int best = 0, best_error = 0;
|
|
while (mi <= ma)
|
|
{
|
|
me = (mi+ma)/2;
|
|
|
|
XVT_FNTID fontid = xvt_font_create();
|
|
xvt_font_set_family(fontid, "Courier New");
|
|
xvt_font_set_size(fontid, me);
|
|
xvt_dwin_set_font(win.win(), fontid);
|
|
const int width = xvt_dwin_get_text_width(win.win(), emme, -1);
|
|
const int error = abs(width - ppi);
|
|
xvt_font_destroy(fontid);
|
|
if (best == 0 || error < best_error)
|
|
{
|
|
best = me;
|
|
best_error = error;
|
|
if (error == 0)
|
|
break;
|
|
}
|
|
if (width > ppi)
|
|
ma = me-1;
|
|
else
|
|
mi = me+1;
|
|
}
|
|
const int nSize = cpi * best / _cpi;
|
|
|
|
XVT_FNTID fontid = xvt_font_create();
|
|
xvt_font_set_family(fontid, (char*)(const char*)_name);
|
|
xvt_font_set_size(fontid, best);
|
|
xvt_font_set_style(fontid, _style);
|
|
|
|
if (_fontid != NULL)
|
|
xvt_font_destroy(_fontid);
|
|
((TReport_font*)this)->_fontid = fontid;
|
|
((TReport_font*)this)->_win_mapped = win.win();
|
|
}
|
|
return _fontid;
|
|
}
|
|
|
|
void TReport_font::create(const char* name, int size, XVT_FONT_STYLE_MASK style)
|
|
{
|
|
_name = name;
|
|
_size = size;
|
|
_style = style;
|
|
_cpi = 120 / _size;
|
|
if (_fontid != NULL)
|
|
{
|
|
xvt_font_destroy(_fontid);
|
|
_fontid = NULL;
|
|
_win_mapped = NULL_WIN;
|
|
}
|
|
}
|
|
|
|
void TReport_font::copy(const TReport_font& font)
|
|
{
|
|
create(font.name(), font.size(), font.style());
|
|
}
|
|
|
|
TReport_font::TReport_font() : _fontid(NULL), _win_mapped(NULL_WIN)
|
|
{
|
|
create("Courier New", DEFAULT_FONT_SIZE, XVT_FS_NONE);
|
|
}
|
|
|
|
TReport_font::~TReport_font()
|
|
{
|
|
if (_fontid != NULL)
|
|
xvt_font_destroy(_fontid);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_section
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TReport_section* TReport_section::father_section() const
|
|
{
|
|
if (level() <= 0)
|
|
{
|
|
if (type() != 'B')
|
|
return _report.find_section('B', 0);
|
|
}
|
|
else
|
|
return _report.find_section('B', type() == 'B' ? 0 : 1);
|
|
return NULL;
|
|
}
|
|
|
|
const TReport_font& TReport_section::font() const
|
|
{
|
|
const TReport_font* f = _font;
|
|
if (f == NULL)
|
|
{
|
|
TReport_section* father = father_section();
|
|
if (father == NULL)
|
|
f = &_report.font();
|
|
else
|
|
f = &father->font();
|
|
}
|
|
return *f;
|
|
}
|
|
|
|
void TReport_section::set_font(const char* name, int size, XVT_FONT_STYLE_MASK style)
|
|
{
|
|
if (_font == NULL)
|
|
_font = new TReport_font;
|
|
_font->create(name, size, style);
|
|
}
|
|
|
|
int TReport_section::add(TObject* obj)
|
|
{
|
|
TReport_field* rf = (TReport_field*)obj;
|
|
rf->set_section(this);
|
|
return TArray::add(obj);
|
|
}
|
|
|
|
int TReport_section::add(TObject& obj)
|
|
{
|
|
TReport_field& rf = (TReport_field&)obj;
|
|
rf.set_section(this);
|
|
return TArray::add(obj);
|
|
}
|
|
|
|
bool TReport_section::get_rect(RCT& rct) const
|
|
{
|
|
rct.left = rct.top = 0;
|
|
rct.right = _width;
|
|
rct.bottom = _height;
|
|
FOR_EACH_ARRAY_ITEM((*this), i, o)
|
|
{
|
|
const TReport_field& rf = (const TReport_field&)o;
|
|
RCT r; rf.get_rect(r);
|
|
if (r.right > rct.right)
|
|
rct.right = r.right;
|
|
if (r.bottom > rct.bottom)
|
|
rct.bottom = r.bottom;
|
|
}
|
|
return xvt_rect_is_empty(&rct) == FALSE;
|
|
}
|
|
|
|
TReport_section::TReport_section(TReport& r, char t, int l)
|
|
: _report(r), _type(t), _level(l), _font(NULL),
|
|
_width(0), _height(0), _hidden_if_needed(false)
|
|
{ }
|
|
|
|
TReport_section::~TReport_section()
|
|
{
|
|
if (_font)
|
|
delete _font;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport_field
|
|
///////////////////////////////////////////////////////////
|
|
|
|
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::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();
|
|
}
|
|
|
|
void TReport_field::copy(const TReport_field& rf)
|
|
{
|
|
_section = rf._section;
|
|
_type = rf.type();
|
|
_x = rf._x; _y = rf._y;
|
|
_width = rf._width; _height = rf._height;
|
|
_fgcolor = rf._fgcolor; _bgcolor = rf._bgcolor;
|
|
_border = rf._border;
|
|
_halign = rf._halign; _valign = rf._valign;
|
|
_picture = rf._picture; _field = rf._field;
|
|
_selected = false;
|
|
|
|
if (_font != NULL)
|
|
{
|
|
delete _font;
|
|
_font = NULL;
|
|
}
|
|
if (rf._font != NULL)
|
|
_font = new TReport_font(rf.font());
|
|
}
|
|
|
|
const char* TReport_field::type_name() const
|
|
{
|
|
const char* n = NULL;
|
|
switch (_type)
|
|
{
|
|
case 'D': n = "Data"; break;
|
|
case 'I': n = "Immagine"; break;
|
|
case 'L': n = "Linea"; break;
|
|
case 'N': n = "Numero"; break;
|
|
case 'R': n = "Rettangolo"; break;
|
|
case 'S': n = "Stringa"; break;
|
|
case 'T': n = "Testo"; break;
|
|
default : break;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
void TReport_field::draw_rect(TWindow& win) const
|
|
{
|
|
if (border() > 0 || color_distance(back_color(), COLOR_WHITE) != 0)
|
|
{
|
|
win.set_pen(fore_color(), border());
|
|
win.set_brush(back_color(), PAT_SOLID);
|
|
RCT r; get_rect(r);
|
|
const PNT f = win.log2dev(r.left, r.top);
|
|
const PNT t = win.log2dev(r.right, r.bottom);
|
|
r.left = f.h; r.top = f.v;
|
|
r.right = t.h; r.bottom = t.v;
|
|
xvt_dwin_draw_rect(win.win(), &r);
|
|
}
|
|
}
|
|
|
|
void TReport_field::draw_text(TWindow& win, const char* text) const
|
|
{
|
|
draw_rect(win);
|
|
|
|
win.set_color(fore_color(), back_color());
|
|
XVT_FNTID fid = font().get_xvt_font(win);
|
|
xvt_dwin_set_font(win.win(), fid);
|
|
RCT r; get_rect(r);
|
|
const PNT f = win.log2dev(r.left, r.top);
|
|
const PNT t = win.log2dev(r.right, r.bottom);
|
|
xvt_dwin_draw_text(win.win(), f.h, t.v-2, text, -1);
|
|
}
|
|
|
|
void TReport_field::draw(TWindow& win) const
|
|
{
|
|
switch (_type)
|
|
{
|
|
case 'L':
|
|
{
|
|
win.set_pen(fore_color(), border());
|
|
RCT r; get_rect(r);
|
|
win.line(r.left, r.top, r.right, r.bottom);
|
|
}
|
|
break;
|
|
case 'R': draw_rect(win); break;
|
|
default : draw_text(win, picture()); break;
|
|
}
|
|
}
|
|
|
|
static short get_num_attr(const TXmlItem& item, const char* attr, short def = 0)
|
|
{
|
|
const TString& str = item.GetAttr(attr);
|
|
if (str.not_empty())
|
|
{
|
|
real n = str; n *=CENTO ;
|
|
def = (short)n.integer();
|
|
}
|
|
return def;
|
|
}
|
|
|
|
static COLOR get_col_attr(const TXmlItem& item, const char* attr, COLOR col)
|
|
{
|
|
const TString& str = item.GetAttr(attr);
|
|
if (str[0] == '#')
|
|
sscanf(str, "#%X", &col);
|
|
return col;
|
|
}
|
|
|
|
static char get_chr_attr(const TXmlItem& item, const char* attr, char c)
|
|
{
|
|
const TString& str = item.GetAttr(attr);
|
|
if (str[0] > ' ')
|
|
c = toupper(str[0]);
|
|
return c;
|
|
}
|
|
|
|
TReport_field::TReport_field()
|
|
: _section(NULL), _type('T'), _selected(false), _font(NULL),
|
|
_border(0), _fgcolor(COLOR_BLACK), _bgcolor(COLOR_WHITE)
|
|
{
|
|
set_pos(0,0);
|
|
set_size(1600,100);
|
|
}
|
|
|
|
TReport_field::TReport_field(const TXmlItem& fld)
|
|
: _section(NULL), _selected(false), _font(NULL)
|
|
{
|
|
set_type(get_chr_attr(fld, "type", 'T'));
|
|
set_column(get_num_attr(fld, "x"));
|
|
set_row(get_num_attr(fld, "y"));
|
|
set_width(get_num_attr(fld, "width"));
|
|
set_height(get_num_attr(fld, "height", 100));
|
|
set_border(fld.GetIntAttr("border"));
|
|
set_back_color(get_col_attr(fld, "bg_color", COLOR_WHITE));
|
|
set_fore_color(get_col_attr(fld, "fg_color", COLOR_BLACK));
|
|
set_horizontal_alignment(get_chr_attr(fld, "align", 'L'));
|
|
set_vertical_alignment(get_chr_attr(fld, "valign", 'B'));
|
|
set_picture(fld.GetAttr("text"));
|
|
TXmlItem* src = fld.FindFirst("source");
|
|
if (src != NULL)
|
|
src->GetEnclosedText(_field);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TReport
|
|
///////////////////////////////////////////////////////////
|
|
|
|
void TReport::build_section_key(char type, int level, TString& key) const
|
|
{ key.format("%c%d", type, level); }
|
|
|
|
TReport_section* TReport::find_section(char type, int level) const
|
|
{
|
|
TString4 key; build_section_key(type, level, key);
|
|
TReport_section* sec = (TReport_section*)_sections.objptr(key);
|
|
return sec;
|
|
}
|
|
|
|
bool TReport::kill_section(char type, int level)
|
|
{
|
|
TString4 key; build_section_key(type, level, key);
|
|
return _sections.remove(key);
|
|
}
|
|
|
|
int TReport::find_max_level() const
|
|
{
|
|
int lev = 1;
|
|
TAssoc_array& ass = (TAssoc_array&)_sections;
|
|
FOR_EACH_ASSOC_OBJECT(ass, h, k, o)
|
|
{
|
|
const int l = k[1]-'0';
|
|
if (l > lev)
|
|
lev = l;
|
|
}
|
|
return lev;
|
|
}
|
|
|
|
TReport_section& TReport::section(char type, int level)
|
|
{
|
|
TReport_section* sec = find_section(type, level);
|
|
if (sec == NULL)
|
|
{
|
|
sec = new TReport_section(*this, type, level);
|
|
TString4 key; key.format("%c%d", type, level);
|
|
_sections.add(key, sec);
|
|
}
|
|
return *sec;
|
|
}
|
|
|
|
void TReport::destroy()
|
|
{
|
|
_sections.destroy();
|
|
_sql.cut(0);
|
|
_description.cut(0);
|
|
}
|
|
|
|
void TReport::load_sections(const TXmlItem& xml)
|
|
{
|
|
for (int i = 0; i < xml.GetChildren(); i++)
|
|
{
|
|
const TXmlItem& sec = *xml.GetChild(i);
|
|
if (sec.GetTag() != "section")
|
|
continue;
|
|
|
|
const char type = sec.GetAttr("type")[0];
|
|
const int level = sec.GetIntAttr("level");
|
|
TReport_section& rs = section(type, level);
|
|
rs.hide_if_needed(sec.GetIntAttr("hidden_if_needed") != 0);
|
|
if (level > 1)
|
|
{
|
|
const TXmlItem* gb = xml.FindFirst("groupby");
|
|
if (gb != NULL)
|
|
{
|
|
TString str;
|
|
gb->GetEnclosedText(str);
|
|
rs.group_by(str);
|
|
}
|
|
}
|
|
|
|
for (int j = 0; j < sec.GetChildren(); j++)
|
|
{
|
|
const TXmlItem& fld = *sec.GetChild(j);
|
|
if (fld.GetTag() != "field")
|
|
continue;
|
|
|
|
TReport_field* rf = new TReport_field(fld);
|
|
rs.add(rf);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool TReport::load(const char* fname)
|
|
{
|
|
destroy();
|
|
TXmlItem xml;
|
|
|
|
_path = fname;
|
|
bool ok = xml.Load(_path);
|
|
if (ok)
|
|
{
|
|
const TXmlItem* desc = xml.FindFirst("description");
|
|
if (desc != NULL)
|
|
desc->GetEnclosedText(_description);
|
|
|
|
if (xml.FindFirst("section") != NULL)
|
|
load_sections(xml);
|
|
|
|
const TXmlItem* sql = xml.FindFirst("sql");
|
|
if (sql != NULL)
|
|
sql->GetEnclosedText(_sql);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
TReport::TReport() : _lpi(6)
|
|
{ }
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPage_printer
|
|
///////////////////////////////////////////////////////////
|
|
|
|
const char* TPage_printer::form_name() const
|
|
{
|
|
return printer().get_form_name();
|
|
}
|
|
|
|
const char* TPage_printer::font_name() const
|
|
{
|
|
return printer().fontname();
|
|
}
|
|
|
|
int TPage_printer::font_size() const
|
|
{
|
|
return printer().get_char_size();
|
|
}
|
|
|
|
bool TPage_printer::ask_pages()
|
|
{
|
|
const int last_page = pages();
|
|
|
|
TPrinter& p = printer();
|
|
TMask msk("bagn003");
|
|
msk.set(F_PRINTER, p.printername());
|
|
msk.set(F_FORM, form_name());
|
|
msk.set(F_FONT, font_name());
|
|
msk.set(F_SIZE, font_size());
|
|
msk.set(F_ISGRAPHICS, p.isgraphics() ? "X" : "");
|
|
msk.set(F_FROMPAGE, _pagefrom);
|
|
msk.set(F_TOPAGE, last_page);
|
|
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 > last_page)
|
|
_pageto = 0;
|
|
}
|
|
return ok;
|
|
}
|