diff --git a/src/include/printer.cpp b/src/include/printer.cpp index fd7bbd83e..17d751ef7 100755 --- a/src/include/printer.cpp +++ b/src/include/printer.cpp @@ -707,12 +707,12 @@ void TPrinter::parse_background(const char* bg_desc, TString_array& background) cnt++; if (_isgraphics) { - tt << op; - tt.add(id); - tt.add(x1); - tt.add(y1); - tt.add(x2); - tt.add(y2); + tt << op; + tt.add(id); + tt.add(x1); + tt.add(y1); + tt.add(x2); + tt.add(y2); } break; case 'l': // line @@ -2428,6 +2428,7 @@ void TTabulator::add_field(int column, int width) if (find_column(column, width, idx, col)) { TTab_info& ti = (TTab_info&)_tab[idx]; + if (ti.intersection(start, end) < width) { split(start, end, ti.start(), ti.end()); @@ -2437,6 +2438,9 @@ void TTabulator::add_field(int column, int width) { if (ti.start() == column && end > ti.end() && end < ti.end()+4) ti.set_end(end); + else + if (ti.start() == column && end < ti.end() && end > 0) + ti.set_end(end); } } else diff --git a/src/include/report.cpp b/src/include/report.cpp index 696fca273..e083f52e6 100755 --- a/src/include/report.cpp +++ b/src/include/report.cpp @@ -277,7 +277,9 @@ void TReport_expr::evaluate_user_func(int index, int nparms, TEval_stack& stack, const TVariant& TReport_expr::as_variant(TFieldtypes ft) { set_type(ft == _alfafld || ft == _nullfld ? _strexpr : _numexpr); + const TString& str = as_string(); + switch (ft) { case _boolfld: _var.set(str=="X"||str=="Y"||str=="1"); break; @@ -955,6 +957,7 @@ TString& TReport_script::translate_message(TReport& rep) const { TString& alx = msg_empty ? empty_alex : alex; TString arg; + for (int i = args.items()-1; i >= 0; i--) { arg = args.get(i); @@ -1252,6 +1255,7 @@ void TReport_field::set_postscript(const char* src) void TReport_field::copy(const TReport_field& rf) { +// don't copy _original _id = rf.id(); _type = rf.type(); _rct = rf._rct; @@ -1526,6 +1530,7 @@ const TReport_rct& TReport_field::compute_draw_rect(const TBook& book) if (dynamic_height()) { const TString& txt = formatted_text(); + if (txt.full()) { TString_array para; @@ -2010,7 +2015,7 @@ int TReport_field::compare(const TSortable& s) const } TReport_field::TReport_field(TReport_section* sec) - : _section(sec), _id(0), _type('T'), _rct(0,0,1000,100), + : _section(sec), _original(nullptr), _id(0), _type('T'), _rct(0,0,1000,100), _txcolor(COLOR_BLACK), _fgcolor(COLOR_BLACK), _bgcolor(COLOR_WHITE), _shcolor(COLOR_GRAY), _pattern(PAT_HOLLOW), _radius(0), _shadow_offset(0), _shade_angle(0), @@ -2021,7 +2026,7 @@ TReport_field::TReport_field(TReport_section* sec) { } TReport_field::TReport_field(const TReport_field& rf) - : _section(nullptr), _font(nullptr), _print_font(nullptr), _draw_hidden(false), + : _section(nullptr), _original(nullptr), _font(nullptr), _print_font(nullptr), _draw_hidden(false), _draw_deactivated(false) { @@ -2031,7 +2036,7 @@ TReport_field::TReport_field(const TReport_field& rf) TReport_field::~TReport_field() { safe_delete(_font); - + safe_delete(_original); safe_delete(_print_font); } @@ -2187,6 +2192,176 @@ TReport_section& TReport::section(char type, int level) return *sec; } +HIDDEN const TString & patch_col(TString & src, const char * pattern, int val) +{ + int pos = src.find(pattern); + + while (pos >= 0) + { + TString str = src.sleft(pos); + + str << val << src.smid(pos + 4); + src = str; + pos = src.find(pattern); + } + return src; +} + +HIDDEN const TString & patch_id(TString & src, int val) +{ + int pos = src.find("CID"); + + while (pos >= 0) + { + TString str = src.sleft(pos); + + str << val + atoi(src.smid(pos + 1)); + pos += 4; + while (src[++pos] && (isdigit(src[pos]) || src[pos] == ')')); + str << src.smid(pos); + src = str; + pos = src.find("CID"); + } + return src; +} + +int TReport::add_column_group(int col, int x_offset) +{ + int col_width = 0; + + ++_last_column; + FOR_EACH_ASSOC_OBJECT(_sections, os, sec_key0, sec_item0) + { + TReport_section & sect = *(TReport_section *)sec_item0; + const int items = sect.items(); + + TReport_field * first_field = sect.find_field(_from_column_id); + int startcol = first_field != nullptr ? first_field->x() : 0; + + for (int i = 0; i < items; i++) + { + const TReport_field & field = sect.field(i); + int id = field.id(); + + if (check_column_id(id)) + { + int width = field.x() - startcol + field.width(); + + if (width > col_width) + col_width = width; + } + } + } + FOR_EACH_ASSOC_OBJECT(_sections, os, sec_key, sec_item) + { + TReport_section & sect = *(TReport_section *)sec_item; + const int items = sect.items(); + + for (int i = 0; i < items; i++) + { + const TReport_field & field = sect.field(i); + int id = field.id(); + + if (check_column_id(id)) + { + TReport_field * new_field = new TReport_field(sect.field(i)); + int y = field.x() + _last_column * col_width + x_offset; + + new_field->set_pos(field.x(), y); + new_field->set_id(new_field->id() + _last_column * _id_offset); + set_column_field(*new_field, _last_column); + + TString src = new_field->field(); + + sect.add(new_field); + patch_col(src, "#COL", col); + if (src.full()) + new_field->set_field(src); + src = new_field->prescript(); + if (src.full()) + { + patch_col(src, "#COL", col); + patch_id(src, _from_column_id + _last_column * _id_offset); + new_field->set_prescript(src); + } + src = new_field->postscript(); + if (src.full()) + { + patch_col(src, "#COL", col); + patch_id(src, _from_column_id + _last_column * _id_offset); + new_field->set_postscript(src); + } + } + } + } + return _last_column; +} + +void TReport::patch_base_column() +{ + + FOR_EACH_ASSOC_OBJECT(_sections, os, sec_key, sec_item) + { + TReport_section & sect = *(TReport_section *)sec_item; + const int items = sect.items(); + int col_width = 0; + + for (int i = 0; i < items; i++) + { + TReport_field & field = (TReport_field &) sect.field(i); + int id = field.id(); + + if (check_column_id(id)) + { + TString src = field.field(); + + if (src.full()) + { + patch_col(src, "#COL", 0); + field.set_field(src); + } + src = field.prescript(); + if (src.full()) + { + patch_col(src, "#COL", 0); + patch_id(src, _from_column_id); + field.set_prescript(src); + } + src = field.postscript(); + if (src.full()) + { + patch_col(src, "#COL", 0); + patch_id(src, _from_column_id); + field.set_postscript(src); + } + } + } + } +} + +TReport_field* TReport::column_field(const char* code, int column) +{ + char type = ' '; + int level = -1, id = 0; + const int k = parse_field(code, type, level, id); + + id = field_column_id(id, column); + + TReport_field* rf = nullptr; + if (k == 3) + { + if (id > 0) + { + TReport_section* sec = find_section(type, level); + if (sec != nullptr) + rf = sec->find_field(id); + } + else + rf = curr_field(); + } + + return rf; +} // Parsa un riferimento a campo, gruppo o sezione // #B0 -> 2 B 0 // #101 -> 3 B 1 101 @@ -2355,6 +2530,7 @@ bool TReport::load(const char* fname) // Carico la query principale PRIMA delle sezioni che potrebbero collegarvicisi const TXmlItem* sql = xml.FindFirstChild("sql"); + if (sql != nullptr) { TString str; sql->GetEnclosedText(str); @@ -2430,6 +2606,7 @@ bool TReport::save(const char* fname) const if (ok) { TXmlItem xml; + xml.SetTag("report"); xml.SetAttr("name", name); xml.SetAttr("class", _class); @@ -2798,6 +2975,7 @@ size_t TReport::add_usr_words(TString_array& words, const char* const names[]) c TReport::get_usr_words(words); const int first_msg = words.items(); // Calcola il primo numero disponibile + for (size_t i = 0; names[i] != nullptr; i++) words.add(names[i]); @@ -3040,6 +3218,7 @@ void TReport::reset_export_sections() } } set_dbase_fixed_fields(false); + restore_dynamic_fields(); } @@ -3084,6 +3263,18 @@ void TReport::set_export4dbase() TReport_section * sect = (TReport_section *)sec_item; sect->show(sect->shown() && sec_id.starts_with("B")); + if (sec_id.starts_with("B")) + { + const int items = sect->items(); + + for (int i = 0; i < items; i++) + { + TReport_field & field = sect->field(i); + + if (field.zeroes_hidden()) + field.hide_zeroes(false); + } + } } } @@ -3093,27 +3284,59 @@ void TReport::set_export_sections(export_type type) { case _export_printer : set_export4print(); + restore_dynamic_fields(); break; case _export_visualize : set_export4visualize(); + restore_dynamic_fields(); break; case _export_excel : set_export4excel(); + set_dynamic_fields(); break; case _export_dbase: set_export4dbase(); + set_dynamic_fields(); break; case _export_pdf : set_export4pdf(); + restore_dynamic_fields(); break; case _export_text : set_export4text(); + restore_dynamic_fields(); + break; default: break; } set_dbase_fixed_fields(type == _export_dbase); } +void TReport::set_dynamic_fields(bool on) +{ + FOR_EACH_ASSOC_OBJECT(_sections, obj, key, item) + { + TReport_section & sect = (TReport_section &)*item; + + FOR_EACH_ARRAY_ITEM(sect, r, objfld) + { + TReport_field & fld = (TReport_field &)*objfld; + + if (on) + { + if (fld.dynamic_height()) + { + fld.copy_original(); + fld.set_height(100); + fld.set_dynamic_height(false); + } + } + else + fld.clear_original(); + } + } +} + KEY TReport::run_form(TMask& m) { report2mask(m); @@ -3128,9 +3351,11 @@ KEY TReport::run_form(const TString& maskname) { TFilename fname = maskname; fname.ext("msk"); KEY key = K_QUIT; + if (fname.custom_path()) { TMask m(maskname); + key = run_form(m); switch (key) { @@ -3545,7 +3770,7 @@ bool TReport::execute_usr_word(unsigned int opcode, TVariant_stack& stack) } break; case 9: // HIDE - do_message(stack.pop(), do_show, NULL); + do_message(stack.pop(), do_show, nullptr); break; case 10: // ISAM_READ msg_isam_read(stack); @@ -3732,6 +3957,7 @@ void TReport::include_libraries(bool reload) libname.trim(); if (libname.find('.') < 0) libname.ext("alx"); + if (libname.exist()) include(libname); } } @@ -3782,7 +4008,8 @@ TReport::TReport() : _cpi(0), _lpi(6), _include(15, ','), _recordset(nullptr), _curr_field(nullptr), _use_printer_font(false), _save_last_printer(false), _orientation(0), _page_split(false), _page_merge(false), _rep_copy(1), _rep_copies(1), - _rep_page(0), _book_page(0) + _rep_page(0), _book_page(0), _id_offset(200), _from_column_id(0), _to_column_id(0), + _last_column(0) { _expressions.set_report(this); _prescript.set_description("PRESCRIPT"); diff --git a/src/include/report.h b/src/include/report.h index 29d935eb3..e1b312c57 100755 --- a/src/include/report.h +++ b/src/include/report.h @@ -272,8 +272,6 @@ public: const TReport_pnt& pos() const { return _pos; } void set_pos(const TReport_pnt& p) { _pos = p; } - - void set_fore_color(COLOR c) { _fgcolor = c; } COLOR fore_color() const { return _fgcolor; } void set_back_color(COLOR c) { _bgcolor = c; } @@ -353,7 +351,8 @@ struct TReport_array_item; class TReport_field : public TSortable { - TReport_section* _section; + TReport_section * _section; + TReport_field * _original; int _id; char _type; // Text, String, Numeric, Price, Valuta, Date, Boolean, Line, Rectangle, Image TReport_rct _rct; // In centesimi @@ -411,6 +410,12 @@ public: const TString& alternate_field() const { return _alt_field; } void set_alternate_field(const char* str) { _alt_field = str; } + const TString & prescript_source() const { return _prescript.get(); } + void prescript_source(const char * source) { _prescript.set(source); } + + const TString & postscript_source() const { return _postscript.get(); } + void postscript_source(const char * source) { _postscript.set(source); } + const TVariant& get() const { return _var; } void set(const char* str); void set(const TString& str); @@ -445,8 +450,10 @@ public: void set_width(long dx) { _rct.set_width(dx); } void set_height(long dy) { _rct.set_height(dy); } const TReport_rct& get_rect() const { return _rct; } + long x() const { return _rct.x; } + long y() const { return _rct.y; } long width() const { return _rct.width(); } - long height() const { _rct.height(); } + long height() const { return _rct.height(); } void set_dynamic_height(bool dh); bool dynamic_height() const; @@ -464,7 +471,7 @@ public: bool zeroes_hidden() const; void hide_zeroes(bool hz) { _hide_zeroes = hz; } - bool draw_hidden() const { return _draw_hidden; } + bool draw_hidden() const { return _draw_hidden; } bool draw_deactivated() const { return _draw_deactivated; } void set_draw_hidden(bool h) { _draw_hidden = h; } void set_draw_deactivated(bool d) { _draw_deactivated = d; } @@ -538,6 +545,9 @@ public: TReport_field* next() const; TReport_field* prev() const; + void copy_original() { _original = new TReport_field(*this); } + void clear_original() { safe_delete(_original); } + TReport_field(TReport_section* sec); TReport_field(const TReport_field& rf); virtual ~TReport_field(); @@ -590,6 +600,10 @@ class TReport : public TAlex_virtual_machine TReport_field* _curr_field; bool _page_split, _page_merge; TAssoc_array _default_shown_sections; + int _id_offset; + int _from_column_id; + int _to_column_id; + int _last_column; protected: virtual const char* class_name() const { return "Report"; } @@ -629,12 +643,15 @@ public: virtual const char * get_excel_disabled_field() { return ""; } virtual void set_dbase_fixed_fields(bool on = true) {} void reset_export_sections(); + void restore_dynamic_fields() { set_dynamic_fields(false); } void set_export_sections(export_type type); - virtual void set_export4print() {}; - virtual void set_export4visualize() {}; + void set_dynamic_fields(bool on = true); + + virtual void set_export4print() { }; + virtual void set_export4visualize() { }; virtual void set_export4excel(); - virtual void set_export4pdf() {}; - virtual void set_export4text() {}; + virtual void set_export4pdf() { }; + virtual void set_export4text() { }; virtual void set_export4dbase(); virtual bool on_link(const TReport_link& link); @@ -705,6 +722,15 @@ public: bool load(const char* fname); void show_all_sections(); + void set_id_offset(int id_offset = 100) { _id_offset = id_offset; } + void set_column_id(int from_column_id, int to_column_id) { _from_column_id = from_column_id; _to_column_id = to_column_id; set_id_offset(_to_column_id - _from_column_id + 1); } + bool check_column_id(int id) const { return (id >= _from_column_id) && (id <= _to_column_id); } + virtual TReport_field * set_column_field(TReport_field & field, int column = 0) { return &field; } + virtual int add_column_group(int col, int x_offest = 0); + void patch_base_column(); + int field_column_id(int id, int column = 0) const { return check_column_id(id) ? id + column * _id_offset : id; } + TReport_field* column_field(const char* code, int column = 0); + // Used by TReport_printer void set_page(word r, word p) { _rep_page = r; _book_page = p; } void set_copy(word c, word s) { _rep_copy = c; _rep_copies = s; } @@ -732,7 +758,9 @@ public: bool export_text(const char * filename, int size = 0, bool signature = false); TReport(); - TReport(const char * name) : _recordset(nullptr), _curr_field(nullptr) { load(name); } + TReport(const char * name) : _recordset(nullptr), _curr_field(nullptr), _id_offset(200), _from_column_id(0), + _to_column_id(0), _last_column(0) + { load(name); } virtual ~TReport(); }; diff --git a/src/include/reprint.cpp b/src/include/reprint.cpp index e6157b18b..c4f485a92 100755 --- a/src/include/reprint.cpp +++ b/src/include/reprint.cpp @@ -1289,7 +1289,7 @@ void TBook::print_doc(TWindow& win, const TFilename& name) if (ext == "bmp" || ext == "gif" || ext == "jpg" || ext == "jpeg" || ext == "png") { const TImage* img = _images.image(name); - if (img != NULL) + if (img != nullptr) { const TSize pr = page_res(); rect.deflate(pr.x/2, pr.y/2); @@ -1908,7 +1908,7 @@ bool TBook::export_dbase(TFilename& fname, TTrec * desc, bool signature, bool go FOR_EACH_STR_TOKEN(line, val) if (*desc->rec().Fd[i].Name != '\0') switch (desc->rec().Fd[i].TypeF) - { + { case _alfafld: case _charfld: case _boolfld: @@ -1927,8 +1927,8 @@ bool TBook::export_dbase(TFilename& fname, TTrec * desc, bool signature, bool go dbf.put(desc->rec().Fd[i++].Name, TDate(atoi(val.left(2)), atoi(val.mid(3,2)), 2000 + atoi(val.right(2)))); break; default : - break; - } + break; + } dbf.write(); } } @@ -1984,7 +1984,8 @@ bool TBook::export_excel(TFilename& fname, bool signature, bool goto_url, bool a { // const char* section = str.get(1); - if ((section[0] == 'B'||section[0]=='F' || section[0] == 'H') && section[1]>'0') + + if ((section[0] == 'B'|| section[0]=='F' && section[1] > '0') || section[0] == 'H') tab.add_field(col, wid); // Raggiunge fine del testo while (str != "" && !ifs.eof()) @@ -2019,7 +2020,7 @@ bool TBook::export_excel(TFilename& fname, bool signature, bool goto_url, bool a { const char* section = str.get(1); bool do_export = section[1] > '0'; - if (!do_export) + if (!do_export) { switch (section[0]) { @@ -2036,12 +2037,13 @@ bool TBook::export_excel(TFilename& fname, bool signature, bool goto_url, bool a if (do_export && str.full()) { int idx, pos; + if (tab.find_column(col, wid, idx, pos, true)) { TToken_string* line = (TToken_string*)page.objptr(row); TString field; - if (line == NULL) + if (line == nullptr) { line = new TToken_string(256,sep); page.add(line, row); @@ -2798,7 +2800,6 @@ long TReport_book::print_section(TReport_section& rs) if (rs.condition().full()) { TVariant var; - _report->evaluate(rs.condition(), var, _alfafld); if (!var.as_bool()) return -2;