#include #include #include #include #include #include "ba8301.h" #include /////////////////////////////////////////////////////////// // 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; }