From 82a46370498e3d2caadb59ea74ad544cfa2dfd1b Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 7 Apr 2004 16:11:18 +0000 Subject: [PATCH] Patch level : 2.1 nopatch Files correlati : ba8.exe Ricompilazione Demo : [ ] Commento : Aggiunti messaggi in lingua MESSAGE, gestione GRUPPI e messaggi a gruppi git-svn-id: svn://10.65.10.50/trunk@11944 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ba/ba8201.h | 2 +- ba/ba8300.cpp | 40 +++--- ba/ba8300.h | 1 + ba/ba8300b.uml | 129 ++++++++++--------- ba/ba8302.cpp | 337 +++++++++++++++++++++++++++++++++++++------------ ba/ba8302.h | 15 ++- ba/ba8303.cpp | 3 + ba/ba8304.cpp | 150 +++++++++------------- ba/ba8304.h | 4 +- 9 files changed, 421 insertions(+), 260 deletions(-) diff --git a/ba/ba8201.h b/ba/ba8201.h index 5b66119a3..6907d98b8 100755 --- a/ba/ba8201.h +++ b/ba/ba8201.h @@ -26,7 +26,6 @@ class TVariant : public TSortable void* _ptr; protected: - virtual int compare(const TSortable& s) const; virtual TObject* dup() const { return new TVariant(*this); } void copy(const TVariant& var); @@ -57,6 +56,7 @@ public: void convert_to(TFieldtypes ft); + virtual int compare(const TSortable& s) const; TVariant& add(const TVariant& var); TVariant& sub(const TVariant& var); diff --git a/ba/ba8300.cpp b/ba/ba8300.cpp index c608270d3..88d372ead 100755 --- a/ba/ba8300.cpp +++ b/ba/ba8300.cpp @@ -73,7 +73,7 @@ public: void TFont_button_mask::update() { const TMask_field& fld = field(F_FONT_SELECT); - if (fld.active() && win() == win(0)) + if (fld.active() && win() == fld.parent()) { RCT rctfld; fld.get_rect(rctfld); const int x = rctfld.right / CHARX + 1; @@ -188,24 +188,21 @@ long TReport_field_mask::get_num(short id) const void TReport_field_mask::update() { - if (win() == win(0)) + for (int i = 0; i < 2; i++) { - for (int i = 0; i < 2; i++) + TMask_field& fld = field(i == 0 ? F_FGCOLOR : F_BGCOLOR); + if (fld.active() && fld.parent() == win()) { - TMask_field& fld = field(i == 0 ? F_FGCOLOR : F_BGCOLOR); - if (fld.active()) - { - 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); - } + 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); } - TFont_button_mask::update(); } + TFont_button_mask::update(); } void TReport_field_mask::vedo_non_vedo() @@ -278,6 +275,8 @@ void TReport_field_mask::set_field(const TReport_field& rf) set(F_HIDDEN, rf.hidden() ? "X" : ""); set(F_DISABLED, rf.deactivated() ? "X" : ""); set(F_HIDE_ZEROES, rf.zeroes_hidden() ? "X" : ""); + set(F_GROUPS, rf.groups()); + str[0] = rf.horizontal_alignment(); set(F_HALIGN, str); str[0] = rf.vertical_alignment(); @@ -288,6 +287,7 @@ void TReport_field_mask::set_field(const TReport_field& rf) set(F_TEXT, rf.picture()); set(F_SOURCE, rf.field()); set_font_info(rf.font()); + set(F_PRESCRIPT, rf.prescript()); set(F_POSTSCRIPT, rf.postscript()); } @@ -301,6 +301,7 @@ void TReport_field_mask::get_field(TReport_field& rf) const rf.show(!get_bool(F_HIDDEN)); rf.activate(!get_bool(F_DISABLED)); rf.hide_zeroes(get_bool(F_HIDE_ZEROES)); + rf.set_groups(get(F_GROUPS)); rf.set_horizontal_alignment(get(F_HALIGN)[0]); rf.set_vertical_alignment(get(F_VALIGN)[0]); @@ -312,6 +313,7 @@ void TReport_field_mask::get_field(TReport_field& rf) const TReport_font f; if (get_font_info(f)) rf.set_font(f); + rf.set_prescript(get(F_PRESCRIPT)); rf.set_postscript(get(F_POSTSCRIPT)); } @@ -741,16 +743,17 @@ void TReport_mask::add_field() { TReport_section& rs = curr_section(); TReport_field_mask m; - m.set(F_DX, 10); m.set(F_DY, 1); - m.set_font_info(rs.font()); + TReport_field* rf = new TReport_field(&rs); + m.set_field(*rf); m.disable(DLG_DELREC); if (m.run() == K_ENTER) { - TReport_field* rf = new TReport_field(&rs); m.get_field(*rf); rs.add(rf); update_report(); } + else + delete rf; } void TReport_mask::edit_field(TReport_field& rf) @@ -777,6 +780,7 @@ void TReport_mask::edit_field(TReport_field& rf) } if (key != K_ESC) { + _is_dirty = true; rf.section().sort(); update_report(); } diff --git a/ba/ba8300.h b/ba/ba8300.h index f141cabcc..44293d3ac 100755 --- a/ba/ba8300.h +++ b/ba/ba8300.h @@ -28,6 +28,7 @@ #define F_HIDE_ZEROES 125 #define F_PRESCRIPT 126 #define F_POSTSCRIPT 127 +#define F_GROUPS 128 #define F_LEVEL 130 #define F_GROUP_BY 131 diff --git a/ba/ba8300b.uml b/ba/ba8300b.uml index 6215727c3..730ddf651 100755 --- a/ba/ba8300b.uml +++ b/ba/ba8300b.uml @@ -4,7 +4,7 @@ PAGE "Campo" -1 -1 72 17 LIST F_TYPE 1 16 BEGIN - PROMPT 2 1 "Tipo " + PROMPT 1 0 "Tipo " ITEM "T|Testo" ITEM "S|Stringa" ITEM "N|Numero" @@ -17,109 +17,64 @@ BEGIN ITEM "E|Ellisse" END -GROUPBOX DLG_NULL 70 5 -BEGIN - PROMPT 1 0 "@bParametri generali" -END - NUMBER F_ID 4 BEGIN - PROMPT 30 1 "Identificatore " + PROMPT 30 0 "Identificatore " FLAGS "U" END STRING F_Y 6 BEGIN - PROMPT 2 2 "Riga " + PROMPT 1 1 "Riga " FLAGS "R" END STRING F_X 6 BEGIN - PROMPT 21 2 "Colonna " + PROMPT 21 1 "Colonna " FLAGS "R" END STRING F_DX 6 BEGIN - PROMPT 2 3 "Larghezza " + PROMPT 1 2 "Larghezza " FLAGS "R" END STRING F_DY 6 BEGIN - PROMPT 21 3 "Altezza " + PROMPT 21 2 "Altezza " FLAGS "R" END BOOLEAN F_HIDDEN BEGIN - PROMPT 39 2 "Nascosto" + PROMPT 39 1 "Nascosto" END BOOLEAN F_DISABLED BEGIN - PROMPT 39 3 "Disattivato" + PROMPT 39 2 "Disattivato" END BOOLEAN F_HIDE_ZEROES BEGIN - PROMPT 51 2 "Nascosto se zero" + PROMPT 53 1 "Nascosto se zero" END -GROUPBOX DLG_NULL 70 8 +STRING F_GROUPS 50 BEGIN - PROMPT 1 5 "@bParametri aspetto" + PROMPT 1 3 "Gruppi " END -LIST F_HALIGN 1 12 +MEMO F_TEXT 68 4 BEGIN - PROMPT 2 6 "Allineamento orizzontale " - ITEM "L|Sinistra" - ITEM "R|Destra" - ITEM "C|Centrato" - ITEM "J|Giustificato" + PROMPT 1 5 "@bTesto" END -LIST F_VALIGN 1 12 +MEMO F_SOURCE 68 4 BEGIN - PROMPT 44 6 "verticale " - ITEM "T|Alto" - ITEM "C|Centrato" - ITEM "B|Basso" -END - -BUTTON F_FGCOLOR 14 1 -BEGIN - PROMPT 2 7 "Colore ~Testo" -END - -BUTTON F_BGCOLOR 14 1 -BEGIN - PROMPT 2 8 "Colore ~Sfondo" -END - -BUTTON F_FONT_SELECT 14 2 -BEGIN - PROMPT 2 9 "~Font" -END - -LIST F_BORDER 1 12 -BEGIN - PROMPT 2 11 "Bordo " - ITEM "0|Nessuno" - ITEM "1|Normale" - ITEM "3|Spesso" -END - -ZOOM F_TEXT 58 -BEGIN - PROMPT 1 13 "Testo " -END - -ZOOM F_SOURCE 58 -BEGIN - PROMPT 1 14 "Sorgente " + PROMPT 1 10 "@bSorgente" END BUTTON DLG_CANCEL 10 2 @@ -139,6 +94,60 @@ END ENDPAGE +PAGE "Aspetto" -1 -1 72 16 + +LIST F_HALIGN 1 12 +BEGIN + PROMPT 1 1 "Allineamento orizzontale " + ITEM "L|Sinistra" + ITEM "R|Destra" + ITEM "C|Centrato" + ITEM "J|Giustificato" +END + +LIST F_VALIGN 1 12 +BEGIN + PROMPT 1 2 "Allineamento verticale " + ITEM "T|Alto" + ITEM "C|Centrato" + ITEM "B|Basso" +END + +BUTTON F_FGCOLOR 14 1 +BEGIN + PROMPT 2 4 "Colore ~Testo" +END + +BUTTON F_BGCOLOR 14 1 +BEGIN + PROMPT 2 5 "Colore ~Sfondo" +END + +BUTTON F_FONT_SELECT 14 2 +BEGIN + PROMPT 2 7 "~Font" +END + +LIST F_BORDER 1 12 +BEGIN + PROMPT 2 10 "Bordo " + ITEM "0|Nessuno" + ITEM "1|Normale" + ITEM "3|Spesso" +END + +BUTTON DLG_CANCEL 10 2 +BEGIN + PROMPT -13 -1 "" +END + +BUTTON DLG_OK 10 2 +BEGIN + PROMPT -33 -1 "" +END + +ENDPAGE + PAGE "Avanzate" -1 -1 72 16 MEMO F_PRESCRIPT 70 7 diff --git a/ba/ba8302.cpp b/ba/ba8302.cpp index e4dcaf2a7..4fffa3f8e 100755 --- a/ba/ba8302.cpp +++ b/ba/ba8302.cpp @@ -118,7 +118,7 @@ void TReport_font::save(TXmlItem& item) const bool TReport_font::load(const TXmlItem& item) { - const TXmlItem* font = item.FindFirst("font"); + const TXmlItem* font = item.FindFirstChild("font"); if (font != NULL) { const TString& name = font->GetAttr("face"); @@ -485,6 +485,10 @@ bool TReport_section::execute_prescript() if (active()) { TString80 str; + if (items() > 0) + report().set_curr_field(&field(0)); + else + report().set_curr_field(NULL); ok = _prescript.execute(report(), str); } for (int i = 0; i < items(); i++) @@ -558,7 +562,7 @@ void TReport_section::load(const TXmlItem& sec) if (level() > 1) { - const TXmlItem* gb = sec.FindFirst("groupby"); + const TXmlItem* gb = sec.FindFirstChild("groupby"); if (gb != NULL) { TString str; @@ -600,6 +604,84 @@ TReport_section::~TReport_section() // TReport_script /////////////////////////////////////////////////////////// +TString& TReport_script::translate_message() const +{ + TToken_string source(_src, '\n'); + TToken_string line(256, '|'); + TString cmd, arg, fld; + TString& alex = get_tmp_string(); + FOR_EACH_TOKEN(source, srcrow) + { + line = srcrow; + if (!line.starts_with("MESSAGE ")) + continue; + line.ltrim(8); line.trim(); + const bool msg_empty = line.starts_with("EMPTY "); + if (msg_empty) + { + line.ltrim(6); + line.trim(); + alex << "0 = IF "; + } + FOR_EACH_TOKEN(line, tok) + { + const TFixed_string msg(tok); + const int comma = msg.find(','); + if (comma > 0) + { + cmd = msg.left(comma); + arg = msg.mid(comma+1); + fld = arg; + if (fld[0] != '#') + fld.insert("#", 0); + } + else + { + cmd = msg; + arg.cut(0); + fld.cut(0); + } + + if (cmd.starts_with("CO")) // COPY + { + alex << "#THIS @ " << fld << " ! "; + } else + if (cmd.starts_with("AD")) // ADD + { + alex << "#THIS @ " << fld << " @ + "<< fld << " ! "; + } else + if (cmd.starts_with("IN")) // INC + { + alex << fld << " @ 1 + "<< fld << " ! "; + } else + if (cmd.starts_with("RE")) // RESET + { + alex << "\"\" " << fld << " ! "; + } else + if (cmd.starts_with("SH")) // SHOW + { + alex << fld << " SHOW "; + } else + if (cmd.starts_with("EN")) // EN + { + alex << fld << " ENABLE "; + } else + if (cmd.starts_with("DI")) // DISABLE + { + alex << fld << " DISABLE "; + } else + if (cmd.starts_with("HI")) // HIDE + { + alex << fld << " HIDE "; + } + } + if (msg_empty) + alex << "THEN "; + } + return alex; +} + + void TReport_script::set(const char* source) { if (_src != source) @@ -609,6 +691,7 @@ void TReport_script::set(const char* source) } } + bool TReport_script::execute(TReport& rep, TString& output) { bool good = ok(); @@ -617,7 +700,10 @@ bool TReport_script::execute(TReport& rep, TString& output) if (_bc == NULL) { _bc = new TBytecode; - good = rep.compile(_src, *_bc); + if (_src.starts_with("MESSAGE ")) + good = rep.compile(translate_message(), *_bc); + else + good = rep.compile(_src, *_bc); } if (good) good = rep.execute(*_bc, output); @@ -630,12 +716,10 @@ bool TReport_script::execute(TReport_field& rf) bool good = ok(); if (good) { - TString str(rf.type() == 'S' ? 1024 : 32); + TString str; TReport& rep = rf.section().report(); rep.set_curr_field(&rf); good = execute(rep, str); - if (good) - rf.set(str); } return good; } @@ -655,7 +739,6 @@ void TReport_script::save(TXmlItem& root, const char* tag) const if (ok()) { TXmlItem& script = root.AddChild(tag); - script.SetAttr("language", "Alex"); script << _src; } } @@ -663,7 +746,7 @@ void TReport_script::save(TXmlItem& root, const char* tag) const bool TReport_script::load(const TXmlItem& root, const char* tag) { destroy(); - TXmlItem* script = root.FindFirst(tag); + TXmlItem* script = root.FindFirstChild(tag); if (script != NULL) script->GetEnclosedText(_src); return ok(); @@ -915,7 +998,13 @@ void TReport_field::draw(TWindow& win, TReport_draw_mode rdm) const RCT r; win.log2dev(get_rect(), r); advanced_draw_rect(win, r, 1, COLOR_LTGRAY, COLOR_WHITE); } - draw_text(win, _field); + if (id() > 0) + { + TString16 str; str << id(); + draw_text(win, str); + } + else + draw_text(win, _field); } else draw_text(win, _var.as_string()); @@ -942,11 +1031,18 @@ void TReport_field::draw(TWindow& win, TReport_draw_mode rdm) const } } -void TReport_field::set_group(int group) -{ _groups.set(group); } +void TReport_field::set_groups(const TString& groups) +{ + _groups.reset(); + _groups.set(groups); +} -void TReport_field::reset_group(int group) -{ _groups.reset(group); } +const TString& TReport_field::groups() const +{ + TString& str = get_tmp_string(); + str << _groups; + return str; +} bool TReport_field::in_group(int group) const { @@ -974,11 +1070,7 @@ void TReport_field::save(TXmlItem& root) const if (has_font()) font().save(fld); if (in_group(0)) - { - TString str; - str << _groups; - fld.AddChild("groups") << str; - } + fld.AddChild("groups") << groups(); switch (horizontal_alignment()) { @@ -1019,19 +1111,18 @@ bool TReport_field::load(const TXmlItem& fld) 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"); + TXmlItem* src = fld.FindFirstChild("source"); if (src != NULL) src->GetEnclosedText(_field); TReport_font font; if (font.load(fld)) set_font(font); - TXmlItem* grp = fld.FindFirst("groups"); + TXmlItem* grp = fld.FindFirstChild("groups"); if (grp != NULL) { TString str; grp->GetEnclosedText(str); - istrstream ins(str.get_buffer(), str.size()); - ins >> _groups; + set_groups(str); } _prescript.load(fld, "prescript"); @@ -1146,34 +1237,61 @@ TReport_section& TReport::section(char type, int level) return *sec; } -TReport_field* TReport::field(const TString& code) +// Parsa un riferimento a campo, gruppo o sezione +// #B0 -> 2 B 0 +// #101 -> 3 B 1 101 +// #B1.101@ -> 4 B 1 101 +int TReport::parse_field(const char* code, char& type, int& level, int& id) const { - TReport_field* rf = NULL; - if (isdigit(code[0]) || code == "THIS") // Campo singolo, es: 101 o THIS + if (code[0] == '#') + code++; + + if (isdigit(code[0]) || strcmp(code, "THIS") == 0) // Niente sezione davanti { - rf = curr_field(); + TReport_field* rf = curr_field(); if (rf != NULL) { - if (code != "THIS") - rf = rf->section().find_field(atoi(code)); + type = rf->section().type(); + level = rf->section().level(); } + id = atoi(code); } else { - const char type = code[0]; - if (type != 'H' && type != 'B' && type != 'F') // Non comincia con un codsice sezione - return NULL; + type = code[0]; + if (type != 'H' && type != 'B' && type != 'F') // Non comincia con un codice sezione + return 0; + + level = atoi((const char*)code + 1); + TReport_section* sec = find_section(type, level); + if (sec == NULL) + return 1; + const int dot = code[2] == '.' ? 2 : (code[3] == '.' ? 3 : -1); if (dot <= 0) - return NULL; + return 2; + id = atoi((const char*)code + dot + 1); + } - const int level = atoi((const char*)code + 1); - TReport_section* sec = find_section(type, level); - if (sec != NULL) + return strchr(code, '@') != NULL ? 4 : 3; +} + +TReport_field* TReport::field(const TString& code) +{ + char type; + int level, id; + const int k = parse_field(code, type, level, id); + + TReport_field* rf = NULL; + if (k == 3) + { + if (id > 0) { - const int id = atoi((const char*)code + dot + 1); - rf = sec->find_field(id); + TReport_section& sec = section(type, level); + rf = sec.find_field(id); } + else + rf = curr_field(); } return rf; } @@ -1188,7 +1306,7 @@ bool TReport::evaluate(const char* expr, TVariant& var, TFieldtypes force_type) const char* name = e.varname(0); if (*name == '#' && strcmp(name, expr) == 0) { - const TFixed_string usr(name+1); + const TFixed_string usr(name); if (get_usr_val(usr, var)) { if (force_type != _nullfld) @@ -1264,14 +1382,14 @@ bool TReport::load(const char* fname) _lpi = xml.GetIntAttr("lpi", 6); _font.load(xml); - const TXmlItem* desc = xml.FindFirst("description"); + const TXmlItem* desc = xml.FindFirstChild("description"); if (desc != NULL) desc->GetEnclosedText(_description); - if (xml.FindFirst("section") != NULL) + if (xml.FindFirstChild("section") != NULL) load_sections(xml); - const TXmlItem* sql = xml.FindFirst("sql"); + const TXmlItem* sql = xml.FindFirstChild("sql"); if (sql != NULL) { TString str; @@ -1336,9 +1454,13 @@ bool TReport::execute_postscript() return _postscript.execute(*this, str); } -bool TReport::get_usr_val(const char* code, TVariant& var) const +bool TReport::get_usr_val(const TString& name, TVariant& var) const { - const TFixed_string name(*code != '#' ? code : (code+1)); + if (name == "#PAGE") + { + var = curr_page(); + return true; + } TReport_field* fld = ((TReport*)this)->field(name); if (fld != NULL) @@ -1347,15 +1469,15 @@ bool TReport::get_usr_val(const char* code, TVariant& var) const return true; } - if (name == "PAGE") - { - var = curr_page(); - return true; - } - if (_recordset != NULL) { - var = _recordset->get(name); + if (name[0] == '#') + { + const TFixed_string str((const char*)name + 1); + var = _recordset->get(str); + } + else + var = _recordset->get(name); if (!var.is_null()) return true; } @@ -1363,9 +1485,8 @@ bool TReport::get_usr_val(const char* code, TVariant& var) const return TAlex_virtual_machine::get_usr_val(name, var); } -bool TReport::set_usr_val(const char* code, const TVariant& var) +bool TReport::set_usr_val(const TString& name, const TVariant& var) { - const TFixed_string name(*code != '#' ? code : (code+1)); TReport_field* fld = field(name); if (fld != NULL) { @@ -1377,73 +1498,123 @@ bool TReport::set_usr_val(const char* code, const TVariant& var) unsigned int TReport::compile_usr_word(const TString& name) const { - const char* const names[5] = { NULL, "GET_RECT", "SET_BACK_COLOR", "SET_FORE_COLOR", "SET_RECT" }; - int i; - for (i = 4; i > 0; i--) + const int words = 9; + const char* const names[words] = { NULL, "DISABLE", "ENABLE", "GET_SIZE", "HIDE", + "SET_BACK_COLOR", "SET_FORE_COLOR", "SET_SIZE", "SHOW" }; + int i; + for (i = words-1; i > 0; i--) if (name == names[i]) break; return i; } -TReport_field* TReport::var2field(const TVariant& var) +static void do_show(TReport_field& rf, void* jolly) +{ rf.show(jolly != NULL); } + +static void do_enable(TReport_field& rf, void* jolly) +{ rf.activate(jolly != NULL); } + +static void do_set_size(TReport_field& rf, void* jolly) { - const TString& code = var.as_string(); - if (code[0] == '#') + const TPoint& pt = *(const TPoint*)jolly; + rf.set_size(pt.x, pt.y); +} + +static void do_set_back_color(TReport_field& rf, void* jolly) +{ rf.set_back_color((COLOR)jolly); } + +static void do_set_fore_color(TReport_field& rf, void* jolly) +{ rf.set_fore_color((COLOR)jolly); } + +bool TReport::do_message(const TVariant& var, FLDMSG_FUNC msg, void* jolly) +{ + char type; + int level, id; + const int k = parse_field(var.as_string(), type, level, id); + switch (k) { - const TFixed_string ref((const char*)code + 1); - return field(ref); + case 2: // E' una sezione + { + TReport_section& sec = section(type, level); + if (msg == do_show) + sec.show(jolly != 0); else + if (msg == do_enable) + sec.activate(jolly != 0); + } + break; + case 3: // E' un campo singolo + { + TReport_field* rf = id <= 0 ? curr_field() : section(type, level).find_field(id); + if (rf != NULL) + msg(*rf, jolly); + } + break; + case 4: // E' un gruppo + { + TReport_section& sec = section(type, level); + for (int i = 0; i < sec.items(); i++) + { + TReport_field& rf = sec.field(i); + if (rf.in_group(id)) + msg(rf, jolly); + } + } + break; + default: + break; } - return field(code); + return true; } bool TReport::execute_usr_word(unsigned int opcode, TVariant_stack& stack) { switch (opcode) { - case 1: // GET_RECT + case 1: // DISABLE + do_message(stack.pop(), do_enable, NULL); + break; + case 2: // ENABLE + do_message(stack.pop(), do_enable, (void*)1); + break; + case 3: // GET_SIZE { - const TReport_field* fld = var2field(stack.pop()); - real x, y, w, h; + const TReport_field* fld = field(stack.pop().as_string()); + real w, h; if (fld != NULL) { const TRectangle& r = fld->get_rect(); - x = r.x / CENTO; y = r.y / CENTO; w = r.width() / CENTO; h = r.height() / CENTO; } - stack.push(x); stack.push(y); stack.push(w); stack.push(h); } break; - case 2: // SET_BACK_COLOR + case 4: // HIDE + do_message(stack.pop(), do_show, NULL); + break; + case 5: // SET_BACK_COLOR { - TReport_field* fld = var2field(stack.pop()); const COLOR rgb = stack.pop().as_color(); - if (fld != NULL) - fld->set_back_color(rgb); + do_message(stack.pop(), do_set_back_color, (void*)rgb); } break; - case 3: // SET_FORE_COLOR + case 6: // SET_FORE_COLOR { - TReport_field* fld = var2field(stack.pop()); const COLOR rgb = stack.pop().as_color(); - if (fld != NULL) - fld->set_fore_color(rgb); + do_message(stack.pop(), do_set_fore_color, (void*)rgb); } break; - case 4: // SET_RECT + case 7: // SET_SIZE { - TReport_field* fld = var2field(stack.pop()); + const TVariant& fld = stack.pop(); const real h = stack.pop().as_real() * CENTO; const real w = stack.pop().as_real() * CENTO; - const real y = stack.pop().as_real() * CENTO; - const real x = stack.pop().as_real() * CENTO; - if (fld != NULL) - { - fld->set_pos(x.integer(), y.integer()); - fld->set_size(w.integer(), h.integer()); - } + const TPoint sz(w.integer(), h.integer()); + do_message(fld, do_set_size, (void*)&sz); } break; + case 8: // SHOW + do_message(stack.pop(), do_show, (void*)1); + break; default: return false; } diff --git a/ba/ba8302.h b/ba/ba8302.h index f8edcd6f3..0a2f09959 100755 --- a/ba/ba8302.h +++ b/ba/ba8302.h @@ -111,6 +111,7 @@ class TReport_script : public TObject protected: void destroy(); + TString& translate_message() const; public: virtual bool ok() const { return !_src.blank(); } @@ -279,8 +280,8 @@ public: bool zeroes_hidden() const { return _hide_zeroes; } void hide_zeroes(bool hz) { _hide_zeroes = hz; } - void set_group(int group); - void reset_group(int group); + void set_groups(const TString& groups); + const TString& groups() const; bool in_group(int group) const; void set_fore_color(COLOR c) { _fgcolor = c; } @@ -315,6 +316,8 @@ public: virtual ~TReport_field(); }; +typedef void (*FLDMSG_FUNC)(TReport_field& rf, void* jolly); + class TReport : public TAlex_virtual_machine { TAssoc_array _sections; @@ -332,9 +335,11 @@ class TReport : public TAlex_virtual_machine protected: virtual unsigned int compile_usr_word(const TString& name) const; virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); - virtual bool get_usr_val(const char* name, TVariant& var) const; - virtual bool set_usr_val(const char* name, const TVariant& var); - TReport_field* var2field(const TVariant& var); + virtual bool get_usr_val(const TString& name, TVariant& var) const; + virtual bool set_usr_val(const TString& name, const TVariant& var); + + int parse_field(const char* code, char& type, int& level, int& id) const; + bool do_message(const TVariant& var, FLDMSG_FUNC msg, void* jolly); void build_section_key(char type, int level, TString& key) const; short get_num_attr(const TXmlItem& item, const char* attr, short def = 0) const; diff --git a/ba/ba8303.cpp b/ba/ba8303.cpp index 68088afbb..1d1fa33da 100755 --- a/ba/ba8303.cpp +++ b/ba/ba8303.cpp @@ -149,6 +149,9 @@ TPrint_preview_window::TPrint_preview_window(int x, int y, int dx, int dy, WINDO TWindowed_field* owner, TPage_printer* printer) : TField_window(x, y, dx, dy, parent, owner), _printer(printer), _page(1), _last(0), _zoom(100) { + RCT r; xvt_vobj_get_client_rect(win(), &r); + _zoom = 100 * r.right / 800; + const TPoint ps = printer->page_size(); set_scroll_max(ps.x/4, ps.y/4); } diff --git a/ba/ba8304.cpp b/ba/ba8304.cpp index 371f4205e..4fd023cd1 100755 --- a/ba/ba8304.cpp +++ b/ba/ba8304.cpp @@ -64,8 +64,8 @@ bool TVariant_stack::push(const real& n) /////////////////////////////////////////////////////////// enum AVM_opcode { avm_nop, avm_add , avm_div , avm_dot, - avm_cmp_eq, avm_cmp_gt, avm_cmp_gteq, avm_cmp_lt, avm_cmp_lteq, avm_cmp_noteq, - avm_drop, avm_dup, + avm_cmp_eq, avm_cmp_gt, avm_cmp_gteq, avm_cmp_lt, avm_cmp_lteq, avm_cmp_noteq, + avm_drop, avm_dup, avm_else, avm_fetch, avm_if, avm_push, avm_rot, avm_store, avm_sub, avm_swap, avm_then, avm_usrword }; @@ -115,11 +115,11 @@ protected: bool get_token(istream& instr, TString& str) const; AVM_opcode token2opcode(const TString& str) const; void log_error(const char* str); + int compare_tos_nos(); public: const TString& get_last_error() const { return _last_error; } - bool compile_legacy_message(istream& instr, TBytecode& bytecode); bool compile(istream& instr, TBytecode& bc); bool execute(const TBytecode& bc, ostream& outstr); @@ -163,19 +163,18 @@ bool TAVM::get_token(istream& instr, TString& str) const AVM_opcode TAVM::token2opcode(const TString& str) const { - const char* AVM_TOKENS[19] = { + const char* AVM_TOKENS[20] = { "+", "-", ".", "!", "@", "/", "=", "<>", ">", "<", ">=", "<=", - "DROP", "DUP", "IF", "ROT", "SWAP", - "THEN", + "DROP", "DUP", "ELSE", "IF", "ROT", + "SWAP", "THEN", NULL }; - AVM_opcode AVM_OPCODES[19] = { + AVM_opcode AVM_OPCODES[20] = { avm_add, avm_sub, avm_dot, avm_store, avm_fetch, avm_div, avm_cmp_eq, avm_cmp_noteq, avm_cmp_gt, avm_cmp_lt, avm_cmp_gteq, avm_cmp_lteq, - avm_drop, avm_dup, avm_if, avm_rot, avm_swap, - avm_then, + avm_drop, avm_dup, avm_else, avm_if, avm_rot, avm_swap, avm_then, avm_nop }; @@ -192,14 +191,7 @@ bool TAVM::compile(istream& instr, TBytecode& bytecode) TString str(256); bytecode.destroy(); - bool ok = get_token(instr, str); - if (ok && str == "MESSAGE") - { - instr.seekg(0); - return compile_legacy_message(instr, bytecode); - } - - while (ok) + while (get_token(instr, str)) { TAVM_op* op = NULL; if (str[0] == '"') @@ -223,14 +215,34 @@ bool TAVM::compile(istream& instr, TBytecode& bytecode) { switch (oc) { - case avm_then: + case avm_else: { for (int i = bytecode.last(); i >= 0; i--) { TAVM_op& ifop = (TAVM_op&)bytecode[i]; if (ifop.op() == avm_if && ifop.var().is_null()) { - ifop.var() = bytecode.size(); + ifop.var() = bytecode.items() - i; + break; + } + } + if (i < 0) + { + _last_error = "ELSE without matching IF"; + log_error(_last_error); + return false; + } + } + op = new TAVM_op(oc); + break; + case avm_then: + { + for (int i = bytecode.last(); i >= 0; i--) + { + TAVM_op& ifop = (TAVM_op&)bytecode[i]; + if ((ifop.op() == avm_if || ifop.op() == avm_else) && ifop.var().is_null()) + { + ifop.var() = bytecode.last() - i; break; } } @@ -241,6 +253,7 @@ bool TAVM::compile(istream& instr, TBytecode& bytecode) return false; } } + op = new TAVM_op(oc); break; default: op = new TAVM_op(oc); @@ -262,15 +275,20 @@ bool TAVM::compile(istream& instr, TBytecode& bytecode) log_error(_last_error); return false; } - ok = get_token(instr, str); } return true; } +int TAVM::compare_tos_nos() +{ + const TVariant& v0 = _stack.pop(); + const TVariant& v1 = _stack.pop(); + return v0.compare(v1); +} + bool TAVM::execute(const TBytecode& bc, ostream& outstr) { - int ip = 0; - while (ip < bc.items()) + for (int ip = 0; ip < bc.items(); ip++) { const TAVM_op& op = *(const TAVM_op*)bc.objptr(ip); bool jumped_elsewhere = false; @@ -284,46 +302,22 @@ bool TAVM::execute(const TBytecode& bc, ostream& outstr) } break; case avm_cmp_eq: - { - const TVariant& v0 = _stack.pop(); - const TVariant& v1 = _stack.pop(); - _stack.push(v0 == v1); - } + _stack.push(compare_tos_nos() == 0); break; case avm_cmp_gt: - { - const TVariant& v0 = _stack.pop(); - const TVariant& v1 = _stack.pop(); - _stack.push(v0 > v1); - } + _stack.push(compare_tos_nos() > 0); break; case avm_cmp_gteq: - { - const TVariant& v0 = _stack.pop(); - const TVariant& v1 = _stack.pop(); - _stack.push(v0 >= v1); - } + _stack.push(compare_tos_nos() >= 0); break; case avm_cmp_lt: - { - const TVariant& v0 = _stack.pop(); - const TVariant& v1 = _stack.pop(); - _stack.push(v0 < v1); - } + _stack.push(compare_tos_nos() < 0); break; case avm_cmp_lteq: - { - const TVariant& v0 = _stack.pop(); - const TVariant& v1 = _stack.pop(); - _stack.push(v0 <= v1); - } + _stack.push(compare_tos_nos() <= 0); break; case avm_cmp_noteq: - { - const TVariant& v0 = _stack.pop(); - const TVariant& v1 = _stack.pop(); - _stack.push(v0 != v1); - } + _stack.push(compare_tos_nos() != 0); break; case avm_div: { @@ -339,6 +333,10 @@ bool TAVM::execute(const TBytecode& bc, ostream& outstr) case avm_dot: outstr << _stack.pop().as_string(); break; case avm_drop: _stack.drop(); break; case avm_dup: _stack.push(_stack.peek()); break; + case avm_else: + ip += op.var().as_int(); + jumped_elsewhere = true; + break; case avm_fetch: { const TString& name = _stack.pop().as_string(); @@ -355,7 +353,7 @@ bool TAVM::execute(const TBytecode& bc, ostream& outstr) case avm_if: if (!_stack.pop().as_bool()) { - ip = op.var().as_int(); + ip += op.var().as_int(); jumped_elsewhere = true; } break; @@ -366,10 +364,7 @@ bool TAVM::execute(const TBytecode& bc, ostream& outstr) const TString& name = _stack.pop().as_string(); const TVariant& var = _stack.pop(); if (name[0] == '#') - { - const TFixed_string usr((const char*)name+1); - _vm->set_usr_val(usr, var); - } + _vm->set_usr_val(name, var); else { // TBI: Set global var @@ -384,38 +379,13 @@ bool TAVM::execute(const TBytecode& bc, ostream& outstr) } break; case avm_swap: _stack.roll(1); break; + case avm_then: break; case avm_usrword: _vm->execute_usr_word(op.var().as_int(), _stack); break; default: _last_error << "Bad op code: " << op.op() << '\n'; log_error(_last_error); return false; } - if (!jumped_elsewhere) - ip++; - } - return true; -} - -bool TAVM::compile_legacy_message(istream& instr, TBytecode& bytecode) -{ - TToken_string line(1024); - while (instr.getline(line.get_buffer(), line.size())) if (line.starts_with("MESSAGE ")) - { - line.ltrim(8); line.trim(); - const bool msg_empty = line.starts_with("EMPTY "); - if (msg_empty) - { - line.ltrim(6); - line.trim(); - } - TToken_string cmd(80, ','); - FOR_EACH_TOKEN(line, tok) - { - cmd = tok; - if (cmd.starts_with("CO")) - { - } - } } return true; } @@ -459,21 +429,20 @@ bool TAlex_virtual_machine::execute(const TBytecode& bc, TString& outs) return execute(bc, outstr); } -bool TAlex_virtual_machine::get_usr_val(const char* code, TVariant& var) const +bool TAlex_virtual_machine::get_usr_val(const TString& name, TVariant& var) const { - const TFixed_string name(*code != '#' ? code : code+1); - if (name == "DATE") + if (name == "#DATE") { const TDate oggi(TODAY); var.set(oggi); return true; } - if (name == "FIRM") + if (name == "#FIRM") { var.set(prefix().get_codditta()); return true; } - if (name == "STUDY") + if (name == "#STUDY") { var.set(firm2dir(-1)); return true; @@ -481,10 +450,9 @@ bool TAlex_virtual_machine::get_usr_val(const char* code, TVariant& var) const return false; } -bool TAlex_virtual_machine::set_usr_val(const char* code, const TVariant& var) +bool TAlex_virtual_machine::set_usr_val(const TString& name, const TVariant& var) { - const TFixed_string name(*code != '#' ? code : code+1); - if (name == "FIRM") + if (name == "#FIRM") { return prefix().set_codditta(var.as_int()); } diff --git a/ba/ba8304.h b/ba/ba8304.h index 65cd3eb90..ab6076e03 100755 --- a/ba/ba8304.h +++ b/ba/ba8304.h @@ -46,8 +46,8 @@ class TAlex_virtual_machine : public TObject public: virtual unsigned int compile_usr_word(const TString& name) const; virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); - virtual bool get_usr_val(const char* name, TVariant& var) const; - virtual bool set_usr_val(const char* name, const TVariant& var); + virtual bool get_usr_val(const TString& name, TVariant& var) const; + virtual bool set_usr_val(const TString& name, const TVariant& var); const TString& get_last_error() const; bool compile(istream& instr, TBytecode& bc);