diff --git a/ba/ba8300.cpp b/ba/ba8300.cpp index 445d883b8..d19d94458 100755 --- a/ba/ba8300.cpp +++ b/ba/ba8300.cpp @@ -550,6 +550,7 @@ void TSection_properties_mask::vedo_non_vedo() show(F_GROUP_BY, type == 'H' && level > 1); show(F_KEEP_WITH_NEXT, level > 1 && type == 'H'); show(F_HIDE_IF_NEEDED, level == 0 && type != 'B'); + show(F_REPEAT, level > 1 && type == 'H'); enable(DLG_DELREC, level > 1); } @@ -592,12 +593,12 @@ void TSection_properties_mask::set_section(const TReport_section& rs) set(F_CONDITION, rs.condition()); set(F_GROUP_BY, rs.grouped_by()); - set(F_HIDE_IF_NEEDED, rs.hidden_if_needed() ? "X" : ""); - set(F_HIDDEN, rs.hidden() ? "X" : ""); + 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_DISABLED, rs.deactivated() ? "X" : ""); + set(F_REPEAT, rs.repeat_on_page()); + set(F_DISABLED, rs.deactivated()); set_font_info(rs.font()); set(F_PRESCRIPT, rs.prescript()); @@ -623,6 +624,7 @@ void TSection_properties_mask::get_section(TReport_section& rs) const 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.set_repeat_on_page(get_bool(F_REPEAT)); TReport_font f; if (get_font_info(f)) diff --git a/ba/ba8300.h b/ba/ba8300.h index b3de717e7..d60ece201 100755 --- a/ba/ba8300.h +++ b/ba/ba8300.h @@ -44,6 +44,7 @@ #define F_PAGE_BREAK 163 #define F_KEEP_WITH_NEXT 164 #define F_CONDITION 165 +#define F_REPEAT 166 #define F_SQL 201 #define F_IMPORT_QRY 202 diff --git a/ba/ba8300c.uml b/ba/ba8300c.uml index 1cf9f73ad..07f17a817 100755 --- a/ba/ba8300c.uml +++ b/ba/ba8300c.uml @@ -68,6 +68,14 @@ BEGIN FLAGS "H" END +BOOLEAN F_REPEAT +BEGIN + // Visibile per testate di livello > 1 + PROMPT 1 6 "Ripeti sezione ad inizio pagina" + FLAGS "H" +END + + MEMO F_CONDITION 48 3 BEGIN // Visibile sezioni con livello > 0 diff --git a/ba/ba8301.cpp b/ba/ba8301.cpp index 1c2154ff5..c1012f8af 100755 --- a/ba/ba8301.cpp +++ b/ba/ba8301.cpp @@ -343,6 +343,7 @@ public: void clear_selection(); void select(const TRectangle& rct); void offset_selection(const TPoint& p); + void resize_selection(const TPoint& p); void set_report(TReport* rep) { _report = rep; } @@ -419,6 +420,21 @@ void TReport_window::offset_selection(const TPoint& p) } } +void TReport_window::resize_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()) + { + TPoint s = f.get_rect().size(); s += p; + if (s.x > 0 && s.y > 0) + f.set_size(s.x, s.y); + } + } +} + void TReport_window::select(const TRectangle& rct) { clear_selection(); @@ -443,7 +459,7 @@ void TReport_window::draw_dragster() void TReport_window::snap_drag(PNT& pnt) const { const int kx = _dpi.h / cpi(); - const int ky = _dpi.v / lpi(); + const int ky = _dpi.v / (lpi()*2); pnt.h = (pnt.h / kx) * kx; pnt.v = (pnt.v / ky) * ky; } @@ -461,21 +477,37 @@ bool TReport_window::on_key(KEY k) switch (k) { case K_LEFT: - offset_selection(TPoint(-50, 0)); + offset_selection(TPoint(-100, 0)); + force_update(); + return true; + case K_LEFT+K_SHIFT: + resize_selection(TPoint(-100, 0)); force_update(); return true; case K_RIGHT: - offset_selection(TPoint(+50, 0)); + offset_selection(TPoint(+100, 0)); + force_update(); + return true; + case K_RIGHT+K_SHIFT: + resize_selection(TPoint(+100, 0)); force_update(); return true; case K_DOWN: offset_selection(TPoint(0, +50)); force_update(); return true; + case K_DOWN+K_SHIFT: + resize_selection(TPoint(0, +100)); + force_update(); + return true; case K_UP: offset_selection(TPoint(0, -50)); force_update(); return true; + case K_UP+K_SHIFT: + resize_selection(TPoint(0, -100)); + force_update(); + return true; case K_DEL: dispatch_e_menu(win(), POPUP_CUT); return true; @@ -860,10 +892,13 @@ void TReport_window::draw_field(const TReport_field& rf) advanced_draw_rect(*this, r, rf.border(), rf.fore_color(), rf.back_color()); break; case 'T': - advanced_draw_rect(*this, r, rf.border(), rf.fore_color(), rf.back_color()); - xvt_dwin_set_font(win(), rf.font().get_xvt_font(*this)); - set_color(rf.fore_color(), rf.back_color()); - advanced_draw_text(*this, rf.picture(), r, rf.horizontal_alignment(), rf.vertical_alignment()); + { + advanced_draw_rect(*this, r, rf.border(), rf.fore_color(), rf.back_color()); + xvt_dwin_set_font(win(), rf.font().get_xvt_font(*this)); + set_color(rf.fore_color(), rf.back_color()); + TString str = rf.picture(); + advanced_draw_paragraph(*this, str, r, rf.horizontal_alignment(), rf.vertical_alignment()); + } break; default : if (rf.dynamic_height()) @@ -896,7 +931,7 @@ void TReport_window::draw_field(const TReport_field& rf) str << rf.id(); else str = rf.field(); - advanced_draw_text(*this, str, r, rf.horizontal_alignment(), rf.vertical_alignment()); + advanced_draw_paragraph(*this, str, r, rf.horizontal_alignment(), rf.vertical_alignment()); break; } diff --git a/include/report.cpp b/include/report.cpp index 17281ad3e..1a6249446 100755 --- a/include/report.cpp +++ b/include/report.cpp @@ -370,6 +370,52 @@ void advanced_draw_text(TWindow& win, const char* text, const RCT& r, xvt_dwin_draw_text(win.win(), x, y, text, -1); } +void advanced_draw_paragraph(TWindow& win, TString& para, const RCT& rct, + char halign, char valign) +{ + const bool acapo = para.find('\n') >= 0; + const bool parag = para.find(char(0xB6)) >= 0; + + if (acapo || parag) // Devo scrivere piu' righe? + { + int leading, ascent, descent; + xvt_dwin_get_font_metrics(win.win(), &leading, &ascent, &descent); + const int kx = xvt_dwin_get_text_width(win.win(), "ABCDEFGH", 8) / 8; + const int ky = leading + ascent + descent; + + const int rct_height = rct.bottom - rct.top; + const unsigned columns = (rct.right - rct.left) / kx; + int rows = rct_height / ky; + + if (parag) + para.replace(char('0xB6'), '\n'); + TParagraph_string str(para, columns); + if (str.items() < rows) + rows = str.items(); + + int ybase = rct.top; + switch (valign) + { + case 'C': ybase += (rct_height - rows*ky) / 2; break; + case 'B': ybase += rct_height - rows*ky; break; + default : break; + } + + for (int row = 0; row < rows; row++) + { + RCT rctline = rct; + rctline.top = ybase + ky*row; + rctline.bottom = rctline.top + ky; + const char* line = str.get(); + if (halign == 'J' && (row == rows-1 || strlen(line) < columns/2)) + halign = 'L'; + advanced_draw_text(win, line, rctline, halign, 'T'); + } + } + else + advanced_draw_text(win, para, rct, halign, valign); +} + static void set_num_attr(TXmlItem& item, const char* attr, long num, short def = 0) { if (num != def) @@ -630,6 +676,7 @@ void TReport_section::save(TXmlItem& root) const item.SetAttr("hidden_if_needed", hidden_if_needed()); item.SetAttr("pagebreak", _page_break); item.SetAttr("keep_with_next", keep_with_next()); + item.SetAttr("repeat", repeat_on_page()); if (condition().not_empty()) item.AddChild("condition") << condition(); if (grouped_by().not_empty()) @@ -655,6 +702,7 @@ void TReport_section::load(const TXmlItem& sec) force_page_break(sec.GetBoolAttr("pagebreak")); keep_with_next(sec.GetBoolAttr("keep_with_next")); hide_if_needed(sec.GetBoolAttr("hidden_if_needed")); + set_repeat_on_page(sec.GetBoolAttr("repeat")); show(!sec.GetBoolAttr("hidden")); activate(!sec.GetBoolAttr("deactivated")); @@ -702,7 +750,8 @@ void TReport_section::load(const TXmlItem& sec) TReport_section::TReport_section(TReport& r, char t, int l) : _report(r), _type(t), _level(l), _font(NULL), - _size(0,0), _pos(0,0), _page_break(false), _hidden_if_needed(false), + _size(0,0), _pos(0,0), + _page_break(false), _hidden_if_needed(false), _repeat(false), _hidden(false), _deactivated(false) { } diff --git a/include/report.h b/include/report.h index b25dc55e6..0388f526e 100755 --- a/include/report.h +++ b/include/report.h @@ -147,7 +147,7 @@ class TReport_section : public TArray TPoint _pos; // Posizione assoluta in centesimi, default (0,0) TPoint _size; // Dimensioni in centesimi, default (0,0) TString _condition, _groupby; - bool _page_break, _hidden_if_needed, _keep_with_next; + bool _page_break, _hidden_if_needed, _keep_with_next, _repeat; bool _hidden, _deactivated; TReport_script _prescript, _postscript; @@ -178,9 +178,10 @@ public: bool compute_rect(TRectangle& rct) const; const TPoint& pos() const { return _pos; } void set_pos(const TPoint& p) { _pos = p; } - bool page_break() const { return _page_break; } void force_page_break(bool pb) { _page_break = pb; } + void set_repeat_on_page(bool r) { _repeat = r; } + bool repeat_on_page() const { return _repeat; } const TString& condition() const { return _condition; } void set_condition(const char* str) { _condition = str; } @@ -356,7 +357,6 @@ public: // virtual void draw_rect(TWindow& win) const; // virtual void draw_text(TWindow& win, const char* text, TReport_draw_mode mode) const; - // virtual void draw(TWindow& win, TReport_draw_mode mode) const; virtual bool print_tools(TBook& book) const; @@ -495,5 +495,7 @@ bool advanced_set_draw_tools(TWindow& win, int border, COLOR fore, COLOR back); void advanced_draw_rect(TWindow& win, const RCT& r, int border, COLOR fore, COLOR back); void advanced_draw_text(TWindow& win, const char* text, const RCT& r, char halign, char valign); +void advanced_draw_paragraph(TWindow& win, TString& text, const RCT& r, + char halign, char valign); #endif diff --git a/include/reprint.cpp b/include/reprint.cpp index 1c8ae1cce..c67d26284 100755 --- a/include/reprint.cpp +++ b/include/reprint.cpp @@ -117,7 +117,7 @@ void TPrint_preview_window::popup_menu(EVENT* ep) menu[5].tag = POPUP_ZOOMIN; menu[5].text = (char*)TR("Zoom +"); menu[5].enabled = _zoom < 300; menu[6].tag = POPUP_ZOOMOUT; menu[6].text = (char*)TR("Zoom -"); menu[6].enabled = _zoom > 50; menu[7].tag = -1; menu[7].separator = true; - menu[8].tag = POPUP_GRID; menu[8].text = (char*)TR("Griglia"); menu[8].enabled = true; + menu[8].tag = POPUP_GRID; menu[8].text = (char*)TR("Griglia"); menu[8].enabled = false; menu[8].checkable = true; menu[8].checked = false; const PNT& p = ep->v.mouse.where; @@ -667,7 +667,7 @@ bool TBook::print_page(TWindow& win, size_t page) break; stringona << str; } - advanced_draw_text(win, stringona, rct, _horizontal_alignment, _vertical_alignment); + advanced_draw_paragraph(win, stringona, rct, _horizontal_alignment, _vertical_alignment); continue; } if (str.starts_with("<text_align")) @@ -792,7 +792,7 @@ bool TBook::preview() { TPreview_mask msk(this); const KEY k = msk.run(); - if (k == ' ') + if (k != K_QUIT) print(); return true; } @@ -841,7 +841,6 @@ TPoint TReport_book::log2dev(const TPoint& ptlog) const TPoint ptdev; ptdev.x = (ptlog.x * _phr) / (100 * _report->cpi()); ptdev.y = (ptlog.y * _pvr) / (100 * _report->lpi()); - return ptdev; } @@ -849,7 +848,6 @@ void TReport_book::define_frame(const TRectangle& r) { TPoint ptlog = r; ptlog += _delta; TPoint szlog = r.size(); - const TRectangle rect(log2dev(ptlog), log2dev(szlog)); TBook::define_frame(rect); } @@ -942,6 +940,24 @@ void TReport_book::create_links(const TReport_section& rs) */ } +void TReport_book::reprint_group_headers() +{ + const int max_group = _report->find_max_level('H'); + for (int level = max_group; level >= 2; level--) + { + TReport_section& rs = _report->section('H', level); + if (rs.repeat_on_page()) + { + const long height = rs.compute_size().y; // Compute size after the initilization script! + if (height > 0) + { + rs.print(*this); + _delta.y += height; + } + } + } +} + long TReport_book::print_section(TReport_section& rs) { if (_print_aborted) @@ -975,6 +991,8 @@ long TReport_book::print_section(TReport_section& rs) { close_page(); open_page(); + if (rs.type() == 'B') + reprint_group_headers(); } if (_page_is_open) rs.print(*this); @@ -1049,7 +1067,7 @@ bool TReport_book::add(TReport& rep) { if (max_group >= 2) // Gestione raggruppamenti { - int changed = 0; + int first_changed = 0; TVariant var; for (int g = 2; g <= max_group; g++) { @@ -1058,9 +1076,12 @@ bool TReport_book::add(TReport& rep) const TString& grp = var.as_string(); newgroup.add(grp, g); if (newgroup.row(g) != oldgroup.row(g) || rex->current_row() == 0) - changed = g; + { + if (first_changed == 0) + first_changed = g; + } } - if (changed) + if (first_changed) { oldgroup = newgroup; @@ -1070,10 +1091,10 @@ bool TReport_book::add(TReport& rep) if (rex->current_row() > 0) { - for (int g = 2; g <= changed; g++) + for (int g = max_group; g >= first_changed ; g--) _delta.y += print_section('F', g); } - for (int g = changed; g >= 2 ; g--) + for (int g = first_changed; g <= max_group; g++) _delta.y += print_section('H', g); } } diff --git a/include/reprint.h b/include/reprint.h index 5128b2a13..7044d2c81 100755 --- a/include/reprint.h +++ b/include/reprint.h @@ -79,6 +79,7 @@ protected: virtual void define_frame(const TRectangle& r); bool init(TReport& rep); + void reprint_group_headers(); long print_section(TReport_section& rs); long print_section(char type, int level); void create_links(const TReport_section& rs);