#include #include #include #include #include #include #include #include #include #include #include "ba8300.h" #include "ba8301.h" #include /////////////////////////////////////////////////////////// // Utility /////////////////////////////////////////////////////////// static TString16 _str; const TString& num2str(int num) { 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; } short str2num(const TString& str) { _str = str; _str.replace(',', '.'); real n(_str); n *= CENTO; return (short)n.integer(); } /////////////////////////////////////////////////////////// // TReport_base_mask /////////////////////////////////////////////////////////// class TReport_base_mask : public TAutomask { TReport_font _font; bool _font_changed; protected: TReport& _report; char _halign, _valign; COLOR _fgcolor, _bgcolor; virtual void update(); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: void set_font_info(const TReport_font& font); bool get_font_info(TReport_font& font) const; TReport_base_mask(const char* name, TReport& rep); }; void TReport_base_mask::update() { const TMask_field& fld = field(F_FONT_SELECT); if (fld.active() && win() == fld.parent()) { RCT rctfld; fld.get_rect(rctfld); const int x = rctfld.right / CHARX + 1; const int y = rctfld.top / ROWY + 1; RCT& rct = resize_rect(x, y, -3, 2, W_PLAIN, win()); rct.top = rctfld.top; rct.bottom = rctfld.bottom; xi_draw_3d_rect((XinWindow)win(), (XinRect*)&rct, TRUE, 2, MASK_LIGHT_COLOR, _bgcolor, MASK_DARK_COLOR); rct.left += 2; rct.right -= 2; rct.top += 2; rct.bottom -= 2; xvt_dwin_set_clip(win(), &rct); XVT_FNTID fontid = _font.get_xvt_font(*this); xvt_font_set_size(fontid, _font.size()); xvt_dwin_set_font(win(), fontid); set_color(_fgcolor, _bgcolor); advanced_draw_text(*this, _font.name(), rct, _halign, _valign); } } bool TReport_base_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { 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; case F_PATTERN: if (e == fe_modify) force_update(); break; case F_FONT_SELECT: if (e == fe_button) { XVT_FNTID font = xvt_font_create(); xvt_font_copy(font, _font.get_xvt_font(*this), XVT_FA_ALL); xvt_font_set_size(font, _font.size()); if (xvt_dm_post_font_sel(win(), font, NULL, 0)) { 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); _font.create(name, size, style); _font_changed = true; force_update(); } xvt_font_destroy(font); } break; case F_HALIGN: case F_VALIGN: if (e == fe_init || e == fe_modify) { _halign = get(F_HALIGN)[0]; _valign = get(F_VALIGN)[0]; force_update(); } break; case F_PRESCRIPT: case F_POSTSCRIPT: if (e == fe_close) { TReport_script s; s.set(o.get()); _report.set_interactive(true); s.compile(_report); _report.set_interactive(false); } break; default: break; } return true; } void TReport_base_mask::set_font_info(const TReport_font& font) { _font = font; } bool TReport_base_mask::get_font_info(TReport_font& font) const { const bool ok = _font_changed; if (ok) font = _font; return ok; } TReport_base_mask::TReport_base_mask(const char* name, TReport& rep) : TAutomask(name), _report(rep), _font_changed(false), _halign('C'), _valign('C'), _fgcolor(COLOR_BLACK), _bgcolor(COLOR_WHITE) { } /////////////////////////////////////////////////////////// // TReport_field_mask /////////////////////////////////////////////////////////// class TReport_field_mask : public TReport_base_mask { TReport_field& _rf; protected: void vedo_non_vedo(); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); virtual void update(); public: void set_num(short id, long n); long get_num(short id) const; void set_field(const TReport_field& rf); void get_field(TReport_field& rf) const; TReport_field_mask(TReport_field& rf); }; void TReport_field_mask::set_num(short id, long num) { set(id, num2str(num)); } long TReport_field_mask::get_num(short id) const { return str2num(get(id)); } void TReport_field_mask::update() { for (int i = 0; i < 2; i++) { TMask_field& fld = field(i == 0 ? F_FGCOLOR : F_BGCOLOR); if (fld.active() && fld.parent() == win()) { RCT rctfld; fld.get_rect(rctfld); const int x = rctfld.right / CHARX + 1; const int y = rctfld.top / ROWY + 1; RCT& rct = resize_rect(x, y, -3, 1, W_PLAIN, win()); rct.top = rctfld.top; rct.bottom = rctfld.bottom; xi_draw_3d_rect((XinWindow)win(), (XinRect*)&rct, TRUE, 2, MASK_LIGHT_COLOR, i == 0 ? _fgcolor : _bgcolor, MASK_DARK_COLOR); } } TReport_base_mask::update(); } void TReport_field_mask::vedo_non_vedo() { const char type = get(F_TYPE)[0]; const bool is_currency = type == 'P' || type == 'V'; const bool is_numeric = is_currency || type == 'N'; const bool is_text = is_numeric || strchr("ADST", type) != NULL; show(F_HIDE_ZEROES, is_numeric || type == 'D'), show(F_HALIGN, is_text); if (is_numeric) { disable(F_HALIGN); set(F_HALIGN, "R"); // Allineo a destra i numeri } else enable(F_HALIGN); show(F_VALIGN, is_text); show(F_TEXT, is_text && !is_currency); show(F_HIDE_DOTS, is_currency); show(F_DYNAMIC_HEIGHT, type == 'S'); show(F_FGCOLOR, type != 'I'); show(F_BGCOLOR, type != 'L'); show(F_PATTERN, type != 'L' && type != 'I'); show(F_RADIUS, type != 'E' && type != 'L' && type != 'I'); show(F_SHADE_OFFSET,type != 'E' && type != 'L'); show(F_FONT_SELECT, is_text); show(F_SOURCE, (is_text || type == 'I') && type != 'T'); show(F_SOURCE2, is_text && type != 'T'); show(DLG_FINDREC, is_text && type != 'T'); show(F_CODVAL, is_currency); // Codice valuta di riferimento show(F_LINK, strchr("DNS", type) != NULL); // Chi puo' essere un link? show(F_PRESCRIPT, is_text); show(F_POSTSCRIPT, is_text); enable_page(3, type == 'A'); if (is_running()) force_update(); } bool TReport_field_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch(o.dlg()) { case F_TYPE: if (e == fe_init || e == fe_modify) { vedo_non_vedo(); if (e == fe_modify) { if (strchr("ELR", o.get()[0]) != NULL && get_int(F_BORDER) == 0) set(F_BORDER, 2); // Propongo un bordo visibile per le linee } } break; case F_X: case F_Y: case F_DX: case F_DY: case F_RADIUS: case F_SHADE_OFFSET: if (e == fe_modify) { const int num = get_num(o.dlg()); set_num(o.dlg(), num); // Reformat } break; case F_LIST: if (e == fe_close) { TSheet_field& sheet = sfield(F_LIST); TAssoc_array ass; FOR_EACH_SHEET_ROW(sheet, i, row) { if (ass.add(row->get(0))) return error_box(TR("E' necessario specificare codici diversi")); } if (ass.items() < 2) return error_box(TR("Specificare almeno due codici")); } break; case DLG_FINDREC: if (e == fe_button) { TRecordset* rex = _rf.section().recordset(); if (rex == NULL) rex = _report.recordset(); if (rex != NULL && rex->columns() > 0) { TArray_sheet sheet(-1, -1, -1, 20, TR("Colonne Query"), HR("Nome@16|Tipo@8|Dimensoni@R")); TToken_string row; for (size_t i = 0; i < rex->columns(); i++) { const TRecordset_column_info& info = rex->column_info(i); row = info._name; switch (info._type) { case _alfafld: row.add("Stringa"); break; case _boolfld: row.add("Logico"); break; case _datefld: row.add("Data"); break; case _memofld: row.add("Memo"); break; default : row.add("Numero"); break; } row.add(info._width); sheet.add(row); } if (sheet.run() == K_ENTER) { row = sheet.row(-1); set(F_SOURCE, row.get(0)); char tipo = row.get_char(1); int width = row.get_int(2); switch (tipo) { case 'D':width = 10; break; case 'L':tipo = 'S'; break; case 'M':tipo = 'S'; width = 50; break; default: break; } const char str[2] = { tipo, '\0' }; set(F_TYPE, str); set(F_DX, width); } } else warning_box("Query non definita"); } break; default: break; } return TReport_base_mask::on_field_event(o, e, jolly); } void TReport_field_mask::set_field(const TReport_field& rf) { char str[2] = { rf.type(), '\0' }; set(F_TYPE, str, true); const TRectangle& r = rf.get_rect(); set(F_ID, rf.id()); set_num(F_X, r.left()); set_num(F_Y, r.top()); set_num(F_DX, r.width()); set_num(F_DY, r.height()); set(F_HIDDEN, rf.hidden() ? "X" : ""); set(F_DISABLED, rf.deactivated() ? "X" : ""); set(F_HIDE_ZEROES, rf.zeroes_hidden() ? "X" : ""); set(F_HIDE_DOTS, rf.picture().find('.') < 0); set(F_DYNAMIC_HEIGHT, rf.dynamic_height() ? "X" : ""); set(F_GROUPS, rf.groups()); set(F_CODVAL, rf.codval()); set(F_LINK, rf.link()); str[0] = rf.horizontal_alignment(); set(F_HALIGN, str); str[0] = rf.vertical_alignment(); set(F_VALIGN, str); set(F_BORDER, rf.border()); set(F_PATTERN, rf.pattern()); set_num(F_RADIUS, rf.radius()); set_num(F_SHADE_OFFSET, rf.shade_offset()); _fgcolor = rf.fore_color(); _bgcolor = rf.back_color(); set(F_TEXT, rf.picture()); set(F_SOURCE, rf.field()); set(F_SOURCE2, rf.alternate_field()); set_font_info(rf.font()); set(F_PRESCRIPT, rf.prescript()); set(F_POSTSCRIPT, rf.postscript()); if (rf.type() == 'A') { TSheet_field& list = sfield(F_LIST); rf.get_list(list.rows_array()); } } void TReport_field_mask::get_field(TReport_field& rf) const { rf.set_type(get(F_TYPE)[0]); rf.set_id(get_int(F_ID)); rf.set_pos(get_num(F_X), get_num(F_Y)); rf.set_size(get_num(F_DX), get_num(F_DY)); rf.show(!get_bool(F_HIDDEN)); rf.activate(!get_bool(F_DISABLED)); rf.hide_zeroes(field(F_HIDE_ZEROES).active() && get_bool(F_HIDE_ZEROES)); rf.set_dynamic_height(get_bool(F_DYNAMIC_HEIGHT)); rf.set_groups(get(F_GROUPS)); rf.set_codval(get(F_CODVAL)); rf.set_link(get(F_LINK)); rf.set_horizontal_alignment(get(F_HALIGN)[0]); rf.set_vertical_alignment(get(F_VALIGN)[0]); rf.set_pattern((PAT_STYLE)get_int(F_PATTERN)); rf.set_border(get_int(F_BORDER)); rf.set_radius(get_num(F_RADIUS)); rf.set_shade_offset(get_num(F_SHADE_OFFSET)); rf.set_fore_color(_fgcolor); rf.set_back_color(_bgcolor); if (strchr("VP", rf.type()) != NULL) rf.set_picture(get_bool(F_HIDE_DOTS) ? "#########,@@" : "###.###.###,@@"); else rf.set_picture(get(F_TEXT)); rf.set_field(get(F_SOURCE)); rf.set_alternate_field(get(F_SOURCE2)); TReport_font f; if (get_font_info(f)) rf.set_font(f); rf.set_prescript(get(F_PRESCRIPT)); rf.set_postscript(get(F_POSTSCRIPT)); if (rf.type() == 'A') { TSheet_field& list = sfield(F_LIST); rf.set_list(list.rows_array()); } } TReport_field_mask::TReport_field_mask(TReport_field& rf) : TReport_base_mask("ba8300b", rf.section().report()), _rf(rf) { set_field(rf); } /////////////////////////////////////////////////////////// // 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]; const TRectangle& rect = rf.get_rect(); row.cut(0); row.add(checked(r) ? "X" : " "); row.add(rf.type_name()); row.add(rf.id()); row.add(num2str(rect.top())); row.add(num2str(rect.left())); row.add(num2str(rect.width())); row.add(num2str(rect.height())); if (rf.field().not_empty()) row.add(rf.field()); else row.add(rf.picture()); } 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|ID@4R|Riga@R|Col.@R|Larg.@R|Alt.@R|Testo@50", 0xE), _section(sec) { } /////////////////////////////////////////////////////////// // TSection_properties_mask /////////////////////////////////////////////////////////// class TSection_properties_mask : public TReport_base_mask { protected: virtual void update(); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); void set_num(short id, long num); short get_num(short id) const; void vedo_non_vedo(); void set_section(const TReport_section& rs); public: void get_section(TReport_section& rs) const; TSection_properties_mask(TReport_section& rs); }; void TSection_properties_mask::update() { for (int i = 0; i < 2; i++) { TMask_field& fld = field(i == 0 ? F_FGCOLOR : F_BGCOLOR); if (fld.active() && fld.parent() == win()) { RCT rctfld; fld.get_rect(rctfld); const int x = rctfld.right / CHARX + 1; const int y = rctfld.top / ROWY + 1; RCT& rct = resize_rect(x, y, -3, 1, W_PLAIN, win()); rct.top = rctfld.top; rct.bottom = rctfld.bottom; xi_draw_3d_rect((XinWindow)win(), (XinRect*)&rct, TRUE, 2, MASK_LIGHT_COLOR, i == 0 ? _fgcolor : _bgcolor, MASK_DARK_COLOR); } } TReport_base_mask::update(); } void TSection_properties_mask::set_num(short id, long num) { set(id, num2str(num)); } short TSection_properties_mask::get_num(short id) const { return str2num(get(id)); } void TSection_properties_mask::vedo_non_vedo() { const char type = get(F_TYPE)[0]; const int level = get_int(F_LEVEL); const bool can_pos = (type != 'H' && level == 0) || (type == 'F' && level == 1); show(F_X, can_pos); show(F_Y, can_pos); show(F_CONDITION, /*type == 'B' &&*/ level > 0 && level < 10); show(F_GROUP_BY, type == 'H' && level > 1 && level < 10); show(F_SQL, type == 'B' && level > 10); show(F_KEEP_WITH_NEXT, level > 1 && type == 'H'); show(F_CAN_BREAK, level > 0 && type == 'B'); show(F_HIDE_IF_NEEDED, level == 0 && type != 'B'); show(F_REPEAT, level > 1 && type == 'H'); bool can_delete = false; if (level > 1) { if (level > 10) can_delete = _report.find_section('B', level+1) == NULL; else can_delete = true; } enable(DLG_DELREC, can_delete); } bool TSection_properties_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; default: break; } return TReport_base_mask::on_field_event(o, e, jolly); } void TSection_properties_mask::set_section(const TReport_section& rs) { char s[2] = { rs.type(), '\0' }; set(F_TYPE, s); set(F_LEVEL, rs.level()); vedo_non_vedo(); if (field(F_X).active()) { set_num(F_X, rs.pos().x); set_num(F_Y, rs.pos().y); } set_num(F_DX, rs.width()); set_num(F_DY, rs.height()); set(F_CONDITION, rs.condition()); set(F_GROUP_BY, rs.grouped_by()); if (rs.recordset() != NULL) set(F_SQL, rs.recordset()->query_text()); else reset(F_SQL); set(F_HIDE_IF_NEEDED, rs.hidden_if_needed()); set(F_HIDDEN, rs.hidden()); set(F_PAGE_BREAK, rs.page_break()); set(F_KEEP_WITH_NEXT, rs.keep_with_next()); set(F_CAN_BREAK, rs.can_be_broken()); set(F_REPEAT, rs.repeat_on_page()); set(F_DISABLED, rs.deactivated()); set(F_BORDER, rs.border()); set(F_PATTERN, rs.pattern()); set_num(F_RADIUS, rs.radius()); _fgcolor = rs.fore_color(); _bgcolor = rs.back_color(); set_font_info(rs.font()); set(F_PRESCRIPT, rs.prescript()); set(F_POSTSCRIPT, rs.postscript()); } void TSection_properties_mask::get_section(TReport_section& rs) const { if (field(F_X).active()) { const TPoint pos(get_num(F_X), get_num(F_Y)); rs.set_pos(pos); } rs.set_width(get_num(F_DX)); rs.set_height(get_num(F_DY)); rs.show(!get_bool(F_HIDDEN)); rs.activate(!get_bool(F_DISABLED)); rs.set_condition(get(F_CONDITION)); rs.group_by(get(F_GROUP_BY)); rs.set_recordset(get(F_SQL)); rs.hide_if_needed(get_bool(F_HIDE_IF_NEEDED)); rs.force_page_break(get_bool(F_PAGE_BREAK)); rs.keep_with_next(get_bool(F_KEEP_WITH_NEXT)); rs.can_break(get_bool(F_CAN_BREAK)); rs.set_repeat_on_page(get_bool(F_REPEAT)); rs.set_pattern((PAT_STYLE)get_int(F_PATTERN)); rs.set_border(get_int(F_BORDER)); rs.set_radius(get_num(F_RADIUS)); rs.set_fore_color(_fgcolor); rs.set_back_color(_bgcolor); TReport_font f; if (get_font_info(f)) rs.set_font(f); rs.set_prescript(get(F_PRESCRIPT)); rs.set_postscript(get(F_POSTSCRIPT)); } TSection_properties_mask::TSection_properties_mask(TReport_section& rs) : TReport_base_mask("ba8300c", rs.report()) { set_section(rs); } /////////////////////////////////////////////////////////// // TReport_properties_mask /////////////////////////////////////////////////////////// class TReport_properties_mask : public TReport_base_mask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); void set_report(const TReport& r); public: void get_report(TReport& r) const; TReport_properties_mask(TReport& rep) : TReport_base_mask("ba8300d", rep) { set_report(rep); } }; bool TReport_properties_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { return TReport_base_mask::on_field_event(o, e, jolly); } void TReport_properties_mask::set_report(const TReport& r) { set(F_FONT_AUTO, r.use_printer_font()); set(F_ORIENTATION, r.orientation()); set(F_DY, r.lpi()); set_font_info(r.font()); set(F_CLASS, r.get_class()); set(F_COMMAND, r.command_line()); set(F_INCLUDE, ((TReport&)r).get_libraries()); set(F_PRESCRIPT, r.prescript()); set(F_POSTSCRIPT, r.postscript()); sfield(F_PARAMS).rows_array() = r.params(); } void TReport_properties_mask::get_report(TReport& r) const { const bool af = get_bool(F_FONT_AUTO); r.set_use_printer_font(af); if (!af) { r.set_lpi(get_int(F_DY)); TReport_font f; if (get_font_info(f)) r.set_font(f); } r.set_orientation(get_int(F_ORIENTATION)); r.set_class(get(F_CLASS)); r.set_command_line(get(F_COMMAND)); const TString& oldlib = r.get_libraries(); if (oldlib != get(F_INCLUDE)) { r.set_libraries(get(F_INCLUDE)); r.include_libraries(); // reload } r.set_prescript(get(F_PRESCRIPT)); r.set_postscript(get(F_POSTSCRIPT)); r.set_params(sfield(F_PARAMS).rows_array()); } /////////////////////////////////////////////////////////// // TReport_mask /////////////////////////////////////////////////////////// class TReport_mask : public TAutomask { TReport _report; TReport_section* _curr_section; TReport_tree _tree; TFilename _curr_report; bool _is_dirty; protected: virtual TMask_field* parse_field(TScanner& scanner); virtual void notify_focus_field(short id); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); protected: bool select_query(); bool select_report(); void select_section(); void update_report() const; TReport_section& curr_section(); void add_field(); void edit_field(TReport_field& rf); void fields_properties(); bool add_section(); void section_properties(); void report_properties(); bool enumerate_bodies(int level, TToken_string& code, TToken_string& desc) const; 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; public: void on_print(); 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_custom_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_custom_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) { path = name; if (!path.is_absolute_path()) { path = firm2dir(-1); path.add("custom"); if (!path.exist()) xvt_fsys_mkdir(path); path.add(name); } path.ext("rep"); } return ok; } 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 _report.set_description(get(F_DESCR)); _report.set_recordset(get(F_SQL)); ok = _report.save(_curr_report); if (ok) _is_dirty = false; 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); const TRecordset* rs = _report.recordset(); if (rs != NULL) set(F_SQL, rs->query_text(), 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(); select_section(); } } return ok; } bool TReport_mask::delete_report() { TFilename path; get_rep_path(path); const bool ok = path.exist() && 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() { #ifdef DBG TFilename tmp; tmp.tempdir(); tmp.add("ba8300.txt"); TReport_book book(tmp); #else TReport_book book; #endif book.add(_report); book.print_or_preview(); } TReport_section& TReport_mask::curr_section() { return *_curr_section; } void TReport_mask::select_section() { TTree_field& tf = tfield(F_SECTIONS); tf.select_current(); _curr_section = &_tree.curr_section(); TReport_drawer& rd = (TReport_drawer&)field(F_REPORT); rd.set_report_section(*_curr_section); const char type = _curr_section->type(); const int level = _curr_section->level(); char htype = 'H'; int hlevel = level; switch (type) { case 'H': { if (level <= 1) hlevel = 1-level; else { if (level < 10) { if (_report.find_section('H', level-1)) hlevel = level-1; } else htype = 'B'; } } break; case 'B': if (level >= 1) { if (level < 10) { hlevel = _report.find_max_level('H'); if (hlevel <= 1) hlevel = 0; } } else hlevel = 0; break; case 'F': if (level > 1) { if (level > 10) htype = 'B'; else { if (_report.find_section('F', level-1)) hlevel = level-1; } } else hlevel = 1-level; break; default: break; } TReport_drawer& rdh = (TReport_drawer&)field(F_REPORTH); rdh.set_report_section(_report.section(htype, hlevel)); update_report(); } void TReport_mask::update_report() const { TTree_field& tf = tfield(F_SECTIONS); tf.win().force_update(); TReport_drawer& rdh = (TReport_drawer&)field(F_REPORTH); rdh.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* rf = new TReport_field(&rs); rf->set_type('S'); rf->set_pos(0, rs.compute_size().y); TReport_field_mask m(*rf); m.disable(DLG_DELREC); if (m.run() == K_ENTER) { m.get_field(*rf); rs.add(rf); update_report(); } else delete rf; } void TReport_mask::edit_field(TReport_field& rf) { TReport_section& rs = rf.section(); TReport_field_mask m(rf); const KEY key = m.run(); switch(key) { case K_ENTER: m.get_field(rf); break; case K_DEL: { for (int i = rs.last(); i >= 0; i--) if (rs.objptr(i) == &rf) { rs.destroy(i, true); break; } } break; default: break; } if (key != K_ESC) { _is_dirty = true; rs.sort(); 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(); } } bool TReport_mask::enumerate_bodies(int level, TToken_string& code, TToken_string& desc) const { TReport_section* rs = _report.find_section('B', level); if (rs != NULL) { TString str; str.format("B%d", level); code.add(str); describe_section('B', level, str); str.trim(); desc.add(str); enumerate_bodies(level*10+1, code, desc); // Figlio enumerate_bodies(level+1, code, desc); // Fratello } return rs != NULL; } bool TReport_mask::add_section() { TMask m("ba8300e"); TToken_string code, desc; enumerate_bodies(1, code, desc); TList_field& list = (TList_field&)m.field(102); list.replace_items(code, desc); if (m.run() == K_ENTER) { char type = m.get(101)[0]; int level = 0; if (type == 'S') { type = 'B'; const int father = atoi(m.get(102).mid(1)); if (father < 100000L) { int i; for (i = 1; i <= 9; i++) // Cerca l'ultimo figlio del nodo padre { level = father*10+i; if (_report.find_section(type, level) == NULL) break; } if (i > 9) level = 0; } } else { if (type == 'H') { const int hl = _report.find_max_level('H'); const int fl = _report.find_max_level('F'); level = max(hl, fl) + 1; } else level = _report.find_max_level('B')+1; if (level > 9) level = 0; } if (level > 0) { _tree.goto_node(type, level); tfield(F_SECTIONS).select_current(); _curr_section = &_report.section(type, level); section_properties(); } else error_box(TR("Livello non ammesso")); } return false; } void TReport_mask::section_properties() { TReport_section& rs = curr_section(); TSection_properties_mask m(rs); switch (m.run()) { case K_ENTER: m.get_section(rs); _tree.goto_node(rs.type(), rs.level()); _is_dirty = true; break; case K_DEL: if (yesno_box(TR("Confermare l'eliminazione della sezione"))) { const char t = rs.type(); const int l = rs.level(); rs.report().kill_section(t, l); _tree.goto_node(t, l-1); _is_dirty = true; } break; default: break; } if (_is_dirty) select_section(); } void TReport_mask::report_properties() { TReport_properties_mask m(_report); if (m.run() == K_ENTER) { m.get_report(_report); _is_dirty = true; update_report(); } } void TReport_mask::notify_focus_field(short id) { TAutomask::notify_focus_field(id); if (id == F_REPORTH || id == F_REPORT) { TReport_drawer& rd = (TReport_drawer&)field(id); _curr_section = &rd.curr_section(); } } bool TReport_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_CODICE: if (e == fe_init) { if (main_app().argc() >= 3) { set(F_CODICE, main_app().argv(2)); load_report(); } } if (e == fe_modify) { save_if_needed(); load_report(); } break; case F_SECTIONS: if (e == fe_init || e == fe_modify) { select_section(); const TReport_section& rs = _tree.curr_section(); const bool ok = strchr("HBF", rs.type()) != NULL; enable(-1, ok); } break; case F_FLD_ADD: 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_ADD: if (e == fe_button && o.active()) add_section(); break; case F_SEC_PROPERTIES: if (e == fe_button && o.active()) section_properties(); break; case F_REP_PROPERTIES: if (e == fe_button) report_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) { TRecordset* rex = NULL; const TString& sql = get(F_SQL); if (sql.starts_with("SELECT ")) rex = new TSQL_recordset(sql); else rex = new TISAM_recordset(sql); if (rex->columns() > 0) { TRecordset_sheet sht(*rex); sht.run(); } else warning_box(TR("Nessuna riga risultato")); delete rex; } 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); const short sec[2] = { F_REPORT, F_REPORTH }; for (int s = 0; s < 2; s++) { TReport_drawer& rd = (TReport_drawer&)field(sec[s]); RCT rct_rep; rd.get_rect(rct_rep); rct_rep.left = rct_sec.right+ROWY; rct_rep.right -= ROWY; rct_rep.bottom -= ROWY; rd.set_rect(rct_rep); switch (s) { case 1 : rd.set_report_section(_report.section('H', 0)); break; default: _curr_section = &_report.section('B', 1); rd.set_report_section(*_curr_section); break; } } _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(); } /////////////////////////////////////////////////////////// // TReporter_app /////////////////////////////////////////////////////////// class TReporter_app : public TSkeleton_application { TReport_mask* _msk; protected: virtual bool create(); virtual void main_loop(); virtual bool destroy(); virtual void print(); public: TReporter_app() : _msk(NULL) { } }; void TReporter_app::print() { if (_msk != NULL) _msk->on_print(); } bool TReporter_app::create() { if (!has_module(RSAUT)) return error_box(TR("Modulo non autorizzato")); _msk = new TReport_mask; xvt_sys_sleep(500); return TSkeleton_application::create(); } bool TReporter_app::destroy() { if (_msk != NULL) { delete _msk; _msk = NULL; } return true; } void TReporter_app::main_loop() { _msk->run(); } int ba8300(int argc, char* argv[]) { TReporter_app app; app.run(argc, argv, TR("Report Generator")); return 0; }