From b4ee199cbce36873f3964dc291cbba2b3712cb98 Mon Sep 17 00:00:00 2001 From: guy Date: Fri, 7 May 2004 10:27:35 +0000 Subject: [PATCH] Patch level : 2.1 nopatch Files correlati : Ricompilazione Demo : [ ] Commento : Spostato tutto in libreria git-svn-id: svn://10.65.10.50/trunk@12063 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ba/alex.alx | 11 +- ba/ba8200.cpp | 2 +- ba/ba8201.cpp | 2057 ------------------------------------------- ba/ba8201.h | 238 ----- ba/ba8300.cpp | 3 +- ba/ba8300m.uml | 49 ++ ba/ba8301.h | 2 +- ba/ba8302.cpp | 2265 ------------------------------------------------ ba/ba8302.h | 466 ---------- ba/ba8303.cpp | 918 -------------------- ba/ba8303.h | 100 --- ba/ba8304.cpp | 1271 --------------------------- ba/ba8304.h | 74 -- ba/ba8400.cpp | 9 +- ba/report.alx | 6 +- ba/ve1100.alx | 36 +- 16 files changed, 83 insertions(+), 7424 deletions(-) delete mode 100755 ba/ba8201.cpp delete mode 100755 ba/ba8201.h create mode 100755 ba/ba8300m.uml delete mode 100755 ba/ba8302.cpp delete mode 100755 ba/ba8302.h delete mode 100755 ba/ba8303.cpp delete mode 100755 ba/ba8303.h delete mode 100755 ba/ba8304.cpp delete mode 100755 ba/ba8304.h diff --git a/ba/alex.alx b/ba/alex.alx index 763d84ef2..f9c322ccc 100755 --- a/ba/alex.alx +++ b/ba/alex.alx @@ -18,15 +18,6 @@ SWAP OVER ; -: +! ( a1 n1 -- ) \ Incrementa la variabile a1 di n1 - DUP - IF - OVER @ + SWAP ! - ELSE - 2DROP - THEN -; - : INCR ( a1 -- ) - 1 +! + 1 SWAP +! ; diff --git a/ba/ba8200.cpp b/ba/ba8200.cpp index bf7bc0d65..62a81ee3b 100755 --- a/ba/ba8200.cpp +++ b/ba/ba8200.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -15,7 +16,6 @@ #include "../sqlite/sqlite.h" #include "ba8200.h" -#include "ba8201.h" /////////////////////////////////////////////////////////// // TRelation_node & TRelation_tree diff --git a/ba/ba8201.cpp b/ba/ba8201.cpp deleted file mode 100755 index ceed557ec..000000000 --- a/ba/ba8201.cpp +++ /dev/null @@ -1,2057 +0,0 @@ -#ifdef WIN32 -#include -#else -#include "../xvaga/incstr.h" -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include "ba8201.h" - -/////////////////////////////////////////////////////////// -// TVariant -/////////////////////////////////////////////////////////// - -static const TVariant NULL_VARIANT; - -void TVariant::set_null() -{ - if (_ptr != NULL) - { - if (_type != _nullfld && _type != _longfld) - delete _ptr; - _ptr = NULL; - } - _type = _nullfld; -} - -void TVariant::set(const char* str) -{ - if (str != NULL) - { - if (_type == _alfafld) - *((TString*)_ptr) = str; - else - { - set_null(); - _type = _alfafld; - _ptr = new TString(str); - } - } - else - set_null(); -} - -void TVariant::set(const real& r) -{ - if (_type == _realfld) - *((real*)_ptr) = r; - else - { - set_null(); - _type = _realfld; - _ptr = new real(r); - } -} - -void TVariant::set(const TDate& d) -{ - if (_type == _datefld) - *((TDate*)_ptr) = d; - else - { - set_null(); - _type = _datefld; - _ptr = new TDate(d); - } -} - -void TVariant::set(const long n) -{ - if (_type != _longfld) - set_null(); - _type = _longfld; - _ptr = (void*)n; -} - -bool TVariant::is_zero() const -{ - switch (_type) - { - case _datefld: return !as_date().ok(); - case _longfld: return _ptr == NULL; - case _realfld: return as_real().is_zero(); - case _alfafld: return as_string().empty(); - default: break; - } - return true; -} - -TDate TVariant::as_date() const -{ - if (_type == _datefld) - return *(TDate*)_ptr; - - const TDate d(as_int()); - return d; -} - -long TVariant::as_int() const -{ - long n = 0; - switch(_type) - { - case _datefld: n = as_date().date2ansi(); break; - case _longfld: n = (long)_ptr; break; - case _realfld: n = as_real().integer(); break; - case _alfafld: n = atoi(as_string()); break; - default : break; - } - return n; -} - -bool TVariant::as_bool() const -{ - bool ok = false; - if (_type == _alfafld) - ok = strchr("XY", as_string()[0]) != NULL; - else - ok = as_int() != 0; - return ok; -} - -COLOR TVariant::as_color() const -{ - const unsigned long rgb = as_int(); - unsigned char r = XVT_COLOR_GET_RED(rgb); - unsigned char g = XVT_COLOR_GET_GREEN(rgb); - unsigned char b = XVT_COLOR_GET_BLUE(rgb); - return MAKE_COLOR(r, g, b); -} - -real TVariant::as_real() const -{ - if (_type == _realfld) - return *(real*)_ptr; - switch(_type) - { - case _alfafld: return real(as_string()); break; - case _longfld: return real(as_int()); break; - default : break; - } - return ZERO; -} - -bool TVariant::as_string(TString& tmp) const -{ - tmp.cut(0); - switch(_type) - { - case _alfafld: tmp = *(TString*)_ptr; break; - case _datefld: tmp = as_date().string(); break; - case _longfld: tmp << as_int(); break; - case _realfld: tmp = as_real().string(); break; - default: break; - } - return !is_null(); -} - -const TString& TVariant::as_string() const -{ - if (_type == _alfafld) - return *(TString*)_ptr; - TString& tmp = get_tmp_string(); - as_string(tmp); - return tmp; -} - -void TVariant::convert_to(TFieldtypes ft) -{ - if (_type != ft) - { - switch (ft) - { - case _alfafld: set(as_string()); break; - case _datefld: set(as_date()); break; - case _longfld: set(as_int()); break; - case _realfld: set(as_real()); break; - default : set_null(); break; - } - } -} - -void TVariant::copy(const TVariant& var) -{ - switch (var._type) - { - case _datefld: set(var.as_date()); break; - case _longfld: set(var.as_int()); break; - case _realfld: set(var.as_real()); break; - case _alfafld: set(var.as_string()); break; - default : set_null(); break; - } -} - -int TVariant::compare(const TSortable& s) const -{ - const TVariant& var = (const TVariant&)s; - int cmp = 0; - switch (_type) - { - case _datefld: cmp = as_date() - var.as_date(); break; - case _longfld: cmp = as_int() - var.as_int(); break; - case _realfld: - { - const real n = as_real() - var.as_real(); - cmp = n.sign(); - } - break; - case _alfafld: cmp = as_string().compare(var.as_string()); break; - default : cmp = var.is_null() ? 0 : -1; - } - return cmp; -} - -TVariant& TVariant::add(const TVariant& var) -{ - switch (_type) - { - case _datefld: set(as_date() + var.as_int()); break; - case _longfld: set(as_int() + var.as_int()); break; - case _alfafld: *(TString*)_ptr << var.as_string(); break; - case _realfld: *(real*)_ptr += var.as_real(); break; - default: copy(var); break; - } - return *this; -} - -TVariant& TVariant::sub(const TVariant& var) -{ - switch (_type) - { - case _datefld: set(as_date() - var.as_int()); break; - case _longfld: - if (var.type() == _longfld) - { - set(as_int() - var.as_int()); - break; - } - // Fall down - default: - { - real n = as_real(); - n -= var.as_real(); - set(n); - } - break; - } - return *this; -} - -/////////////////////////////////////////////////////////// -// TTable name converter -/////////////////////////////////////////////////////////// - -class TTable_names : public TObject -{ - TAssoc_array _names; - TArray _ids; - long _filled; - -protected: - void fill(); - void add_file(int logic, const TString& table); - -public: - const TString& name(int logic_num); - int logic_num(const TString& name); - - TTable_names() : _filled(0) { } -} _table_names; - -void TTable_names::add_file(int logic, const TString& table) -{ - TString8* id = new TString8; - id->format("%d", logic); - _names.add(table, id); - _ids.add(table, logic); -} - -void TTable_names::fill() -{ - if (_filled != prefix().get_codditta()) - { - FileDes dir; - CGetFile(LF_DIR, &dir, _nolock, NORDIR); - const int nfiles = (int)dir.EOD; - - TFilename n; - for (int logic = LF_USER; logic < nfiles; logic++) - { - const FileDes& fd = prefix().get_filedes(logic); - n = fd.SysName; n = n.name(); n.upper(); - if (_names.objptr(n) == NULL) - add_file(logic, n); - } - _filled = prefix().get_codditta(); - } -} - -int TTable_names::logic_num(const TString& name) -{ - if (isdigit(name[0])) - { - int num = atoi(name); - if (name[name.len()-1] == '@') - num = -num; - return num; - } - - if (name[0] == '%' && name.len() == 4) - return LF_TABCOM; - - if (name.len() == 3) - return LF_TAB; - - TString* str = (TString*)_names.objptr(name); - if (str == NULL) - { - fill(); - str = (TString*)_names.objptr(name); - } - return str == NULL ? 0 : atoi(*str); -} - -const TString& TTable_names::name(int logic_num) -{ - TString* str = (TString*)_ids.objptr(logic_num); - if (str == NULL) - { - fill(); - str = (TString*)_ids.objptr(logic_num); - } - return str == NULL ? (const TString&)EMPTY_STRING : *str; -} - -const TString& logic2table(int logic_num) -{ return _table_names.name(logic_num); } - -int table2logic(const TString& name) -{ return _table_names.logic_num(name); } - - -/////////////////////////////////////////////////////////// -// Utility -/////////////////////////////////////////////////////////// - -static bool is_numeric(const char* str) -{ - if (str == NULL || *str == '\0' || *str == '0') - return false; // Se comincia per zero va preservato! - if (*str == '-') - { - str++; - if (*str <= ' ') - return false; - } - while (*str) - { - if (strchr("0123456789.", *str) == NULL) - return false; - str++; - } - return true; -} - -/////////////////////////////////////////////////////////// -// TRecordset -/////////////////////////////////////////////////////////// - -const TString& TRecordset::query_text() const -{ - return EMPTY_STRING; -} - -const TToken_string& TRecordset::sheet_head() const -{ - TToken_string head; - TToken_string tablefield(32, '.'); - for (unsigned int c = 0; c < columns(); c++) - { - const TRecordset_column_info& ci = column_info(c); - tablefield = ci._name; - int maxlen = 0; - FOR_EACH_TOKEN(tablefield, tok) - { - if (maxlen == 0) - head.add(tok); - else - head << '\n' << tok; - const int len = strlen(tok); - if (len > maxlen) - maxlen = len; - } - head << '@' << max(ci._width, maxlen); - if (ci._type == _wordfld || ci._type == _intfld || ci._type == _longfld || ci._type == _realfld) - head << 'R'; - } - - // Creo la stringa temporanea solo ora, altrimenti puo' essere sovrascritta! - TToken_string& h = get_tmp_string(); - h = head; - return h; -} - -bool TRecordset::save_as_html(const char* path) -{ - TProgind pi(items(), TR("Esportazione in corso..."), true, true); - ofstream out(path); - out << "" << endl; - out << "" << endl; - out << "" << endl; - out << " " << endl; - - out << " "; - for (unsigned int c = 0; c < columns(); c++) - { - const TRecordset_column_info& ci = column_info(c); - TToken_string header(ci._name, '.'); - TString str; - FOR_EACH_TOKEN(header, tok) - { - if (str.not_empty()) - str << "
"; - str << tok; - } - out << " " << endl; - } - out << " " << endl; - - TString val; - for (TRecnotype n = 0; n < items(); n++) - { - move_to(n); - pi.addstatus(1); - if (pi.iscancelled()) - break; - out << " " << endl; - for (unsigned int c = 0; c < columns(); c++) - { - const TRecordset_column_info& ci = column_info(c); - out << " "; - get(c).as_string(val); - if (!val.blank()) - { - val.rtrim(); - out << val; - } - out << " " << endl; - } - out << " " << endl; - } - - out << "

" << path << "

" << str << "
" << endl; - out << "" << endl; - out << "" << endl; - - return !pi.iscancelled(); -} - -bool TRecordset::save_as_silk(const char* path) -{ - TProgind pi(items(), TR("Esportazione in corso..."), true, true); - - ofstream out(path); - out << "ID;PWXL;N;E" << endl; - - for (unsigned int c = 0; c < columns(); c++) - { - const TRecordset_column_info& ci = column_info(c); - out << "C;Y1;X" << (c+1) << ";K\"" << ci._name << '"' << endl; - } - - TString val; - for (TRecnotype n = 0; n < items(); n++) - { - move_to(n); - pi.addstatus(1); - if (pi.iscancelled()) - break; - for (unsigned int c = 0; c < columns(); c++) - { - out << "C;Y" << (n+2) << ";X" << (c+1) << ";K\""; - get(c).as_string(val); - if (!val.blank()) - { - val.rtrim(); - val.replace('"', '\''); - out << val; - } - out << '"' << endl; - } - } - out << "E" << endl; - - return !pi.iscancelled(); -} - -bool TRecordset::save_as_text(const char* path) -{ - TProgind pi(items(), TR("Esportazione in corso..."), true, true); - - ofstream out(path); - TString val; - for (TRecnotype n = 0; n < items(); n++) - { - move_to(n); - for (unsigned int c = 0; c < columns(); c++) - { - if (c > 0) - out << '\t'; - get(c).as_string(val); - if (!val.blank()) - { - val.rtrim(); - out << val; - } - } - out << endl; - pi.addstatus(1); - if (pi.iscancelled()) - break; - } - - return !pi.iscancelled(); -} - -bool TRecordset::save_as_campo(const char* path) -{ - TProgind pi(items(), TR("Esportazione in corso..."), true, true); - ofstream out(path); - - out << "[Head]" << endl; - out << "Version=0"; - - for (unsigned int c = 0; c < columns(); c++) - { - const TRecordset_column_info& ci = column_info(c); - if ((c % 8) == 0) - out << endl << "Fields="; - else - out << '|'; - out << ci._name; - } - out << endl << endl << "[Data]" << endl; - - TString val; - for (TRecnotype n = 0; n < items(); n++) - { - move_to(n); - for (unsigned int c = 0; c < columns(); c++) - { - if (c > 0) - out << '|'; - get(c).as_string(val); - if (!val.blank()) - { - val.rtrim(); - out << val; - } - } - out << endl; - pi.addstatus(1); - if (pi.iscancelled()) - break; - } - return !pi.iscancelled(); -} - -bool TRecordset::save_as(const char* path, TRecordsetExportFormat fmt) -{ - if (fmt == fmt_unknown) - { - TString ext; - xvt_fsys_parse_pathname(path, NULL, NULL, NULL, ext.get_buffer(), NULL); - ext.lower(); - if (ext.starts_with("htm")) - fmt = fmt_html; else - if (ext == "xls" || ext == "slk") - fmt = fmt_silk; - } - bool ok = false; - switch (fmt) - { - case fmt_html : ok = save_as_html(path); break; - case fmt_silk : ok = save_as_silk(path); break; - case fmt_campo: ok = save_as_campo(path); break; - default : ok = save_as_text(path); break; - } - - return ok; -} - -int TRecordset::find_column(const char* column_name) const -{ - for (int i = columns()-1; i >= 0; i--) - { - const TRecordset_column_info& info = column_info(i); - if (info._name == column_name) - break; - } - return i; -} - -const TVariant& TRecordset::get(const char* column_name) const -{ - if (*column_name == '#') - { - if (variables().items() > 0) - { - const TVariant& var = get_var(column_name); - if (!var.is_null()) - return var; - } - column_name++; - } - - char* colon = strchr(column_name, ':'); - if (colon != NULL) - { - *colon = '\0'; - const int i = find_column(column_name); - *colon = ':'; - if (i >= 0) - { - const TString& str = get(i).as_string(); - TString subfield; subfield << (colon+1) << '='; - int s = str.find(subfield); - if (s == 0 || (s > 0 && str[s-1] < ' ')) - { - static TVariant var; - s += subfield.len(); - const int e = str.find('\n', s); - var.set(str.sub(s, e)); - return var; - } - } - } - else - { - const int i = find_column(column_name); - if (i >= 0) - return get(i); - } - - return NULL_VARIANT; -} - -const TVariant& TRecordset::get_var(const char* name) const -{ - const TVariant* var = (const TVariant*)_var.objptr(name); - return var != NULL ? *var : NULL_VARIANT; -} - -bool TRecordset::set_var(const char* name, const TVariant& var, bool create) -{ - bool ok = false; - TVariant* old = (TVariant*)_var.objptr(name); - if (old != NULL) - { - *old = var; - ok = true; - } - else - { - if (create) - { - _var.add(name, var); - _varnames.add(name); - ok = true; - } - } - return ok; -} - -bool is_var_separator(char c) -{ - if (isspace(c)) - return true; - return strchr("<=>,", c) != NULL; -} - -// Cerca le variabili nel testo SQL: -// Una variabile comincia per # ed e' composta da soli caratteri alfanumerici. -// Prima del simbolo # e dopo il nome della variabile deve esserci un separatore o blank -void TRecordset::find_and_reset_vars() -{ - _var.destroy(); - _varnames.destroy(); - - const TString& sql = query_text(); - int diesis = sql.find('#'); // cerco il primo # - for ( ; diesis > 0; diesis = sql.find('#', diesis+1)) // Cerco tutti i # - { - if (is_var_separator(sql[diesis-1])) // Controllo che ci sia un separatore prima del # - { - int i = diesis+1; - for ( ; sql[i] && (isalnum(sql[i]) || sql[i] == '_'); i++); - if (i > diesis+1) - { - const TString& name = sql.sub(diesis, i); - set_var(name, NULL_VARIANT, true); - } - } - } -} - -void TRecordset::parsed_text(TString& sql) const -{ - sql = query_text(); - const bool vars = ((TSQL_recordset*)this)->ask_variables(false); - if (vars) // Se ci sono variabili faccio le sostituzioni - { - const TString_array& names = variables(); - FOR_EACH_ARRAY_ROW(names, i, name) // Scandisco tutte le variabili - { - TVariant var = get_var(*name); - int pos = sql.find(*name); - for ( ; pos > 0; pos = sql.find(*name, pos+1)) - { - const TString& after = sql.mid(pos+name->len()); - sql.cut(pos); - TString s = var.as_string(); - if ((var.is_string() && s[0] != '\'') || var.is_null()) - { - s.insert("'"); - s << '\''; - } - sql << s << after; - } - } - } -} - -bool ask_variable(const char* name, TVariant& var) -{ - TMask m("Richiesta variabile", 1, 52, 4); - m.add_static(-1, 0, name, 1, 0); - m.add_string(101, 0, "", 1, 1, 80, "", 50); - m.add_button(DLG_OK, 0, "", -12, -1, 10, 2); - m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2); - m.set(101, var.as_string()); - const bool ok = m.run() == K_ENTER; - if (ok) - { - const TString& str = m.get(101); - if (is_numeric(str)) - var = real(str); - else - var = str; - } - return ok; -} - -bool TRecordset::ask_variables(bool all) -{ - const bool ok = variables().items() > 0; - if (ok) // Se ci sono variabili faccio le sostituzioni - { - FOR_EACH_ARRAY_ROW(_varnames, i, name) - { - TVariant var = get_var(*name); - if (var.is_null() || all) - { - ask_variable(*name, var); - if (var.is_null()) - var.set(""); // Mi serve assolutamente un valore! - - set_var(*name, var); - } - } - } - return ok; -} - -/////////////////////////////////////////////////////////// -// Utility -/////////////////////////////////////////////////////////// - -bool select_custom_file(TFilename& path, const char* ext) -{ - TFilename custom = firm2dir(-1); - custom.add("custom"); - if (!custom.exist()) - xvt_fsys_mkdir(custom); - - path = custom; - path.add("*"); - path.ext(ext); - - TString_array files; - list_files(path, files); - - TArray_sheet sheet(-1, -1, 78, 20, TR("Selezione"), TR("Nome@20|Descrizione@50")); - - TString str; - FOR_EACH_ARRAY_ROW(files, i, row) - { - - TXmlItem item; - if (item.Load(*row)) - { - TToken_string* riga = new TToken_string; - path = *row; - path = path.name(); - path.ext(""); - riga->add(path); - - const TXmlItem* desc = item.FindFirst("description"); - str = *row; - if (desc != NULL) - desc->GetEnclosedText(str); - riga->add(str); - - sheet.add(riga); - } - } - - const bool ok = sheet.run() == K_ENTER; - if (ok) - { - path = custom; - path.add(sheet.row(-1).get(0)); - path.ext(ext); - } - return ok; -} - - -/////////////////////////////////////////////////////////// -// Private interface -/////////////////////////////////////////////////////////// - -#include "../sqlite/sqlite.h" - - -class TSQLite : public TObject -{ - sqlite* _handle; - TFilename _currdb; - -protected: - TVariant& get_sql_value(const TRectype& curr, const RecFieldDes& fd, TVariant& tmp) const; - - void build_curr_path(TFilename& name) const; - void test_path(); - - bool esporta(const TRectype& rec, ostream& sql) const; - bool create_dbf_times(); - long get_dbf_time(const TString& table); - bool set_dbf_time(const TString& table, long last); - bool import(int logicnum); - -public: - sqlite* open(const char* fname = NULL); - bool exec(const char* sql, sqlite_callback callback = NULL, void* jolly = NULL, bool show_error = true); - void close(); - - bool exists(const char* table); - bool parse_select_from(const char* szSql); - - TSQLite(); - virtual ~TSQLite(); -} _TheDataBase; - -void get_sql_directory(TFilename& name) -{ - name = firm2dir(-1); - name.add("sql"); - if (!name.exist()) - make_dir(name); -} - -void TSQLite::build_curr_path(TFilename& name) const -{ - TString16 firm; firm.format("%05ldA.sql", prefix().get_codditta()); - get_sql_directory(name); - name.add(firm); -} - -sqlite* TSQLite::open(const char* fname) -{ - close(); - _currdb = fname; - char* errmsg = NULL; - _handle = sqlite_open(_currdb, 0, &errmsg); - if (errmsg != NULL) - { - error_box(errmsg); - sqlite_freemem(errmsg); - } - - create_dbf_times(); - - return _handle; -} - -void TSQLite::test_path() -{ - TFilename n; - build_curr_path(n); - if (n != _currdb) - open(n); -} - -bool TSQLite::exec(const char* sql, sqlite_callback callback, void* jolly, bool show_error) -{ - if (_handle == NULL) - test_path(); - - TWait_cursor hourglass; - char* errmsg = NULL; - const int rc = sqlite_exec(_handle, sql, callback, jolly, &errmsg); - if (errmsg != NULL) - { - if (show_error) - { - TString msg; - msg << sql; - msg.cut(128); - msg << '\n' << errmsg; - error_box(msg); - } - sqlite_freemem(errmsg); - } - return rc == SQLITE_OK; -} - -void TSQLite::close() -{ - if (_handle != NULL) - { - sqlite_close(_handle); - _handle = NULL; - } -} - -const char* const DBF_TIMES_TABLE = "DBF_TIMES"; - -bool TSQLite::create_dbf_times() -{ - bool ok = exists(DBF_TIMES_TABLE); - if (!ok) - { - TString sql; - sql << "CREATE TABLE " << DBF_TIMES_TABLE << " (name TEXT,time NUMERIC);\n" - << "CREATE UNIQUE INDEX " << DBF_TIMES_TABLE << "_1 ON " << DBF_TIMES_TABLE << " (name);"; - ok = exec(sql); - } - return ok; -} - -bool TSQLite::set_dbf_time(const TString& table, long last) -{ - TString sql; - sql << "REPLACE INTO " << DBF_TIMES_TABLE << " VALUES(" - << '\'' << table << "','" << last << "');"; - return exec(sql); -} - -static int dbf_time_callback(void* jolly, int argc, char** argv, char** columns) -{ - long& last = *(long*)jolly; - last = atol(argv[0]); - return SQLITE_OK; -} - -long TSQLite::get_dbf_time(const TString& table) -{ - TString sql; - sql << "SELECT time FROM " << DBF_TIMES_TABLE << " WHERE name='" << table << "';"; - long last = 0; - exec(sql, dbf_time_callback, &last); - return last; -} - -TVariant& TSQLite::get_sql_value(const TRectype& curr, const RecFieldDes& fd, TVariant& tmp) const -{ - switch (fd.TypeF) - { - case _realfld : tmp.set(curr.get_real(fd.Name)); break; - case _intfld : - case _longfld : - case _wordfld : - case _intzerofld : - case _longzerofld: tmp.set(curr.get_long(fd.Name)); break; - case _datefld : - { - const TDate date = curr.get_date(fd.Name); - tmp.set(date.date2ansi()); - } - break; - case _boolfld : tmp.set(curr.get_bool(fd.Name)); break; - case _memofld: - { - TString memo = curr.get(fd.Name); - memo.replace('\n', char(0xB6)); // Simbolo di paragrafo - tmp.set(memo); - } - break; - default : tmp.set(curr.get(fd.Name)); break; - } - return tmp; -} - -static int exists_callback(void *jolly, int argc, char **argv, char **azColName) -{ - bool& yes = *(bool*)jolly; - yes = argc > 0; - return SQLITE_OK; -} - -bool TSQLite::exists(const char* table) -{ - TString sql; - sql << "SELECT name FROM sqlite_master WHERE (type='table')AND(name='" << table << "');"; - bool yes = false; - exec(sql, exists_callback, &yes, false); - return yes; -} - -bool TSQLite::esporta(const TRectype& rec, ostream& sql) const -{ - const RecDes& rd = *rec.rec_des(); - TVariant tmp; - for (int i = 0; i < rd.NFields; i++) - { - if (i > 0) sql << '\t'; - get_sql_value(rec, rd.Fd[i], tmp); - sql << tmp.as_string(); - } - sql << '\n'; - return true; -} - -bool TSQLite::import(int logicnum) -{ - const TString& table = logic2table(logicnum); - - long last = get_dbf_time(table); - if (logicnum >= LF_USER) // Dummy test - { - TLocalisamfile file(logicnum); - if (!file.is_changed_since(last)) - return true; - } - - const RecDes& rd = prefix().get_recdes(logicnum); - - TString sql; - if (exists(table)) - { - // Drop old table - sql.cut(0) << "DROP TABLE "<< table << ';'; - exec(sql); - } - - // Create new table - sql.cut(0) << "CREATE TABLE "<< table << "\n("; - for (int i = 0; i < rd.NFields; i++) - { - if (i > 0) sql << ','; - sql << rd.Fd[i].Name << ' '; - switch (rd.Fd[i].TypeF) - { - case _alfafld: sql << "TEXT"; break; - case _memofld: sql << "BLOB"; break; - case _datefld: sql << "DATE"; break; - default : sql << "NUMERIC"; break; - } - } - sql << ");"; - if (!exec(sql)) - return false; - - // Creazione indici - for (int index = 0; index < rd.NKeys; index++) - { - sql.cut(0) << "CREATE INDEX " << table << '_' << (index+1) << " ON "<< table << "\n("; - const KeyDes& kd = rd.Ky[index]; - for (int k = 0; k < kd.NkFields; k++) - { - if (k > 0) sql << ','; - const int ndx = kd.FieldSeq[k] % MaxFields; - sql << rd.Fd[ndx].Name; - } - sql << ");"; - exec(sql); - } - - TRelation rel(logicnum); - TCursor cur(&rel); - const TRecnotype items = cur.items(); - cur.freeze(); - const TRectype& curr = rel.curr(); - - TString msg; - msg << TR("Esportazione tabella") << ' ' << table; - msg << ": " << items << ' ' << TR("righe"); - TProgind pi(items, msg, true, true); - - TFilename tmp; tmp.tempdir(); tmp.add("sql.txt"); - ofstream txt(tmp, ios::binary); - - for (cur = 0; cur.pos() < items; ++cur) - { - esporta(curr, txt); - pi.addstatus(1); - if (pi.iscancelled()) - break; - } - - txt.close(); - - msg << '\n' << TR("Importazione tabella") << ' ' << table; - msg << ": " << items << ' ' << TR("righe"); - pi.set_text(msg); - - sql.cut(0) << "COPY " << table << " FROM '" << tmp << "';"; - if (exec(sql)) - set_dbf_time(table, last); // Aggiorna ora di ultima modifica - - ::remove(tmp); - - return true; -} - -bool TSQLite::parse_select_from(const char* szSql) -{ - test_path(); - - TString sql(szSql); - sql.trim(); sql.upper(); - if (!sql.starts_with("SELECT")) - return false; - - const int from = sql.find("FROM"); - if (from < 0) - return false; - - const int where = sql.find("WHERE", from); - TToken_string tables(sql.sub(from+5, where), ','); - TString table; - FOR_EACH_TOKEN(tables, tok) - { - table = tok; - table.trim(); - for (int i = 0; table[i]; i++) - { - if (table[i] <= ' ' || table[i] == ';') - { table.cut(i); break; } - } - const int logicnum = table2logic(table); - if (logicnum > 0) - import(logicnum); - } - - return true; -} - -TSQLite::TSQLite() : _handle(NULL) -{ } - -TSQLite::~TSQLite() -{ - close(); -} - -/////////////////////////////////////////////////////////// -// TSQL_recordset -/////////////////////////////////////////////////////////// - -void TSQL_recordset::reset() -{ - _items = 0; - _pagesize = 512; - _page.destroy(); - _column.destroy(); -} - -int TSQL_recordset::on_get_items(int argc, char** values, char** columns) -{ - if (_column.items() == 0) - { - for (int i = 0; i < argc; i++) - { - TRecordset_column_info* info = new TRecordset_column_info; - info->_name = columns[i]; - info->_width = 1; - info->_type = _alfafld; - - const char* fldtype = columns[argc+i]; - if (fldtype != NULL) - { - if (xvt_str_compare_ignoring_case(fldtype, "DATE") == 0) - { - info->_type = _datefld; - info->_width = 10; - } else - if (xvt_str_compare_ignoring_case(fldtype, "NUMERIC") == 0) - { - info->_type = _realfld; - } else - if (xvt_str_compare_ignoring_case(fldtype, "BLOB") == 0) - { - info->_type = _memofld; - info->_width = 50; - } - } - _column.add(info); - } - } - if (_items < _pagesize) - { - for (int i = 0; i < argc; i++) if (values[i] && *values[i]) - { - TRecordset_column_info& info = (TRecordset_column_info&)_column[i]; - if (info._type == _alfafld || info._type == _realfld) - { - const int len = strlen(values[i]); - if (len > info._width) - info._width = len; - } - } - } - - _items++; - return SQLITE_OK; -} - -static int query_get_items(void* jolly, int argc, char** values, char** columns) -{ - TSQL_recordset* q = (TSQL_recordset*)jolly; - return q->on_get_items(argc, values, columns); -} - -bool TSQL_recordset::ask_variables(bool all) -{ - const bool ok = TRecordset::ask_variables(all); - if (ok) - _page.destroy(); - return ok; -} - -TRecnotype TSQL_recordset::items() const -{ - if (_items == 0) - { - TString sql; parsed_text(sql); - TProfiler prof("SQL query"); - _TheDataBase.exec("PRAGMA show_datatypes = ON;", NULL, NULL); - _TheDataBase.exec(sql, query_get_items, (TSQL_recordset*)this); - _TheDataBase.exec("PRAGMA show_datatypes = OFF;", NULL, NULL); - } - return _items; -} - -unsigned int TSQL_recordset::columns() const -{ - if (_column.items() == 0) - items(); - return _column.items(); -} - -const TRecordset_column_info& TSQL_recordset::column_info(unsigned int c) const -{ - return (const TRecordset_column_info&)_column[c]; -} - -// Funzione chiamata per riempire la pagina corrente delle righe della query -int TSQL_recordset::on_get_rows(int argc, char** values, char** columns) -{ - TArray* a = new TArray; - for (int c = 0; c < argc; c++) - { - TVariant* var = new TVariant; - switch (column_info(c)._type) - { - case _alfafld: - var->set(values[c]); - break; - case _memofld: - { - TFixed_string memo(values[c]); - memo.replace(char(0xB6), '\n'); - var->set(memo); - } - break; - case _datefld: - var->set(TDate(values[c])); - break; - default: - var->set(real(values[c])); - break; - } - a->add(var, c); - } - _page.add(a); - return SQLITE_OK; -} - -static int query_get_rows(void* jolly, int argc, char** values, char** columns) -{ - TSQL_recordset* rs = (TSQL_recordset*)jolly; - return rs->on_get_rows(argc, values, columns); -} - -bool TSQL_recordset::move_to(TRecnotype n) -{ - _current_row = n; - if (n < 0 || n >= items()) - { - _page.destroy(); // Forza rilettura la prossiva volta - _first_row = 0; - return false; - } - - if (n < _first_row || n >= _first_row+_page.items()) - { - TString sql; parsed_text(sql); - if (sql.find("LIMIT ") < 0) - { - const int semicolon = sql.rfind(';'); - if (semicolon >= 0) - sql.cut(semicolon); - sql.trim(); - _page.destroy(); - if (n >= _pagesize) - _first_row = n-_pagesize/8; // Prendo qualche riga dalla pagina precedente, per velocizzare il pagina su - else - _first_row = n; - sql << "\nLIMIT " << _pagesize << " OFFSET " << _first_row << ';'; - } - _TheDataBase.exec(sql, query_get_rows, this); - } - - return true; -} - -const TArray* TSQL_recordset::row(TRecnotype n) -{ - const TArray* a = NULL; - if (move_to(n)) - a = (const TArray*)_page.objptr(n-_first_row); - return a; -} - -const TVariant& TSQL_recordset::get(unsigned int c) const -{ - const TArray* a = (const TArray*)_page.objptr(_current_row-_first_row); - if (a != NULL) - { - const TVariant* s = (const TVariant*)a->objptr(c); - if (s != NULL) - return *s; - } - return NULL_VARIANT; -} - -void TSQL_recordset::set(const char* sql) -{ - reset(); - _sql = sql; - if (_sql.find("SELECT") >= 0 || _sql.find("select") >= 0) - { - _TheDataBase.parse_select_from(_sql); - find_and_reset_vars(); - } -} - -TSQL_recordset::TSQL_recordset(const char* sql) -{ - set(sql); -} - -/////////////////////////////////////////////////////////// -// TCursor_parser -/////////////////////////////////////////////////////////// - -class TCursor_parser -{ - istream& _instr; - TArray& _column; - - TString _pushed; - TString _token; - - TRelation* _relation; - TCursor* _cursor; - -protected: - const TString& pop(); - void push(); - void add_column_info(const char* table, const TRectype& rec); - - void parse_sortexpr(TToken_string& se); - void parse_filter(TToken_string& filter); - void parse_region(TRectype& rec); - void parse_join_param(TRelation* rel, const TString& j, int to); - void parse_join(); - void parse_sortedjoin(); - -public: - TRelation* get_relation() { return _relation; } - TCursor* get_cursor() { return _cursor; } - - TCursor_parser(istream& instr, TArray& column); -}; - -const TString& TCursor_parser::pop() -{ - if (_pushed.not_empty()) - { - _token = _pushed; - _pushed.cut(0); - } - else - { - _token.cut(0); - - _instr.eatwhite(); - if (_instr.eof()) - return _token; - - char c; - _instr.get(c); - while (!isspace(c) && c != EOF) - { - _token << c; - _instr.get(c); - } - } - return _token; -} - -void TCursor_parser::push() -{ - CHECK(_pushed.empty(), "Repushing?"); - _pushed = _token; -} - -void TCursor_parser::add_column_info(const char* table, const TRectype& rec) -{ - for (int i = 0; i < rec.items(); i++) - { - TRecordset_column_info* info = new TRecordset_column_info; - const char* name = rec.fieldname(i); - info->_name << table << '.' << name; - info->_type = rec.type(name); - switch (info->_type) - { - case _datefld: info->_width = 10; break; - case _memofld: info->_width = 50; break; - default : info->_width = rec.length(name); break; - } - _column.add(info); - } -} - -void TCursor_parser::parse_sortexpr(TToken_string& se) -{ - const char sep = se.separator(); - se.separator(' '); - _instr.getline(se.get_buffer(), se.size()); - se.strip_d_spaces(); - se.replace(' ', sep); - se.separator(sep); -} - -void TCursor_parser::parse_filter(TToken_string& filter) -{ - const TString& str = pop(); - while (str.find('=') > 0) - { - filter.add(str); - pop(); - } - push(); -} - -void TCursor_parser::parse_region(TRectype& rec) -{ - TString16 field; - TString value; - while (true) - { - const TString& ass = pop(); - const int equal = ass.find('='); - if (equal > 0) - { - field = ass.left(equal); - value = ass.mid(equal+1); - if (value[0] == '"' || value[0] == '\'') - { - value.rtrim(1); - value.ltrim(1); - } - rec.put(field, value); - } - else - break; - } - push(); -} - - -void TCursor_parser::parse_join_param(TRelation* rel, const TString& j, int to) -{ - int key = 1; - const TString& tok = pop(); - if (tok.starts_with("KE")) - { - pop(); - key = atoi(tok); - } - else - push(); - - int alias = 0; - pop(); - if (tok.starts_with("AL")) - { - pop(); - alias = atoi(tok); - } - else - push(); - - TToken_string exp(80); - pop(); - if (tok == "INTO") - { - parse_filter(exp); - } - if (exp.empty()) - yesnofatal_box("JOIN senza espressioni INTO"); - - const int logicnum = table2logic(j); - if (logicnum != LF_TAB && logicnum != LF_TABCOM) - rel->add(logicnum, exp, key, to, alias); // join file - else - rel->add(j, exp, key, to, alias); // join table - - TString16 tabname; - if (alias > 0) - tabname << alias << '@'; - else - tabname = j; - const TRectype& rec = rel->curr(logicnum); - add_column_info(tabname, rec); -} - -void TCursor_parser::parse_join() -{ - const TString j = pop(); // File or table - - int to = 0; - const TString& tok = pop(); - if (tok == "TO") // TO keyword - { - pop(); - to = table2logic(tok); - } - else - push(); - - parse_join_param(_relation, j, to); -} - -void TCursor_parser::parse_sortedjoin() -{ - TToken_string filter,sortexp; - const TString j = pop(); // File or table - const TString& tok = pop(); - if (tok == "BY" ) - { - parse_sortexpr(sortexp); - } - else - push(); - - pop(); - if (tok.starts_with("FI") || tok.starts_with("SE")) - { - parse_filter(filter); - } - else - push(); - - TRelation* sortrel = new TRelation(table2logic(j)); - while (true) - { - pop(); - if (tok.empty() || tok.starts_with("JO")) - { - push(); - break; - } - - if (tok.starts_with("US")) // USING keyword - { - const TString subj = pop(); // File or table - parse_join_param(sortrel, subj, table2logic(j)); - } - } - - int to = 0; - pop(); - if (tok == "TO") // TO keyword - { - pop(); - to = table2logic(tok); - } - else - push(); - - int key = 1; - pop(); - if (tok.starts_with("KE")) - { - pop(); - key = atoi(tok); - } - else - push(); - - int alias = 0; - pop(); - if (tok.starts_with("AL")) - { - pop(); - alias = atoi(tok); - } - else - push(); - - TToken_string exp(80); - if (pop() == "INTO") - { - pop(); - while (tok.find('=') > 0) - { - exp.add(tok); - pop(); - } - } - push(); - - TSortedfile *sf= new TSortedfile(atoi(j),sortrel,sortexp,filter,key); - _relation->add((TLocalisamfile *)sf, exp, key, to, alias, false); // join table - - TString16 tabname = j; - if (alias > 0) - tabname.cut(0) << alias << '@'; - add_column_info(tabname, sf->curr()); -} - -TCursor_parser::TCursor_parser(istream& instr, TArray& col) - : _instr(instr), _column(col), _relation(NULL), _cursor(NULL) -{ - _column.destroy(); - const TString& tok = pop(); - if (!tok.starts_with("US")) - push(); - - pop(); - if (tok.blank()) - return; - - const int logicnum = table2logic(tok); - const char* tab = NULL; - - if (logicnum != LF_TAB && logicnum != LF_TABCOM) - _relation = new TRelation(logicnum); - else - _relation = new TRelation(tok); - add_column_info(tok, _relation->curr()); - - int key = 1; // key number - pop(); - if (tok.starts_with("KE")) - { - pop(); - key = atoi(tok); - } - else - push(); - - pop(); - if (tok.starts_with("BY")) // "sort BY": user-defined sort - { - TToken_string ordexpr(256); - parse_sortexpr(ordexpr); - _cursor = new TSorted_cursor(_relation, ordexpr,"", key); - } - else - push(); - - pop(); - if (tok.starts_with("FI") || tok.starts_with("SE")) - { - TToken_string filter; - parse_filter(filter); - if (_cursor == NULL) - _cursor = new TCursor(_relation, filter, key); - else - _cursor->setfilter(filter); - } - else - push(); - - if (_cursor == NULL) - _cursor = new TCursor(_relation, "", key); - - TRectype rec_start(_relation->curr()); - TRectype rec_stop(_relation->curr()); - - pop(); - if (tok.starts_with("FR")) - parse_region(rec_start); - else - push(); - pop(); - if (tok.starts_with("TO")) - parse_region(rec_stop); - else - push(); - if (!rec_start.empty() || !rec_stop.empty()) - _cursor->setregion(rec_start, rec_stop, 0x2); - - while (true) - { - pop(); - if (tok.starts_with("JO")) - parse_join(); else - if (tok.starts_with("SO")) - parse_sortedjoin(); - else - break; - } - push(); - - if (_relation->items() == 0) // Non ci sono anche tabelle collegate - { - FOR_EACH_ARRAY_ITEM(_column, i, obj) - { - TRecordset_column_info* info = (TRecordset_column_info*)obj; - const int arrow = info->_name.find('.'); - if (arrow > 0) - info->_name = info->_name.mid(arrow+1); - } - } -} - -/////////////////////////////////////////////////////////// -// TISAM_recordset -/////////////////////////////////////////////////////////// - -TVariant& TISAM_recordset::get_tmp_var() const -{ - static TArray _page; // Variants to be returned by get - static int _next_var = 0; // Index of next variant to be returned - - if (_next_var >= 32) - _next_var = 0; - TVariant* var = (TVariant*)_page.objptr(_next_var); - if (var == NULL) - { - var = new TVariant; - _page.add(var, _next_var); - } - _next_var++; - return *var; -} - -const TVariant& TISAM_recordset::get(int logic, const char* fldname) const -{ - TString80 name = fldname; - TString16 subfield; - int from = 1, to = 0; - - const int open_bracket = name.find('['); - if (open_bracket > 0) - { - sscanf((const char*)name + open_bracket, "[%d,%d]", &from, &to); - name.cut(open_bracket); - } - - const int colon = name.find(':'); - if (colon > 0) - { - subfield = name.mid(colon+1); - name.cut(colon); - } - - const TRectype& rec = _relation->curr(logic); - const TFieldtypes ft = rec.type(name); - - if (ft == _nullfld) - return NULL_VARIANT; - - TVariant& var = get_tmp_var(); - switch (ft) - { - case _datefld: var.set(rec.get_date(name)); break; - case _realfld: var.set(rec.get_real(name)); break; - case _intfld : - case _longfld: - case _wordfld: var.set(rec.get_long(name)); break; - default : var.set(rec.get(name)); break; - } - - if (subfield.not_empty()) - { - subfield << '='; - const TString& str = var.as_string(); - int s = str.find(subfield); - if (s == 0 || (s > 0 && str[s-1] < ' ')) - { - s += subfield.len(); - const int e = str.find('\n', s); - var.set(str.sub(s, e)); - } - } - - if (to >= from) - var.set(var.as_string().sub(from-1, to)); - - return var; -} - -const TVariant& TISAM_recordset::get(size_t c) const -{ - const TRecordset_column_info* info = (const TRecordset_column_info*)_column.objptr(c); - if (info != NULL) - { - int logic = 0; - const char* field = info->_name; - const int dot = info->_name.find('.'); - if (dot > 0) - { - logic = table2logic(info->_name.left(dot)); - field += dot+1; - } - return get(logic, field); - } - return NULL_VARIANT; -} - -const TVariant& TISAM_recordset::get(const char* name) const -{ - const TFixed_string fldname(name); - - int table_end = fldname.find('.'); - int field_start = table_end+1; - if (table_end < 0) - { - table_end = fldname.find('-'); - if (table_end > 0) - field_start = table_end+2; - } - int logic = 0; - const char* field = name; - if (table_end > 0) - { - logic = table2logic(fldname.left(table_end)); - field += field_start; - } - return get(logic, field); -} - -const TRecordset_column_info& TISAM_recordset::column_info(size_t i) const -{ - return (const TRecordset_column_info&)_column[i]; -} - -TRecnotype TISAM_recordset::current_row() const -{ - return _cursor != NULL ? _cursor->pos() : -1; -} - -bool TISAM_recordset::ask_variables(bool all) -{ - bool ok = TRecordset::ask_variables(all); - if (ok) - reset(); - return ok; -} - -TRecnotype TISAM_recordset::items() const -{ - if (_cursor == NULL) - { - TString use; parsed_text(use); - TProfiler prof("ISAM query"); - TISAM_recordset* my = (TISAM_recordset*)this; - istrstream instr(use.get_buffer(), use.len()); - TCursor_parser parser(instr, my->_column); - - my->_relation = parser.get_relation(); - my->_cursor = parser.get_cursor(); - - if (_cursor != NULL) - { - _cursor->items(); - _cursor->freeze(); - } - } - - return _cursor != NULL ? _cursor->items() : 0; -} - -unsigned int TISAM_recordset::columns() const -{ - if (_cursor == NULL) - items(); - return _column.items(); -} - - -bool TISAM_recordset::move_to(TRecnotype pos) -{ - bool ok = _cursor != NULL; - if (ok) - { - *_cursor = pos; - ok = pos >= 0 && pos < items(); - } - return ok; -} - -void TISAM_recordset::reset() -{ - _column.destroy(); - if (_relation != NULL) - { - delete _relation; - _relation = NULL; - } - if (_cursor != NULL) - { - delete _cursor; - _cursor = NULL; - } -} - -void TISAM_recordset::set(const char* use) -{ - reset(); - _use = use; - find_and_reset_vars(); -} - -TISAM_recordset::TISAM_recordset(const char* use) - : _relation(NULL), _cursor(NULL) -{ - set(use); -} - -TISAM_recordset::~TISAM_recordset() -{ - reset(); -} - -/////////////////////////////////////////////////////////// -// TRecordset_sheet -/////////////////////////////////////////////////////////// - -void TRecordset_sheet::get_row(long r, TToken_string& row) -{ - row.separator('\t'); - row.cut(0); - if (_query.move_to(r)) - { - TString str; - for (unsigned int c = 0; c < _query.columns(); c++) - { - _query.get(c).as_string(str); - row.add(str); - } - } -} - -long TRecordset_sheet::get_items() const -{ - return _query.items(); -} - -TRecordset_sheet::TRecordset_sheet(TRecordset& query) - : TSheet(-1, -1, -2, -4, "Query", query.sheet_head()), _query(query) -{ -} - -/////////////////////////////////////////////////////////// -// TProfiler -/////////////////////////////////////////////////////////// - -TProfiler::TProfiler(const char* desc) - : _desc(desc) -{ -#ifdef DBG - _start = clock(); - - TString80 msg; - msg << "Profiling " << desc << "..."; - statbar_set_title(TASK_WIN, msg); - - while (true) - { - const clock_t clk = clock(); - if (clk != _start) - { - _start = clk; - break; - } - } -#endif -} - -void TProfiler::show() const -{ -#ifdef DBG - const double s = double(clock() - _start) / CLOCKS_PER_SEC; - - int hour = 0, min = 0; - int sec = int(s); - const int cent = int((s - sec)*100); - - if (sec >= 3600) - { - hour = sec / 3600; - sec -= hour * 3600; - } - if (sec >= 60) - { - min = sec / 60; - sec -= min * 60; - } - - TString80 msg = _desc; - msg.format("%s %02d:%02d:%02d.%02d", (const char*)_desc, hour, min, sec, cent); - statbar_set_title(TASK_WIN, msg); -#endif -} - -TProfiler::~TProfiler() -{ - show(); -} diff --git a/ba/ba8201.h b/ba/ba8201.h deleted file mode 100755 index c53f364ff..000000000 --- a/ba/ba8201.h +++ /dev/null @@ -1,238 +0,0 @@ -#ifndef __RECORDSET_H -#define __RECORDSET_H - -#ifndef __ASSOC_H -#include -#endif - -#ifndef __RECTYPES_H -#include -#endif - -#ifndef __SHEET_H -#include -#endif - -struct TRecordset_column_info : public TObject -{ - TString _name; // Table.Column - int _width; - TFieldtypes _type; -}; - -/////////////////////////////////////////////////////////// -// TVariant -/////////////////////////////////////////////////////////// - -class TVariant : public TSortable -{ - TFieldtypes _type; - void* _ptr; - -protected: - virtual TObject* dup() const { return new TVariant(*this); } - void copy(const TVariant& var); - -public: - TFieldtypes type() const { return _type; } // Internal use only - bool is_string() const { return _type == _alfafld; } - bool is_null() const { return _type == _nullfld; } - bool is_zero() const; - void set_null(); - - void set(const char* str); - void set(const real& r); - void set(const long n); - void set(const TDate& d); - - TVariant& operator=(const TVariant& var) { copy(var); return *this; } - TVariant& operator=(const char* str) { set(str); return *this; } - TVariant& operator=(const real& r) { set(r); return *this; } - TVariant& operator=(const long n) { set(n); return *this; } - TVariant& operator=(const TDate& d) { set(d); return *this; } - - const TString& as_string() const; - bool as_string(TString& str) const; - real as_real() const; - long as_int() const; - TDate as_date() const; - bool as_bool() const; - COLOR as_color() const; - - void convert_to(TFieldtypes ft); - - virtual int compare(const TSortable& s) const; - TVariant& add(const TVariant& var); - TVariant& sub(const TVariant& var); - - TVariant() : _type(_nullfld), _ptr(NULL) { } - TVariant(const char* str) : _type(_alfafld), _ptr(new TString(str)) { } - TVariant(const real& num) : _type(_realfld), _ptr(new real(num)) { }; - TVariant(const TDate& d) : _type(_datefld), _ptr(new TDate(d)) { }; - TVariant(long num) : _type(_longfld), _ptr((void*)num) { }; - TVariant(bool ok) : _type(_longfld), _ptr((void*)ok) { }; - TVariant(const TVariant& var) : _type(_nullfld), _ptr(NULL) { copy(var); } - virtual ~TVariant() { set_null(); } -}; - -extern const TVariant NULL_VARIANT; - -/////////////////////////////////////////////////////////// -// TRecordset -/////////////////////////////////////////////////////////// - -enum TRecordsetExportFormat { fmt_unknown, fmt_html, fmt_text, fmt_silk, fmt_campo }; - -class TRecordset : public TObject -{ - TAssoc_array _var; - TString_array _varnames; - -protected: - bool save_as_html(const char* path); - bool save_as_silk(const char* path); - bool save_as_text(const char* path); - bool save_as_campo(const char* path); - - void find_and_reset_vars(); - void parsed_text(TString& sql) const; - -public: // Absolutely needed methods - virtual TRecnotype items() const pure; - virtual bool move_to(TRecnotype pos) pure; - virtual TRecnotype current_row() const pure; - - virtual bool move_first() { return move_to(0); } - virtual bool move_prev() { return move_to(current_row()-1); } - virtual bool move_next() { return move_to(current_row()+1); } - virtual bool move_last() { return move_to(items()-1); } - virtual bool bof() const { return current_row() <= 0; } - virtual bool eof() const { return current_row() >= items(); } - - virtual unsigned int columns() const pure; - virtual const TRecordset_column_info& column_info(unsigned int column) const pure; - virtual const TVariant& get(unsigned int column) const pure; - - virtual const TString_array& variables() const { return _varnames; } - virtual const TVariant& get_var(const char* name) const; - virtual bool set_var(const char* name, const TVariant& var, bool create = false); - virtual bool ask_variables(bool all); - - virtual const TString& query_text() const; - virtual int find_column(const char* column_name) const; - virtual const TVariant& get(const char* column_name) const; - virtual const TToken_string& sheet_head() const; - - virtual bool save_as(const char* path, TRecordsetExportFormat fmt = fmt_unknown); -}; - -/////////////////////////////////////////////////////////// -// TSQL_recordset -/////////////////////////////////////////////////////////// - -class TSQL_recordset : public TRecordset -{ - TString _sql; - - TRecnotype _first_row, _pagesize, _items, _current_row; - TArray _column; - TArray _page; - -protected: - void reset(); - void parsed_sql_text(TString& sql) const; - -public: // TRecordset - virtual TRecnotype items() const; - virtual bool move_to(TRecnotype pos); - virtual TRecnotype current_row() const { return _current_row; } - virtual unsigned int columns() const; - virtual const TRecordset_column_info& column_info(unsigned int c) const; - virtual const TVariant& get(unsigned int column) const; - virtual bool ask_variables(bool all); - const TString& query_text() const { return _sql; } - -public: - void set(const char* sql); - - // Internal use only - virtual int on_get_items(int argc, char** values, char** columns); - virtual int on_get_rows(int argc, char** values, char** columns); - const TArray* row(TRecnotype n); - - TSQL_recordset(const char* sql); - virtual ~TSQL_recordset() { } -}; - -/////////////////////////////////////////////////////////// -// TISAM_recordset -/////////////////////////////////////////////////////////// - -class TISAM_recordset : public TRecordset -{ - TString _use; - - TRelation* _relation; - TCursor* _cursor; - TArray _column; // Column infos - -protected: - void reset(); - TVariant& get_tmp_var() const; - const TVariant& get(int logic, const char* field) const; - -public: - void set(const char* use); - virtual TRecnotype items() const; - virtual bool move_to(TRecnotype pos); - virtual TRecnotype current_row() const; - virtual unsigned int columns() const; - virtual const TRecordset_column_info& column_info(unsigned int c) const; - virtual const TVariant& get(unsigned int column) const; - virtual const TVariant& get(const char* column_name) const; - virtual bool ask_variables(bool all); - virtual const TString& query_text() const { return _use; } - - - TISAM_recordset(const char* use); - virtual ~TISAM_recordset(); -}; - -/////////////////////////////////////////////////////////// -// TRecordset_sheet -/////////////////////////////////////////////////////////// - -class TRecordset_sheet : public TSheet -{ - TRecordset& _query; - -protected: - virtual void get_row(long r, TToken_string& row); - virtual long get_items() const; - -public: - TRecordset_sheet(TRecordset& sql); -}; - -/////////////////////////////////////////////////////////// -// Utility -/////////////////////////////////////////////////////////// - -class TProfiler : public TObject -{ - TString _desc; - clock_t _start; - -public: - void show() const; - - TProfiler(const char* desc = ""); - ~TProfiler(); -}; - -bool select_custom_file(TFilename& path, const char* ext); -const TString& logic2table(int logic_num); -int table2logic(const TString& name); - -#endif - diff --git a/ba/ba8300.cpp b/ba/ba8300.cpp index 0dfa6fadc..6defbae6a 100755 --- a/ba/ba8300.cpp +++ b/ba/ba8300.cpp @@ -7,11 +7,10 @@ #include #include #include +#include -#include "ba8201.h" #include "ba8300.h" #include "ba8301.h" -#include "ba8303.h" #include /////////////////////////////////////////////////////////// diff --git a/ba/ba8300m.uml b/ba/ba8300m.uml new file mode 100755 index 000000000..f67f218bd --- /dev/null +++ b/ba/ba8300m.uml @@ -0,0 +1,49 @@ +PAGE "Monitor" -1 -1 50 20 + +LIST 101 24 -3 +BEGIN + PROMPT 0 0 "" +END + +STACK 102 -3 10 +BEGIN + PROMPT 27 0 "" +END + +STACK 103 -3 -3 +BEGIN + PROMPT 27 11 "" +END + +BUTTON DLG_NEXTREC 9 2 +BEGIN + PROMPT -14 -1 "" + PICTURE 124 + MESSAGE EXIT,K_F11 +END + +BUTTON DLG_LASTREC 9 2 +BEGIN + PROMPT -24 -1 "" + PICTURE 1671 + MESSAGE EXIT,K_F10 +END + +BUTTON DLG_ELABORA 9 2 +BEGIN + PROMPT -34 -1 "" + PICTURE BMP_LASTREC + MESSAGE EXIT,K_F5 +END + +BUTTON DLG_QUIT 9 2 +BEGIN + PROMPT -44 -1 "" + MESSAGE EXIT,K_QUIT +END + + +ENDPAGE + +ENDMASK + diff --git a/ba/ba8301.h b/ba/ba8301.h index 5db171696..fe8ca78c4 100755 --- a/ba/ba8301.h +++ b/ba/ba8301.h @@ -7,7 +7,7 @@ #endif #ifndef __REPORT_H -#include "ba8302.h" +#include #endif /////////////////////////////////////////////////////////// diff --git a/ba/ba8302.cpp b/ba/ba8302.cpp deleted file mode 100755 index 726df180c..000000000 --- a/ba/ba8302.cpp +++ /dev/null @@ -1,2265 +0,0 @@ -#include -#include -#include -#include -#include - -#include "ba8201.h" -#include "ba8301.h" - -/////////////////////////////////////////////////////////// -// TReport_font -/////////////////////////////////////////////////////////// - -XVT_FNTID TReport_font::get_xvt_font(const TWindow& win) const -{ - if (win.win() != _win_mapped) - { - int nSize = _size; - - if (win.win() != 883) // Non e' una stampa! - { - const int cpi = 120 / DEFAULT_FONT_SIZE; - const PNT pnt0 = win.log2dev(0,0); - const PNT pnt1 = win.log2dev(cpi*100,100); - const int ppi = pnt1.h - pnt0.h; - const TString emme(cpi, 'M'); - - int mi = 0, me = 0, ma = 2*(pnt1.v - pnt0.v); - int best = 0, best_error = 0; - while (mi <= ma) - { - me = (mi+ma)/2; - - XVT_FNTID fontid = xvt_font_create(); - xvt_font_set_family(fontid, "Courier New"); - xvt_font_set_size(fontid, me); - xvt_dwin_set_font(win.win(), fontid); - const int width = xvt_dwin_get_text_width(win.win(), emme, -1); - const int error = abs(width - ppi); - xvt_font_destroy(fontid); - if (best == 0 || error < best_error) - { - best = me; - best_error = error; - if (error == 0) - break; - } - if (width > ppi) - ma = me-1; - else - mi = me+1; - } - nSize = cpi * best / _cpi; - } - - XVT_FNTID fontid = xvt_font_create(); - xvt_font_set_family(fontid, (char*)(const char*)_name); - xvt_font_set_size(fontid, nSize); - xvt_font_set_style(fontid, _style); - - TReport_font& myself = *(TReport_font*)this; - myself.unmap(); - myself._fontid = fontid; - myself._win_mapped = win.win(); - xvt_dwin_get_font_metrics(_win_mapped, &myself._leading, &myself._ascent, &myself._descent); - } - return _fontid; -} - -void TReport_font::unmap() -{ - if (_fontid != NULL) - { - xvt_font_destroy(_fontid); - _fontid = NULL; - } - _win_mapped = NULL_WIN; -} - -void TReport_font::create(const char* name, int size, XVT_FONT_STYLE_MASK style) -{ - _name = name; - _size = size; - _style = style; - _cpi = 120 / _size; - unmap(); -} - -void TReport_font::copy(const TReport_font& font) -{ - create(font.name(), font.size(), font.style()); -} - -int TReport_font::compare(const TSortable& s) const -{ - const TReport_font& f = (const TReport_font&)s; - int cmp = _name.compare(f.name(), -1, true); - if (cmp == 0) - { - cmp = _size - f.size(); - if (cmp == 0) - cmp = _style - f.style(); - } - return cmp; -} - -void TReport_font::save(TXmlItem& item) const -{ - TXmlItem& font = item.AddChild("font"); - font.SetAttr("face", _name); - font.SetAttr("size", _size); - if (_style & XVT_FS_BOLD) - font.SetAttr("bold", "1"); - if (_style & XVT_FS_ITALIC) - font.SetAttr("italic", "1"); - if (_style & XVT_FS_UNDERLINE) - font.SetAttr("underline", "1"); -} - -bool TReport_font::load(const TXmlItem& item) -{ - const TXmlItem* font = item.FindFirstChild("font"); - if (font != NULL) - { - const TString& name = font->GetAttr("face"); - const int size = font->GetIntAttr("size", 10); - XVT_FONT_STYLE_MASK style = 0; - if (font->GetIntAttr("bold")) - style |= XVT_FS_BOLD; - if (font->GetIntAttr("italic")) - style |= XVT_FS_ITALIC; - if (font->GetIntAttr("underline")) - style |= XVT_FS_UNDERLINE; - create(name, size, style); - } - return font != NULL; -} - -TReport_font::TReport_font() : _fontid(NULL), _win_mapped(NULL_WIN) -{ - create("Courier New", DEFAULT_FONT_SIZE, XVT_FS_NONE); -} - -TReport_font::TReport_font(const TReport_font& f) : _fontid(NULL), _win_mapped(NULL_WIN) -{ copy(f); } - -TReport_font::~TReport_font() -{ - unmap(); -} - -/////////////////////////////////////////////////////////// -// TReport_expr -/////////////////////////////////////////////////////////// - -class TReport_expr : public TExpression -{ - TReport& _report; - TVariant _var; - -protected: - virtual int parse_user_func(const char* name, int nparms) const; - virtual void evaluate_user_func(int index, int nparms, TEval_stack& stack, TTypeexp type) const; - bool is_numeric(const char* str) const; - -public: - TReport_expr(TReport& rep, const char* exp); - const TVariant& as_variant(TFieldtypes ft); -}; - -int TReport_expr::parse_user_func(const char* name, int nparms) const -{ - return -1; -} - -void TReport_expr::evaluate_user_func(int index, int nparms, TEval_stack& stack, TTypeexp type) const -{ -} - -bool TReport_expr::is_numeric(const char* str) const -{ - if (str == NULL || *str == '\0' || *str == '0') - return false; // Se comincia per zero va preservato! - if (*str == '-') - { - str++; - if (*str <= ' ') - return false; - } - while (*str) - { - if (strchr("0123456789.", *str) == NULL) - return false; - str++; - } - return true; -} - -const TVariant& TReport_expr::as_variant(TFieldtypes ft) -{ - set_type(ft == _alfafld || ft == _nullfld ? _strexpr : _numexpr); - const TString& str = as_string(); - switch (ft) - { - case _datefld: _var.set(TDate(str)); break; - case _longfld: _var.set(atol(str)); break; - case _realfld: _var.set(real(str)); break; - default : _var.set(str); break; - }; - return _var; -} - -TReport_expr::TReport_expr(TReport& rep, const char* exp) - : _report(rep) -{ - set(exp, _strexpr); -} - - -TObject* TReport_expr_cache::key2obj(const char* key) -{ - return new TReport_expr(*_report, key); -} - -TReport_expr& TReport_expr_cache::operator[](const char* key) -{ return *(TReport_expr*)objptr(key); } - - -TObject* TReport_image_cache::key2obj(const char* key) -{ - TImage* img = NULL; - - TFilename pathname = key; - if (pathname.custom_path()) - img = new TImage(pathname); - - return img; -} - -TImage* TReport_image_cache::image(const TString& key) -{ - return (TImage*)objptr(key); -} - -TReport_image_cache::TReport_image_cache() : TCache(7) -{ -} - -/////////////////////////////////////////////////////////// -// Utility -/////////////////////////////////////////////////////////// - -void advanced_draw_rect(TWindow& win, const RCT& r, int border, COLOR fore, COLOR back) -{ - const bool has_pen = border > 0; - const bool has_brush = color_distance(back, COLOR_WHITE) != 0; - if (has_pen || has_brush) - { - if (has_pen) - win.set_pen(fore, border, PAT_SOLID); - else - win.hide_pen(); - if (has_brush) - win.set_brush(back, PAT_SOLID); - else - win.hide_brush(); - xvt_dwin_draw_rect(win.win(), (RCT*)&r); - } -} - -void advanced_draw_justified_text(TWindow& win, const char* text, short x, short y, short dx) -{ - TString txt(text); txt.rtrim(); - int spaces = 0; - for (int s = 0; txt[s]; s++) - if (isspace(txt[s])) spaces++; - const int tw = xvt_dwin_get_text_width(win.win(), txt, -1); - if (tw < dx && spaces > 0) - { - txt << ' '; // Aggiunge spazio finale - const double kspc = double(dx - tw) / spaces; - int start = 0; - double kx = x; - for (int i = 0; txt[i]; i++) - { - if (isspace(txt[i])) - { - const bool last_word = txt[i+1] == '\0'; - const TString& parola = txt.sub(start, i + (last_word ? 0 : 1)); - const int lw = xvt_dwin_get_text_width(win.win(), parola, -1); - if (last_word) // ultima parola - kx = x+dx-lw; - xvt_dwin_draw_text(win.win(), int(kx+0.5), y, parola, -1); - kx += lw + kspc; - start = i+1; - } - } - } - else - xvt_dwin_draw_text(win.win(), x, y, text, -1); -} - -void advanced_draw_text(TWindow& win, const char* text, const RCT& r, - char halign, char valign) -{ - const short dx = r.right-r.left; - const short dy = r.bottom-r.top; - short x = r.left; - short y = r.bottom; - - if (halign != 'L') - { - const int tw = xvt_dwin_get_text_width(win.win(), text, -1); - switch (halign) - { - case 'C': x += (dx - tw)/2; break; - case 'R': x = r.right-tw; break; - default : break; - } - } - - // Text Height - int leading, ascent, descent; - xvt_dwin_get_font_metrics(win.win(), &leading, &ascent, &descent); - switch (valign) - { - case 'C': y -= (dy - ascent)/2; break; - case 'T': y = r.top + leading + ascent; break; - default : y -= descent; break; - } - - if (halign == 'J') - advanced_draw_justified_text(win, text, x, y, dx); - else - xvt_dwin_draw_text(win.win(), x, y, text, -1); -} - -static void set_num_attr(TXmlItem& item, const char* attr, long num, short def = 0) -{ - if (num != def) - { - const real n = num / CENTO; - item.SetAttr(attr, n.string()); - } -} - -static void set_col_attr(TXmlItem& item, const char* attr, COLOR col, COLOR def = COLOR_BLACK) -{ - if (color_distance(col, def) != 0) - { - TString16 str; - str.format("#%06X", col & 0xFFFFFF); - item.SetAttr(attr, str); - } -} - -static short get_num_attr(const TXmlItem& item, const char* attr, short def = 0) -{ - const TString& str = item.GetAttr(attr); - if (str.not_empty()) - { - real n = str; n *=CENTO ; - def = (short)n.integer(); - } - return def; -} - -static COLOR get_col_attr(const TXmlItem& item, const char* attr, COLOR col) -{ - const TString& str = item.GetAttr(attr); - if (str[0] == '#') - sscanf(str, "#%X", &col); - return col; -} - -static char get_chr_attr(const TXmlItem& item, const char* attr, char c) -{ - const TString& str = item.GetAttr(attr); - if (str[0] > ' ') - c = toupper(str[0]); - return c; -} - -/////////////////////////////////////////////////////////// -// TReport_section -/////////////////////////////////////////////////////////// - -TReport_section* TReport_section::father_section() const -{ - if (level() <= 0) - { - if (type() != 'B') - return _report.find_section('B', 0); - } - else - return _report.find_section('B', type() == 'B' ? 0 : 1); - return NULL; -} - -const TReport_font& TReport_section::font() const -{ - const TReport_font* f = _font; - if (f == NULL) - { - TReport_section* father = father_section(); - if (father == NULL) - f = &_report.font(); - else - f = &father->font(); - } - return *f; -} - -void TReport_section::set_font(const TReport_font& f) -{ - if (_font != NULL) - { - delete _font; - _font = NULL; - } - if (font() != f) - _font = new TReport_font(f); -} - -const TString& TReport_section::prescript() const -{ return _prescript.get(); } - -void TReport_section::set_prescript(const char* src) -{ - _prescript.set(src); - TString desc; desc << type() << level() << " PRESCRIPT"; - _prescript.set_description(desc); -} - -const TString& TReport_section::postscript() const -{ return _postscript.get(); } - -void TReport_section::set_postscript(const char* src) -{ - _postscript.set(src); - TString desc; desc << type() << level() << " POSTSCRIPT"; - _postscript.set_description(desc); -} - -void TReport_section::unmap_font() -{ - if (_font != NULL) - _font->unmap(); - for (int i = last(); i >= 0; i--) - field(i).unmap_font(); -} - -int TReport_section::add(TObject* obj) -{ - TReport_field* rf = (TReport_field*)obj; - rf->set_section(this); - return TArray::add(obj); -} - -int TReport_section::add(TObject& obj) -{ - TReport_field& rf = (TReport_field&)obj; - rf.set_section(this); - return TArray::add(obj); -} - -int TReport_section::find_field_pos(int id) -{ - for (int i = items()-1; i >= 0; i--) - { - if (field(i).id() == id) - break; - } - return i; -} - -TReport_field* TReport_section::find_field(int id) -{ - const int pos = find_field_pos(id); - if (pos >= 0) - return &field(pos); - return NULL; -} - -TPoint TReport_section::compute_size() const -{ - if (hidden()) - return TPoint(0,0); - - TPoint s = _size; - if (_size.x <= 0 || _size.y <= 0) // Calcolo automatico necessario - { - for (int i = 0; i < items(); i++) - { - const TReport_field& rf = field(i); - if (rf.shown()) - { - const TRectangle r = rf.get_draw_rect(); - if (_size.x <= 0 && r.right() > s.x) // Richiesto calcolo larghezza - s.x = r.right(); - if (_size.y <= 0 && r.bottom() > s.y) // Richiesto calcolo altezza - s.y = r.bottom(); - } - } - if ((s.x % 100) != 0) // Arrotonda alla colonna successiva - s.x = (s.x / 100 + 1) * 100; - if ((s.y % 100) != 0) // Arrotonda alla riga successiva - s.y = (s.y / 100 + 1) * 100; - } - return s; -} - -bool TReport_section::compute_rect(TRectangle& rct) const -{ - rct.set(TPoint(0, 0), compute_size()); - return !rct.is_empty(); -} - -void TReport_section::draw(TWindow& win, TReport_draw_mode rdm) const -{ - if (shown() || rdm == rdm_edit) - { - for (int i = 0; i < items(); i++) - { - const TReport_field& f = field(i); - f.draw(win, rdm); - } - } -} - -bool TReport_section::load_fields() -{ - const bool ok = active() || shown(); - if (ok) - { - for (int i = 0; i < items(); i++) - { - TReport_field& f = field(i); - f.load_field(); - } - } - return ok; -} - -bool TReport_section::execute_prescript() -{ - bool ok = true; - 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++) - { - TReport_field& f = field(i); - f.execute_prescript(); - } - return ok; -} - -bool TReport_section::execute_postscript() -{ - bool ok = true; - for (int i = 0; i < items(); i++) - { - TReport_field& f = field(i); - f.execute_postscript(); - } - if (active()) - { - TString80 str; - ok = _postscript.execute(report(), str); - } - return ok; -} - -void TReport_section::save(TXmlItem& root) const -{ - TXmlItem& item = root.AddChild("section"); - char* tipo = NULL; - switch (type()) - { - case 'H': tipo = "Head"; break; - case 'F': tipo = "Foot"; break; - default : tipo = "Body"; break; - } - item.SetAttr("type", tipo); - item.SetAttr("level", level()); - set_num_attr(item, "x", pos().x); - set_num_attr(item, "y", pos().y); - set_num_attr(item, "width", width()); - set_num_attr(item, "height", height()); - item.SetAttr("hidden", _hidden); - item.SetAttr("deactivated", _deactivated); - item.SetAttr("hidden_if_needed", hidden_if_needed()); - item.SetAttr("pagebreak", _page_break); - item.SetAttr("keep_with_next", keep_with_next()); - if (grouped_by().not_empty()) - item.AddChild("groupby") << grouped_by(); - if (has_font()) - font().save(item); - _prescript.save(item, "prescript"); - _postscript.save(item, "postscript"); - - for (int i = 0; i < items(); i++) - { - const TReport_field& rf = field(i); - rf.save(item); - } -} - -void TReport_section::load(const TXmlItem& sec) -{ - _pos.x = get_num_attr(sec, "x"); - _pos.y = get_num_attr(sec, "y"); - set_width(get_num_attr(sec, "width")); - set_height(get_num_attr(sec, "height")); - force_page_break(sec.GetBoolAttr("pagebreak")); - keep_with_next(sec.GetBoolAttr("keep_with_next")); - hide_if_needed(sec.GetBoolAttr("hidden_if_needed")); - show(!sec.GetBoolAttr("hidden")); - activate(!sec.GetBoolAttr("deactivated")); - - TReport_font font; - if (font.load(sec)) - set_font(font); - - if (level() > 1) - { - const TXmlItem* gb = sec.FindFirstChild("groupby"); - if (gb != NULL) - { - TString str; - gb->GetEnclosedText(str); - group_by(str); - } - } - - for (int j = 0; j < sec.GetChildren(); j++) - { - const TXmlItem& fld = *sec.GetChild(j); - if (fld.GetTag() == "field") - { - TReport_field* rf = new TReport_field(this); - if (rf->load(fld)) - add(rf); - else - delete rf; - } - } - - _prescript.load(sec, "prescript"); - _postscript.load(sec, "postscript"); -} - -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), - _hidden(false), _deactivated(false) -{ } - -TReport_section::~TReport_section() -{ - if (_font) - delete _font; -} - -/////////////////////////////////////////////////////////// -// TReport_script -/////////////////////////////////////////////////////////// - -TString& TReport_script::translate_message(TReport& rep) const -{ - TToken_string source(_src, '\n'); - TToken_string line(256, '|'); - TToken_string args(256, ','); - TString cmd; - TString alex, empty_alex; - 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(); - } - FOR_EACH_TOKEN(line, tok) - { - const TFixed_string msg(tok); - const int comma = msg.find(','); - if (comma > 0) - { - cmd << msg.left(comma); - args = msg.mid(comma+1); - if (args[0] != '#') // Controlla se c'e' bisogno di un # all'inizio - { - char type; - int level, id; - if (rep.parse_field(args.get(0), type, level, id) >= 2) - args.insert("#"); - } - } - else - { - cmd << msg; - args.cut(0); - } - - if (cmd[0] != '_') - cmd.insert("_"); - cmd.insert("MESSAGE"); - if (rep.defined(cmd)) - { - TString& alx = msg_empty ? empty_alex : alex; - alx << args << ' ' << cmd << ' '; - } - else - { - cmd << " ?"; - error_box(cmd); - } - } - } - TString& src = get_tmp_string(); - if (!empty_alex.blank()) - { - src = "#THIS @ IF\n"; - src << alex; - src << "\nELSE\n"; - src << empty_alex; - src << "\nTHEN"; - } - else - src = alex; - - return src; -} - - -void TReport_script::set(const char* source) -{ - if (_src != source) - { - destroy(); - _src = source; - } -} - -void TReport_script::copy(const TReport_script& rs) -{ - set(rs.get()); -} - -bool TReport_script::compile(TReport& rep) -{ - if (_bc == NULL) - _bc = new TBytecode; - - bool good = true; - if (_src.starts_with("MESSAGE ")) - good = rep.compile(translate_message(rep), *_bc); - else - good = rep.compile(_src, *_bc); - _bc->set_name(_desc); - - return good; -} - -bool TReport_script::execute(TReport& rep, TString& output) -{ - bool good = true; - if (ok()) - { - if (_bc == NULL) - good = compile(rep); - if (good) - good = rep.execute(*_bc, output); - } - return good; -} - -bool TReport_script::execute(TReport_field& rf) -{ - bool good = true; - if (ok()) - { - TString str; - TReport& rep = rf.section().report(); - rep.set_curr_field(&rf); - good = execute(rep, str); - } - return good; -} - -void TReport_script::destroy() -{ - if (_bc != NULL) - { - delete _bc; - _bc = NULL; - } - _src.cut(0); -} - -void TReport_script::save(TXmlItem& root, const char* tag) const -{ - if (ok()) - { - TXmlItem& script = root.AddChild(tag); - script.SetAttr("description", _desc); - script << _src; - } -} - -bool TReport_script::load(const TXmlItem& root, const char* tag) -{ - destroy(); - TXmlItem* script = root.FindFirstChild(tag); - if (script != NULL) - { - _desc = script->GetAttr("description"); - script->GetEnclosedText(_src); - } - return ok(); -} - -TReport_script::TReport_script() : _bc(NULL) -{ } - -TReport_script::~TReport_script() -{ destroy(); } - -/////////////////////////////////////////////////////////// -// TReport_field -/////////////////////////////////////////////////////////// - -void TReport_field::set_pos(long x, long y) -{ - _rct.x = x; - _rct.y = y; -} - -void TReport_field::set_size(long w, long h) -{ - _rct.set_width(w); - _rct.set_height(h); -} - -void TReport_field::offset(const TPoint& pt) -{ - _rct.x += pt.x; - _rct.y += pt.y; -} - -void TReport_field::set_draw_pos(long x, long y) -{ - _rct_draw.x = x; - _rct_draw.y = y; -} - -void TReport_field::set_draw_size(long w, long h) -{ - _rct_draw.set_width(w); - _rct_draw.set_height(h); -} - -void TReport_field::compute_draw_rect() const -{ - TRectangle& rct = ((TReport_field*)this)->_rct_draw; - rct = get_rect(); - if (type() == 'S') - { - if (rct.width() <= 0) - { - TString text = formatted_text(); text.rtrim(); - TToken_string str(text, '\n'); - int maxlen = 1; - FOR_EACH_TOKEN(str, line) - { - const int len = strlen(line); - if (len > maxlen) - maxlen = len; - } - rct.set_width(maxlen * 100); - } - if (rct.height() <= 0) - { - if (rct.width() >= 100) - { - TString text = formatted_text(); text.rtrim(); - TParagraph_string str(text, rct.width()/100); - rct.set_height(str.items() * 100); - } - if (rct.height() <= 0) - rct.set_height(100); - } - } -} - -const TReport_font& TReport_field::font() const -{ - return _font != NULL ? *_font : _section->font(); -} - -void TReport_field::set_font(const TReport_font& f) -{ - if (_font != NULL) - { - delete _font; - _font = NULL; - } - if (f != font()) - _font = new TReport_font(f); -} - -void TReport_field::unmap_font() -{ - if (_font != NULL) - _font->unmap(); -} - -const TString& TReport_field::prescript() const -{ return _prescript.get(); } - -void TReport_field::set_prescript(const char* src) -{ - TString desc; desc << section().type() << section().level() << '.' << id() << " PRESCRIPT"; - _prescript.set_description(desc); - _prescript.set(src); -} - -const TString& TReport_field::postscript() const -{ return _postscript.get(); } - -void TReport_field::set_postscript(const char* src) -{ - TString desc; desc << section().type() << section().level() << '.' << id() << " POSTSCRIPT"; - _postscript.set_description(desc); - _postscript.set(src); -} - -void TReport_field::copy(const TReport_field& rf) -{ - _section = rf._section; - _id = rf.id(); - _type = rf.type(); - _rct = rf._rct; - _fgcolor = rf._fgcolor; _bgcolor = rf._bgcolor; - _border = rf._border; - _halign = rf._halign; _valign = rf._valign; - _picture = rf._picture; _field = rf._field; - _hidden = rf.hidden(); - _deactivated = rf.deactivated(); - _hide_zeroes = rf._hide_zeroes; - _selected = false; - _prescript = rf._prescript; - _postscript = rf._postscript; - _list = rf._list; - - set_font(rf.font()); -} - -const char* TReport_field::type_name() const -{ - const char* n = NULL; - switch (_type) - { - case 'A': n = "Array"; break; - case 'D': n = "Data"; break; - case 'E': n = "Ellisse"; break; - case 'I': n = "Immagine"; break; - case 'L': n = "Linea"; break; - case 'N': n = "Numero"; break; - case 'P': n = "Prezzo"; break; - case 'R': n = "Rettangolo"; break; - case 'S': n = "Stringa"; break; - case 'T': n = "Testo"; break; - case 'V': n = "Valuta"; break; - default : break; - } - return n; -} - -TFieldtypes TReport_field::var_type() const -{ - TFieldtypes ft = _nullfld; - switch (_type) - { - case 'D': ft = _datefld; break; - case 'P': // Prezzo - case 'V': // Valuta - case 'N': ft = _realfld; break; - case 'I': - case 'A': - case 'S': ft = _alfafld; break; - default : ft = _nullfld; break; - } - return ft; -} - -void TReport_field::set(const char* str) -{ - _var = str; - _var.convert_to(var_type()); -} - -void TReport_field::set(const TVariant& var) -{ - _var = var; - _var.convert_to(var_type()); -} - -bool TReport_field::load_field() -{ - const bool ok = !_field.blank(); - if (ok) - { - const TFieldtypes ft = var_type(); - if (ft != _nullfld) - { - if (_field.starts_with("SELECT ")) - { - TSQL_recordset qry(_field); - TString str; - for (int i = 0; i < qry.items(); i++) - { - if (i > 0) str << '\n'; - for (unsigned int j = 0; j < qry.columns(); j++) - { - if (j > 0) str << ' '; - str << qry.get(j).as_string(); - } - } - _var.set(str); - _var.convert_to(ft); - } - else - section().report().evaluate(_field, _var, ft); - } - else - _var.set_null(); - } - compute_draw_rect(); - - return ok; -} - -bool TReport_field::execute_prescript() -{ - bool ok = true; - if (active()) - ok = _prescript.execute(*this); - return ok; -} - -bool TReport_field::execute_postscript() -{ - return deactivated() || _postscript.execute(*this); -} - -void TReport_field::draw_rect(TWindow& win) const -{ - RCT r; win.log2dev(get_rect(), r); - advanced_draw_rect(win, r, border(), fore_color(), back_color()); -} - -COLOR TReport_field::link_color() const -{ - return COLOR_BLUE; -} - -void TReport_field::draw_text(TWindow& win, const char* text, TReport_draw_mode rdm) const -{ - const TRectangle& rct = get_draw_rect(); - RCT r; win.log2dev(rct, r); - advanced_draw_rect(win, r, border(), fore_color(), back_color()); - - if (rdm == rdm_print_preview && link().not_empty()) - { - XVT_FNTID lnkfont = xvt_font_create(); - xvt_font_copy(lnkfont, font().get_xvt_font(win), XVT_FA_ALL); - xvt_font_set_style(lnkfont, XVT_FS_UNDERLINE); - xvt_dwin_set_font(win.win(), lnkfont); - win.set_color(link_color(), back_color()); - } - else - { - xvt_dwin_set_font(win.win(), font().get_xvt_font(win)); - win.set_color(fore_color(), back_color()); - } - - if (rct.height() > 100) - { - const unsigned columns = rct.width() / 100; - int rows = rct.height() / 100; - TParagraph_string str(text, columns); - if (str.items() < rows) - rows = str.items(); - - int ybase = rct.y; - switch (_valign) - { - case 'C': ybase += (rct.height() - rows*100) / 2; break; - case 'B': ybase += rct.height() - rows*100; break; - default : break; - } - char halign = _halign; - char valign = 'T'; - for (int row = 0; row < rows; row++) - { - TRectangle rctline = rct; - rctline.y = ybase + 100*row; - rctline.set_height(100); - win.log2dev(rctline, r); - const char* line = str.get(); - if (halign == 'J' && (row == rows-1 || strlen(line) < columns/2)) - halign = 'L'; - advanced_draw_text(win, line, r, halign, valign); - } - } - else - advanced_draw_text(win, text, r, _halign, _valign); -} - -void TReport_field::get_currency(TCurrency& cur) const -{ - if (_codval.not_empty()) - { - TVariant val; - section().report().evaluate(_codval, val, _alfafld); - cur.force_value(val.as_string()); - } - cur.set_price(_type == 'P'); - cur.set_num(_var.as_real()); -} - -const TString& TReport_field::formatted_text() const -{ - if (_hide_zeroes && _var.is_zero()) - return EMPTY_STRING; - - switch (_type) - { - case 'A': - { - const TString& val = _var.as_string(); - TString_array list; get_list(list); - int i; - for (i = list.last(); i > 0; i--) - if (val == list.row(i).get(0)) - break; - if (i >= 0) - { - TString& fmt = get_tmp_string(); - TToken_string& tok = list.row(i); - tok.get(1, fmt); - return fmt; - } - } - break; - case 'D': - { - const TDate d = _var.as_date(); - TString& tmp = get_tmp_string(); - if (_picture.not_empty()) - { - if (_picture.find('#') >= 0) - { - TString8 str; str.format("%02d%02d%04d", d.day(), d.month(), d.year()); - tmp.picture(_picture, str); - } - else - tmp << _picture << ' ' << d; - } - else - tmp = d.string(_rct.width() >= 1000 ? full : brief); - return tmp; - } - break; - case 'N': - { - const real n = _var.as_real(); - TString& tmp = get_tmp_string(); - if (_picture.not_empty()) - tmp = n.string(_picture); - else - tmp = n.stringa(); - return tmp; - } - break; - case 'P': - case 'V': - { - TString& tmp = get_tmp_string(); - TCurrency cur; get_currency(cur); - tmp = cur.string(true); - return tmp; - } - break; - default: - return _var.as_string(); - } - return EMPTY_STRING; -} - -void TReport_field::draw(TWindow& win, TReport_draw_mode rdm) const -{ - if (rdm != rdm_edit && (hidden() || deactivated())) - return; - - if (rdm == rdm_edit) - compute_draw_rect(); - - PAT_STYLE back_pattern = PAT_HOLLOW; - if (rdm == rdm_edit) - { - if (hidden() || deactivated()) - { - if (hidden() && deactivated()) - back_pattern = PAT_DIAGCROSS; - else - back_pattern = hidden() ? PAT_FDIAG : PAT_BDIAG; - } - } - - switch (_type) - { - case 'E': - { - const bool has_pen = border() > 0; - const bool has_brush = color_distance(back_color(), COLOR_WHITE) != 0; - if (has_pen) - win.set_pen(fore_color(), border(), PAT_SOLID); - else - win.hide_pen(); - if (has_brush) - win.set_brush(back_color(), PAT_SOLID); - else - win.hide_brush(); - RCT r; win.log2dev(get_rect(), r); - xvt_dwin_draw_oval(win.win(), &r); - - if (rdm == rdm_edit && back_pattern != PAT_HOLLOW) - { - win.set_brush(COLOR_GRAY, back_pattern); - xvt_dwin_draw_oval(win.win(), &r); - back_pattern = PAT_HOLLOW; - } - } - break; - case 'I': - { - RCT r; win.log2dev(get_rect(), r); - TReport& rep = section().report(); - if (rdm == rdm_edit) - { - TVariant var; - section().report().evaluate(_field, var, _alfafld); - const TString& name = var.as_string(); - const TImage* img = rep.image(name); - if (img != NULL && img->ok()) - img->draw(win.win(), r); - } - else - { - const TString& name = get().as_string(); - const TImage* img = rep.image(name); - if (img != NULL && img->ok()) - img->draw(win.win(), r); - } - draw_rect(win); - } - break; - case 'L': - { - win.set_pen(fore_color(), border()); - const TRectangle& r = get_rect(); - win.line((short)r.left(), (short)r.top(), (short)r.right(), (short)r.bottom()); - back_pattern = PAT_HOLLOW; - } - break; - case 'R': draw_rect(win); break; - case 'T': draw_text(win, _picture, rdm); break; - default : - if (rdm == rdm_edit) - { - if (border() <= 0) // Rendi piu' visibile il bordo dei campi che non ce l'hanno - { - RCT r; win.log2dev(get_draw_rect(), r); - advanced_draw_rect(win, r, 1, COLOR_LTGRAY, COLOR_WHITE); - } - if (id() > 0) - { - TString16 str; str << id(); - draw_text(win, str, rdm); - } - else - draw_text(win, _field, rdm); - } - else // Real printing - { - const TString& str = formatted_text(); - if (!str.blank()) - draw_text(win, str, rdm); - } - break; - } - - if (rdm == rdm_edit) - { - RCT r; win.log2dev(get_rect(), r); - if (back_pattern != PAT_HOLLOW) - { - win.set_pen(COLOR_LTGRAY); - win.set_brush(COLOR_LTGRAY, back_pattern); - xvt_dwin_draw_rect(win.win(), &r); - } - if (selected()) - { - const int k = 4; - RCT s = r; s.right = s.left+k; s.bottom = s.top+k; - advanced_draw_rect(win, s, 0, COLOR_WHITE, COLOR_LTGRAY); - s = r; s.left = s.right-k; s.top = s.bottom-k; - advanced_draw_rect(win, s, 0, COLOR_WHITE, COLOR_LTGRAY); - } - } -} - -void TReport_field::set_groups(const TString& groups) -{ - _groups.reset(); - _groups.set(groups); -} - -const TString& TReport_field::groups() const -{ - TString& str = get_tmp_string(); - str << _groups; - return str; -} - -bool TReport_field::in_group(int group) const -{ - if (group <= 0) - return _groups.first_one() > 0; - return _groups[group]; -} - -void TReport_field::save(TXmlItem& root) const -{ - TXmlItem& fld = root.AddChild("field"); - fld.SetAttr("type", type_name()); - - const TRectangle& rct = get_rect(); - fld.SetAttr("id", _id); - set_num_attr(fld, "x", rct.left()); - set_num_attr(fld, "y", rct.top()); - set_num_attr(fld, "width", rct.width()); - set_num_attr(fld, "height", rct.height(), 100); - fld.SetAttr("hidden", _hidden); - fld.SetAttr("deactivated", _deactivated); - fld.SetAttr("zeroes_hidden", _hide_zeroes); - set_col_attr(fld, "bg_color", back_color(), COLOR_WHITE); - set_col_attr(fld, "fg_color", fore_color(), COLOR_BLACK); - if (has_font()) - font().save(fld); - if (in_group(0)) - fld.AddChild("groups") << groups(); - - switch (horizontal_alignment()) - { - case 'C': fld.SetAttr("align", "center"); break; - case 'R': fld.SetAttr("align", "right"); break; - case 'J': fld.SetAttr("align", "justify"); break; - default : break; - }; - switch (vertical_alignment()) - { - case 'B': fld.SetAttr("valign", "bottom"); break; - case 'C': fld.SetAttr("valign", "center"); break; - default : break; - }; - fld.SetAttr("border", border()); - fld.SetAttr("text", picture()); - fld.SetAttr("codval", codval()); - fld.SetAttr("link", link()); - if (field().not_empty()) - fld.AddChild("source") << field(); - _prescript.save(fld, "prescript"); - _postscript.save(fld, "postscript"); - - if (_type == 'A') - { - TString_array arr; get_list(arr); - TXmlItem& list = fld.AddChild("list"); - FOR_EACH_ARRAY_ROW(arr, i, row) - { - TXmlItem& li = list.AddChild("li"); - li.SetAttr("Code", row->get(0)); - li << row->get(); - } - } -} - - -bool TReport_field::load(const TXmlItem& fld) -{ - const TString& t = fld.GetAttr("type"); - set_type(t[0]); - - set_id(fld.GetIntAttr("id")); - set_column(get_num_attr(fld, "x")); - set_row(get_num_attr(fld, "y")); - set_width(get_num_attr(fld, "width")); - set_height(get_num_attr(fld, "height", 100)); - _rct_draw = _rct; - show(!fld.GetBoolAttr("hidden")); - activate(!fld.GetBoolAttr("deactivated")); - hide_zeroes(fld.GetBoolAttr("zeroes_hidden")); - set_border(fld.GetIntAttr("border")); - set_back_color(get_col_attr(fld, "bg_color", COLOR_WHITE)); - set_fore_color(get_col_attr(fld, "fg_color", COLOR_BLACK)); - set_horizontal_alignment(get_chr_attr(fld, "align", 'L')); - set_vertical_alignment(get_chr_attr(fld, "valign", 'T')); - set_picture(fld.GetAttr("text")); - set_codval(fld.GetAttr("codval")); - set_link(fld.GetAttr("link")); - TXmlItem* src = fld.FindFirstChild("source"); - if (src != NULL) - src->GetEnclosedText(_field); - TReport_font font; - if (font.load(fld)) - set_font(font); - - TXmlItem* grp = fld.FindFirstChild("groups"); - if (grp != NULL) - { - TString str; grp->GetEnclosedText(str); - set_groups(str); - } - - _prescript.load(fld, "prescript"); - _postscript.load(fld, "postscript"); - - _list.cut(0); - if (_type == 'A') - { - TXmlItem* list = fld.FindFirstChild("list"); - TToken_string tok; - TString str; - for (int i = 0; i < list->GetChildren(); i++) - { - const TXmlItem* li = list->GetChild(i); - tok = li->GetAttr("Code"); - tok.add(li->GetEnclosedText(str)); - _list.add(tok); - } - } - - return true; -} - -void TReport_field::get_list(TString_array& list) const -{ - list.destroy(); - TToken_string& toklst = (TToken_string&)_list; - FOR_EACH_TOKEN(toklst, tok) - list.add(tok); -} - -void TReport_field::set_list(const TString_array& list) -{ - _list.cut(0); - FOR_EACH_ARRAY_ROW(list, i, row) - _list.add(*row); -} - -int TReport_field::compare(const TSortable& s) const -{ - const TReport_field& rf = (TReport_field&)s; - - int cmp = _rct.y - rf._rct.y; - if (cmp == 0) - { - cmp = _rct.x - rf._rct.x; - if (cmp == 0) - cmp = _id - rf._id; - } - return cmp; -} - -TReport_field::TReport_field(TReport_section* sec) - : _section(sec), _id(0), _type('T'), - _font(NULL), _halign('L'), _valign('T'), - _selected(false), _hidden(false), _deactivated(false), _hide_zeroes(false), - _border(0), _fgcolor(COLOR_BLACK), _bgcolor(COLOR_WHITE), _list(32, '\n') -{ - set_pos(0,0); - set_size(1600,100); - _rct_draw = _rct; -} - -TReport_field::TReport_field(const TReport_field& rf) : _font(NULL) -{ - copy(rf); -} - -TReport_field::~TReport_field() -{ - if (_font != NULL) - delete _font; -} - -/////////////////////////////////////////////////////////// -// TReport_link -/////////////////////////////////////////////////////////// - -void TReport_link::set(const char* field, const TVariant& var) -{ - _fields.add(field, var, true); -} - -const TVariant& TReport_link::get(const char* field) const -{ - const TVariant* var = (const TVariant*)_fields.objptr(field); - return var != NULL ? *var : NULL_VARIANT; -} - -void TReport_link::add_rect(const RCT& rct) -{ - // Non memorizzo tutti i rettangoli del link, ma la loro unione - if (xvt_rect_is_empty(&_rct)) - _rct = rct; - else - { - if (rct.left < _rct.left) _rct.left = rct.left; - if (rct.top < _rct.top) _rct.top = rct.top; - if (rct.right > _rct.right) _rct.right = rct.right; - if (rct.bottom > _rct.bottom) _rct.bottom = rct.bottom; - } -} - -int TReport_link::hit_test(const PNT& p) const -{ - if (p.v < _rct.top) - return -1; - if (p.v > _rct.bottom) - return +1; - if (p.h < _rct.left) - return -1; - if (p.h > _rct.right) - return +1; - return 0; -} - -int TReport_link::compare(const TSortable& s) const -{ - const TReport_link& lnk = (const TReport_link&)s; - int cmp = _rct.top - lnk._rct.top; - if (cmp == 0) - cmp = _rct.left - lnk._rct.left; - return cmp; -} - -TReport_link::TReport_link(const char* table) - : _table(table) -{ - xvt_rect_set_empty(&_rct); -} - -/////////////////////////////////////////////////////////// -// TReport -/////////////////////////////////////////////////////////// - -void TReport::build_section_key(char type, int level, TString& key) const -{ key.format("%c%d", type, level); } - -TReport_section* TReport::find_section(char type, int level) const -{ - TString4 key; build_section_key(type, level, key); - TReport_section* sec = (TReport_section*)_sections.objptr(key); - return sec; -} - -bool TReport::kill_section(char type, int level) -{ - TString4 key; build_section_key(type, level, key); - const bool ok = _sections.remove(key); - if (ok && level > 1 && type != 'B') - { - // Cancello anche testa/coda corrispondente - build_section_key(type == 'H' ? 'F' : 'H', level, key); - _sections.remove(key); - } - return ok; -} - -int TReport::find_max_level(char type) const -{ - int lev = 1; - - char type1 = type; - char type2 = ' '; - if (type == 'H' || type == 'F') - { type1 = 'H'; type2 = 'F'; } // Non puo' esistere footer di gruppo senza header - - TAssoc_array& ass = (TAssoc_array&)_sections; - FOR_EACH_ASSOC_OBJECT(ass, h, k, o) if (k[0] == type1 || k[0] == type2) - { - const int l = atoi(k+1); - if (l > lev) - lev = l; - } - return lev; -} - -bool TReport::set_recordset(TRecordset* rs) -{ - if (_recordset != NULL) - { - delete _recordset; - _recordset = NULL; - } - _recordset = rs; - return _recordset != NULL; -} - - -bool TReport::set_recordset(const TString& sql) -{ - bool ok = false; - if (sql.compare("SELECT ", 7, true) == 0) - ok = set_recordset(new TSQL_recordset(sql)); - else - ok = set_recordset(new TISAM_recordset(sql)); - return ok; -} - -TReport_section& TReport::section(char type, int level) -{ - TReport_section* sec = find_section(type, level); - if (sec == NULL) - { - sec = new TReport_section(*this, type, level); - TString4 key; build_section_key(type, level, key); - _sections.add(key, sec); - } - return *sec; -} - -// 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 -{ - if (code[0] == '#') - code++; - - if (isdigit(code[0]) || strncmp(code, "THIS", 4) == 0) // Niente sezione davanti - { - TReport_field* rf = curr_field(); - if (rf != NULL) - { - type = rf->section().type(); - level = rf->section().level(); - } - id = atoi(code); - } - else - { - 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 2; - id = atoi((const char*)code + dot + 1); - } - - return strchr(code, '@') != NULL ? 4 : 3; -} - -TReport_field* TReport::field(const TString& code) -{ - char type = ' '; - int level = -1, id = 0; - const int k = parse_field(code, type, level, id); - - TReport_field* rf = NULL; - if (k == 3) - { - if (id > 0) - { - TReport_section* sec = find_section(type, level); - if (sec != NULL) - rf = sec->find_field(id); - } - else - rf = curr_field(); - } - return rf; -} - -bool TReport::evaluate(const char* expr, TVariant& var, TFieldtypes force_type) -{ - TReport_expr& e = _expressions[expr]; - - // Caso semplice nonche' standard - if (e.numvar() == 1) - { - const TFixed_string name(e.varname(0)); - if (name == expr) - { - if (get_usr_val(name, var)) - { - if (force_type != _nullfld) - var.convert_to(force_type); - return true; - } - } - } - - for (int i = 0; i < e.numvar(); i++) - { - const TFixed_string name(e.varname(i)); - const bool ok = get_usr_val(name, var); - if (!ok) - var = name; - if (var.is_string()) - e.setvar(i, var.as_string()); - else - e.setvar(i, var.as_real()); - } - - const TFieldtypes ft = force_type != _nullfld ? force_type : var.type(); - var = e.as_variant(ft); - - return true; -} - -void TReport::destroy() -{ - _sections.destroy(); - _description.cut(0); - if (_recordset != NULL) - { - delete _recordset; - _recordset = NULL; - } -} - -void TReport::load_sections(const TXmlItem& xml) -{ - for (int i = 0; i < xml.GetChildren(); i++) - { - const TXmlItem& sec = *xml.GetChild(i); - if (sec.GetTag() != "section") - continue; - - const char type = sec.GetAttr("type")[0]; - const int level = sec.GetIntAttr("level"); - TReport_section& rs = section(type, level); - rs.load(sec); - } -} - -bool TReport::load(const char* fname) -{ - destroy(); - TXmlItem xml; - - _path = fname; - bool ok = xml.Load(_path); - if (ok) - { - _lpi = xml.GetIntAttr("lpi", 6); - _font.load(xml); - - const TXmlItem* desc = xml.FindFirstChild("description"); - if (desc != NULL) - desc->GetEnclosedText(_description); - - if (xml.FindFirstChild("section") != NULL) - load_sections(xml); - - const TXmlItem* sql = xml.FindFirstChild("sql"); - if (sql != NULL) - { - TString str; - sql->GetEnclosedText(str); - set_recordset(str); - } - - _include = xml.GetAttr("libraries"); - FOR_EACH_TOKEN(_include, lib) - { - TFilename libname = lib; - libname.trim(); - if (libname.find('.') < 0) - libname.ext("alx"); - include(libname); - } - - _prescript.load(xml, "prescript"); - _postscript.load(xml, "postscript"); - } - return ok; -} - -bool TReport::save(const char* fname) const -{ - char name[_MAX_FNAME]; - xvt_fsys_parse_pathname (fname, NULL, NULL, name, NULL, NULL); - bool ok = *name > ' '; - if (ok) - { - TXmlItem xml; - xml.SetTag("report"); - xml.SetAttr("name", name); - xml.SetAttr("lpi", lpi()); - xml.AddChild("description") << _description; - xml.SetAttr("libraries", _include); - _font.save(xml); - - const char* sectype = "HBF"; - for (int j = 0; j < 3; j++) - { - const int ml = find_max_level(sectype[j]); - for (int i = 0; i <= ml; i++) - { - TReport_section& rs = ((TReport*)this)->section(sectype[j], i); - rs.save(xml); - } - } - - if (_recordset != NULL) - xml.AddChild("sql") << _recordset->query_text(); - - _prescript.save(xml, "prescript"); - _postscript.save(xml, "postscript"); - - xml.Save(fname); - } - return ok; -} - -void TReport::unmap_font() -{ - _font.unmap(); - FOR_EACH_ASSOC_OBJECT(_sections, h, k, o) - { - TReport_section& sec = *(TReport_section*)o; - sec.unmap_font(); - } -} - -const TString& TReport::prescript() const -{ return _prescript.get(); } - -void TReport::set_prescript(const char* src) -{ - _prescript.set(src); -} - -const TString& TReport::postscript() const -{ return _postscript.get(); } - -void TReport::set_postscript(const char* src) -{ - _postscript.set(src); -} - -bool TReport::execute_prescript() -{ - bool ok = true; - - warm_restart(); - if (_prescript.ok()) - { - TString80 str; - ok = _prescript.execute(*this, str); - if (recordset() != NULL) - recordset()->ask_variables(false); - } - else - { - // Script dei poveri: lancia la maschera associata al report - TFilename msk = _path; msk.ext("msk"); - if (msk.exist()) - { - const KEY key = run_form(msk.name()); - ok = key != K_ESC && key != K_QUIT; - } - else - { - // Script dei poverissimi: chiede le eventuali variabili - if (recordset() != NULL) - recordset()->ask_variables(true); - } - } - - return ok; -} - -bool TReport::execute_postscript() -{ - TString80 str; - return _postscript.execute(*this, str); -} - -bool TReport::get_report_field(const TString& name, TVariant& var) const -{ - bool found = false; - const char* str = name; - if (name[0] == '#') - { - if (name.starts_with("#REPORT.")) - { - str += 8; - found = true; - } - else - str++; - } - const TFixed_string n(str); - - if (n == "PAGE") - { - var = curr_page(); - return true; - } - TReport_field* fld = ((TReport*)this)->field(n); - if (fld != NULL) - { - var = fld->get(); - return true; - } - - return found; -} - -bool TReport::get_record_field(const TString& name, TVariant& var) const -{ - bool found = false; - if (_recordset != NULL) - { - const char* str = name; - if (name[0] == '#') - { - if (name.starts_with("#RECORD.")) - { - str += 8; - found = true; - } - else - str++; - } - var = _recordset->get(str); - if (!var.is_null()) - return true; - } - - return found; -} - - -bool TReport::get_usr_val(const TString& name, TVariant& var) const -{ - if (get_report_field(name, var)) - return true; - - if (get_record_field(name, var)) - return true; - - return TAlex_virtual_machine::get_usr_val(name, var); -} - -bool TReport::set_usr_val(const TString& name, const TVariant& var) -{ - const char* str = name; - if (name[0] == '#') - { - if (name.starts_with("#REPORT.")) - str += 8; - else - str++; - } - const TFixed_string n(str); - TReport_field* fld = field(n); - if (fld != NULL) - { - fld->set(var); - return true; - } - - return TAlex_virtual_machine::set_usr_val(name, var); -} - -size_t TReport::get_usr_words(TString_array& words) const -{ - const char* const name[] = - { - "***", "DISABLE", "ENABLE", "GET_POS", - "GET_SIZE", "HIDE", "RUN_FORM", "SET_BACK_COLOR", "SET_FORE_COLOR", - "SET_POS", "SET_SIZE", "SHOW", NULL - }; - size_t i; - for (i = 0; name[i] != NULL; i++) - words.add(name[i]); - return i; -} - -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_pos(TReport_field& rf, void* jolly) -{ - const TPoint& pt = *(const TPoint*)jolly; - rf.set_draw_pos(pt.x, pt.y); -} - -static void do_set_size(TReport_field& rf, void* jolly) -{ - const TPoint& pt = *(const TPoint*)jolly; - rf.set_draw_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) - { - 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 true; -} - -KEY TReport::run_form(const TString& maskname) -{ - TFilename fname = maskname; fname.ext("msk"); - KEY key = K_QUIT; - if (fname.custom_path()) - { - TMask m(maskname); - TVariant var; - for (int i = m.fields()-1; i >= 0; i--) - { - TMask_field& f = m.fld(i); - const TFieldref* ref = f.field(); - if (ref != NULL) - { - TString name = ref->name(); - if (name[0] != '#') - name.insert("#"); - if (get_usr_val(name, var)) - f.set(var.as_string()); - } - } - key = m.run(); - if (key != K_QUIT && key != K_ESC) - { - TRecordset* rset = recordset(); - if (rset != NULL && rset->variables().items() == 0) - rset = NULL; - - // Rendi visibili tutte le variabili utente al report - for (int i = m.fields()-1; i >= 0; i--) - { - TMask_field& f = m.fld(i); - const TFieldref* ref = f.field(); - if (ref != NULL) - { - switch (f.class_id()) - { - case CLASS_CURRENCY_FIELD: - case CLASS_REAL_FIELD: var = real(f.get()); break; - case CLASS_DATE_FIELD: var = TDate(f.get()); break; - default: var = f.get(); break; - } - TString name = ref->name(); - if (name[0] != '#') - name.insert("#"); - set_usr_val(name, var); - if (rset != NULL) - rset->set_var(name, var); - } - } - } - } - return key; -} - -bool TReport::execute_usr_word(unsigned int opcode, TVariant_stack& stack) -{ - switch (opcode) - { - case 1: // Placeholder - break; - case 2: // DISABLE - do_message(stack.pop(), do_enable, NULL); - break; - case 3: // ENABLE - do_message(stack.pop(), do_enable, (void*)1); - break; - case 4: // GET_POS - { - const TReport_field* fld = field(stack.pop().as_string()); - real x, y; - if (fld != NULL) - { - const TRectangle& r = fld->get_draw_rect(); - x = r.x / CENTO; y = r.y / CENTO; - } - stack.push(x); stack.push(y); - } - break; - case 5: // GET_SIZE - { - const TReport_field* fld = field(stack.pop().as_string()); - real w, h; - if (fld != NULL) - { - const TRectangle& r = fld->get_draw_rect(); - w = r.width() / CENTO; h = r.height() / CENTO; - } - stack.push(w); stack.push(h); - } - break; - case 6: // HIDE - do_message(stack.pop(), do_show, NULL); - break; - case 7: // RUN_FORM - { - const TString& msk = stack.pop().as_string(); - const KEY key = run_form(msk); - stack.push(key); - } - break; - case 8: // SET_BACK_COLOR - { - const COLOR rgb = stack.pop().as_color(); - do_message(stack.pop(), do_set_back_color, (void*)rgb); - } - break; - case 9: // SET_FORE_COLOR - { - const COLOR rgb = stack.pop().as_color(); - do_message(stack.pop(), do_set_fore_color, (void*)rgb); - } - break; - case 10: // SET_POS - { - const TVariant& fld = stack.pop(); - const real y = stack.pop().as_real() * CENTO; - const real x = stack.pop().as_real() * CENTO; - const TPoint pt(x.integer(), y.integer()); - do_message(fld, do_set_pos, (void*)&pt); - } - break; - case 11: // SET_SIZE - { - const TVariant& fld = stack.pop(); - const real h = stack.pop().as_real() * CENTO; - const real w = stack.pop().as_real() * CENTO; - const TPoint sz(w.integer(), h.integer()); - do_message(fld, do_set_size, (void*)&sz); - } - break; - case 12: // SHOW - do_message(stack.pop(), do_show, (void*)1); - break; - default: - return false; - } - return true; -} - -bool TReport::on_link(const TReport_link& lnk) -{ - const TString& table = lnk.table(); - const int logicnum = table2logic(table); - if (logicnum >= LF_USER) - { - TRectype rec(logicnum); - TAssoc_array& fields = lnk.fields(); - FOR_EACH_ASSOC_OBJECT(fields, h, k, o) - { - const TVariant* var = (const TVariant*)o; - rec.put(k, var->as_string()); - } - return rec.edit(); - } - - return false; -} - -TReport::TReport() : _lpi(6), _recordset(NULL), _curr_field(NULL), _include(15, ',') -{ - _expressions.set_report(this); - - include("report.alx"); // Include base libraries - - _prescript.set_description("PRESCRIPT"); - _postscript.set_description("POSTSCRIPT"); -} - -TReport::~TReport() -{ - destroy(); -} - diff --git a/ba/ba8302.h b/ba/ba8302.h deleted file mode 100755 index adcbeeac8..000000000 --- a/ba/ba8302.h +++ /dev/null @@ -1,466 +0,0 @@ -#ifndef __REPORT_H -#define __REPORT_H - -#ifndef __ASSOC_H -#include -#endif - -#ifndef __IMAGE_H -#include -#endif - -#ifndef __WINDOW_H -#include -#endif - -#ifndef __XML_H -#include -#endif - -#ifndef __RECORDSET_H -#include "ba8201.h" -#endif - -#ifndef __ALEX_H -#include "ba8304.h" -#endif - -/////////////////////////////////////////////////////////// -// TReport_font -/////////////////////////////////////////////////////////// - -class TReport_font : public TSortable -{ - enum { DEFAULT_FONT_SIZE = 10 }; - - TString _name; - int _size, _cpi; - XVT_FONT_STYLE_MASK _style; - - WINDOW _win_mapped; - XVT_FNTID _fontid; - int _leading, _ascent, _descent; - -protected: - virtual int compare(const TSortable& s) const; - void copy(const TReport_font& f); - -public: - const TString& name() const { return _name; } - int size() const { return _size; } - XVT_FONT_STYLE_MASK style() const { return _style; } - int cpi() const { return _cpi; } - XVT_FNTID get_xvt_font(const TWindow& win) const; - void unmap(); - - int leading() const { return _leading; } - int ascent() const { return _ascent; } - int descent() const { return _descent; } - - void save(TXmlItem& root) const; - bool load(const TXmlItem& root); - - void create(const char* name, int size, XVT_FONT_STYLE_MASK style); - TReport_font& operator=(const TReport_font& f) { copy(f); return *this; } - TReport_font(); - TReport_font(const TReport_font& f); - virtual ~TReport_font(); -}; - -class TReport; -class TReport_field; - -/////////////////////////////////////////////////////////// -// Cache varie -/////////////////////////////////////////////////////////// - -class TReport_expr; - -class TReport_expr_cache : public TCache -{ - TReport* _report; - -protected: - virtual TObject* key2obj(const char* key); - -public: - TReport_expr& operator[](const char* key); - - void set_report(TReport* rep) { _report = rep; } - TReport_expr_cache() : _report(NULL) { } -}; - -class TReport_image_cache : public TCache -{ -protected: - virtual TObject* key2obj(const char* key); - -public: - TImage* image(const TString& name); - TReport_image_cache(); -}; - -/////////////////////////////////////////////////////////// -// TReport_script -/////////////////////////////////////////////////////////// - -class TReport_script : public TObject -{ - TBytecode* _bc; // Chesire's cat class - TString _src, _desc; - -protected: - void destroy(); - TString& translate_message(TReport& report) const; - void copy(const TReport_script& rs); - -public: - virtual bool ok() const { return !_src.blank(); } - void set(const char* source); - const TString& get() const { return _src; } - void set_description(const char* d) { _desc = d; } - - bool compile(TReport& report); - bool execute(TReport& report, TString& output); - bool execute(TReport_field& rf); - - void save(TXmlItem& root, const char* tag) const; - bool load(const TXmlItem& root, const char* tag); - - TReport_script& operator =(const TReport_script& rs) { copy(rs); return *this; } - TReport_script(); - TReport_script(const TReport_script& rs) { copy(rs); } - virtual ~TReport_script(); -}; - -/////////////////////////////////////////////////////////// -// TReport_section -/////////////////////////////////////////////////////////// - -enum TReport_draw_mode { rdm_edit, rdm_print, rdm_print_preview, rdm_spooler, rdm_textonly }; - -class TReport_section : public TArray -{ - TReport& _report; - - char _type; // Head,Body,Tail - int _level; // 0,1,2,... - TPoint _pos; // Posizione assoluta in centesimi, default (0,0) - TPoint _size; // Dimensioni in centesimi, default (0,0) - TString _groupby; - bool _page_break, _hidden_if_needed, _keep_with_next; - bool _hidden, _deactivated; - TReport_script _prescript, _postscript; - - TReport_font* _font; - -protected: - virtual const char* class_name() const { return "ReportSection"; } - TReport_section* father_section() const; - -public: - virtual int add(TObject* obj); - virtual int add(TObject& obj); - TReport_field& field(int i) { return *(TReport_field*)objptr(i); } - const TReport_field& field(int i) const { return *(TReport_field*)objptr(i); } - int find_field_pos(int id); - TReport_field* find_field(int id); - TReport& report() { return _report; } - - char type() const { return _type; } - int level() const { return _level; } - - int width() const { return _size.x; } - int height() const { return _size.y; } - void set_width(short w) { _size.x = w; } - void set_height(short h) { _size.y = h; } - const TPoint& size() const { return _size; } - TPoint compute_size() const; - 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; } - - const TString& grouped_by() const { return _groupby; } - void group_by(const char* gb) { _groupby = gb; } - - bool hidden_if_needed() const { return _hidden_if_needed; } - void hide_if_needed(bool h) { _hidden_if_needed = h; } - bool keep_with_next() const { return _keep_with_next; } - void keep_with_next(bool k) { _keep_with_next = k; } - bool hidden() const { return _hidden; } - bool shown() const { return !hidden(); } - void show(bool on) { _hidden = !on; } - void hide() { show(false); } - bool deactivated() const { return _deactivated; } - bool active() const { return !deactivated(); } - void activate(bool on) { _deactivated = !on; } - void deactivate() { activate(false); } - - const TString& prescript() const; - void set_prescript(const char* src); - const TString& postscript() const; - void set_postscript(const char* src); - - bool has_font() const { return _font != NULL; } - const TReport_font& font() const; - void set_font(const TReport_font& f); - void unmap_font(); - - bool load_fields(); - bool execute_prescript(); - bool execute_postscript(); - void draw(TWindow& win, TReport_draw_mode mode) const; - - void save(TXmlItem& report) const; - void load(const TXmlItem& sec); - - TReport_section(TReport& r, char t, int l); - virtual ~TReport_section(); -}; - -class TReport_field : public TSortable -{ - TReport_section* _section; - int _id; - char _type; // Text, String, Numeric, Price, Valuta, Date, Line, Rectangle, Image - TRectangle _rct, _rct_draw; // In centesimi - COLOR _fgcolor, _bgcolor; - short _border; - char _halign, _valign; - TBit_array _groups; - TString _picture, _field, _codval, _link; - TVariant _var; - TReport_script _prescript, _postscript; - TToken_string _list; // Elementi di un campo lista - - TReport_font* _font; - bool _hidden, _deactivated, _hide_zeroes, _selected; - -protected: - virtual const char* class_name() const { return "ReportField"; } - virtual int compare(const TSortable& s) const; - void copy(const TReport_field& rf); - TFieldtypes var_type() const; - const TString& formatted_text() const; - void get_currency(TCurrency& cur) const; - void compute_draw_rect() const; - -public: - virtual TObject* dup() const { return new TReport_field(*this); } - TReport_field& operator=(const TReport_field& rf) { copy(rf); return *this; } - - TReport_section& section() const { return *_section; } - void set_section(TReport_section* sec) { _section = sec; } - - bool has_font() const { return _font != NULL; } - const TReport_font& font() const; - void set_font(const TReport_font& f); - void unmap_font(); - - const TString& picture() const { return _picture; } - void set_picture(const char* str) { _picture = str; } - - const TString& field() const { return _field; } - void set_field(const char* str) { _field = str; } - - const TVariant& get() const { return _var; } - void set(const char* str); - void set(const TVariant& var); - - bool load_field(); - bool execute_prescript(); - bool execute_postscript(); - - void get_list(TString_array& list) const; - void set_list(const TString_array& list); - - int id() const { return _id; } - void set_id(int id) { _id = id; } - char type() const { return _type; } - const char* type_name() const; - void set_type(char t) { _type = t; } - void set_pos(long x, long y); - void set_row(long y) { _rct.y = y; } - void set_column(long x) { _rct.x = x; } - void set_size(long w, long h); - void set_width(long dx) { _rct.set_width(dx); } - void set_height(long dy) { _rct.set_height(dy); } - const TRectangle& get_rect() const { return _rct; } - - void set_draw_pos(long x, long y); - void set_draw_size(long x, long y); - const TRectangle& get_draw_rect() const { return _rct_draw; } - - bool hidden() const { return _hidden; } - bool shown() const { return !hidden(); } - void show(bool on) { _hidden = !on; } - void hide() { show(false); } - bool deactivated() const { return _deactivated; } - bool active() const { return !deactivated(); } - void activate(bool on) { _deactivated = !on; } - void deactivate() { activate(false); } - bool zeroes_hidden() const { return _hide_zeroes; } - void hide_zeroes(bool hz) { _hide_zeroes = hz; } - - void set_groups(const TString& groups); - const TString& groups() const; - bool in_group(int group) const; - void set_codval(const char* cod) { _codval = cod; } - const TString& codval() const { return _codval; } - void set_link(const char* l) { _link = l; } - const TString& link() const { return _link; } // TABLE.FIELD - - void set_fore_color(COLOR c) { _fgcolor = c; } - COLOR fore_color() const { return _fgcolor; } - void set_back_color(COLOR c) { _bgcolor = c; } - COLOR back_color() const { return _bgcolor; } - COLOR link_color() const; - void set_border(short b) { _border = b; } - short border() const { return _border; } - void set_horizontal_alignment(char a) { _halign = a; } - char horizontal_alignment() const { return _halign; } - void set_vertical_alignment(char a) { _valign = a; } - char vertical_alignment() const { return _valign; } - - const TString& prescript() const; - void set_prescript(const char* src); - const TString& postscript() const; - void set_postscript(const char* src); - - void select(bool ok = true) { _selected = ok; } - bool selected() const { return _selected; } - void offset(const TPoint& pt); - - 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; - - void save(TXmlItem& root) const; - bool load(const TXmlItem& root); - - TReport_field(TReport_section* sec); - TReport_field(const TReport_field& rf); - virtual ~TReport_field(); -}; - -class TReport_link : public TSortable -{ - TString _table; - TAssoc_array _fields; - RCT _rct; - -protected: - virtual int compare(const TSortable& s) const; - -public: - const TString& table() const { return _table; } - void set(const char* field, const TVariant& value); - const TVariant& get(const char* field) const; - void add_rect(const RCT& rct); // Aggiunge un rettangolo al link - int hit_test(const PNT& p) const; - - TAssoc_array& fields() const { return (TAssoc_array&)_fields; } - - TReport_link(const char* table); - virtual ~TReport_link() { } -}; - -// Internal usage only -typedef void (*FLDMSG_FUNC)(TReport_field& rf, void* jolly); - -class TReport : public TAlex_virtual_machine -{ - TAssoc_array _sections; - TFilename _path; - TString _description; - TReport_font _font; - int _lpi; // Lines per inch - TToken_string _include; - TReport_script _prescript, _postscript; - TRecordset* _recordset; - TReport_expr_cache _expressions; - TReport_image_cache _images; - word _curr_page; - TReport_field* _curr_field; - -protected: - virtual const char* class_name() const { return "Report"; } - virtual size_t get_usr_words(TString_array& words) const; - virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); - virtual bool get_usr_val(const TString& name, TVariant& var) const; - virtual bool set_usr_val(const TString& name, const TVariant& var); - KEY run_form(const TString& msk); - - 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; - COLOR get_col_attr(const TXmlItem& item, const char* attr, COLOR defcol = COLOR_BLACK) const; - void load_sections(const TXmlItem& xml); - void save_section(const TReport_section& rs, TXmlItem& item) const; - - bool get_report_field(const TString& name, TVariant& var) const; - bool get_record_field(const TString& name, TVariant& var) const; - -public: - TReport_section* find_section(char type, int level) const; - TReport_section& section(char type, int level); - bool kill_section(char type, int level); - int find_max_level(char type) const; - - virtual bool on_link(const TReport_link& link); - - const TReport_font& font() const { return _font; } - void set_font(const TReport_font& f) { _font = f; } - void unmap_font(); - - int cpi() const { return _font.cpi(); } - int lpi() const { return _lpi; } - void set_lpi(int lpi) { _lpi= lpi; } - - bool set_recordset(const TString& sql); - bool set_recordset(TRecordset* sql); - TRecordset* recordset() const { return _recordset; } - bool evaluate_atom(const char* atom, TVariant& var); - bool evaluate(const char* expr, TVariant& var, TFieldtypes force_type); - - const TString& prescript() const; - void set_prescript(const char* src); - const TString& postscript() const; - void set_postscript(const char* src); - bool execute_prescript(); - bool execute_postscript(); - - void set_libraries(const char* inc) { _include = inc; } - TToken_string& get_libraries() { return _include; } - - void set_description(const char* d) { _description = d; } - const TString& description() const { return _description; } - TImage* image(const TString& name) { return _images.image(name); } - - const TFilename& filename() const { return _path; } - bool save(const char* fname) const; - bool load(const char* fname); - - // Used by TReport_printer - void set_curr_page(word p) { _curr_page = p; } - word curr_page() const { return _curr_page; } - void set_curr_field(TReport_field* fld) { _curr_field = fld; } - TReport_field* curr_field() const { return _curr_field; } - - int parse_field(const char* code, char& type, int& level, int& id) const; - TReport_field* field(const TString& code); - - void destroy(); - TReport(); - virtual ~TReport(); -}; - -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); - -#endif diff --git a/ba/ba8303.cpp b/ba/ba8303.cpp deleted file mode 100755 index 895ba1c22..000000000 --- a/ba/ba8303.cpp +++ /dev/null @@ -1,918 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include "ba8201.h" -#include "ba8303.h" - -static bool _print_aborted = false; - -/////////////////////////////////////////////////////////// -// TPrint_preview_window -/////////////////////////////////////////////////////////// - -class TPrint_preview_window : public TField_window -{ - TPage_printer* _printer; - word _page, _last; - int _zoom; - static bool _locked; - -protected: - void page_select(); - void popup_menu(EVENT* ep); - virtual void handler(WINDOW win, EVENT* ep); - virtual void update(); - virtual bool on_key(KEY k); - -public: - virtual PNT log2dev(long lx, long ly) const; - static void lock_preview_update(bool yes) { _locked = yes; } - - void set_printer(TPage_printer* printer) { _printer = printer; } - TPrint_preview_window(int x, int y, int dx, int dy, WINDOW parent, - TWindowed_field* owner, TPage_printer* printer); -}; - -bool TPrint_preview_window::_locked = false; - -PNT TPrint_preview_window::log2dev(long lx, long ly) const -{ - PNT pnt; - pnt.h = short(lx * _zoom / 1000); - pnt.v = short(ly * _zoom / 1000); - - const TPoint orig = origin(); - pnt.h -= short(orig.x*10); - pnt.v -= short(orig.y*10); - - return pnt; -} - -void TPrint_preview_window::update() -{ - if (!_locked) - { - _printer->print_page(_page); - TString80 str; - str.format(FR("Pagina %u di %u"), _page, _last); - statbar_set_title(TASK_WIN, str); - } -} - -#define POPUP_FIRST 20883 -#define POPUP_PREV 20884 -#define POPUP_NEXT 20885 -#define POPUP_SEARCH 20886 -#define POPUP_LAST 20887 -#define POPUP_ZOOMIN 20888 -#define POPUP_ZOOMOUT 20889 -#define POPUP_GRID 20890 - -void TPrint_preview_window::popup_menu(EVENT* ep) -{ - MENU_ITEM menu[16]; // Stiamo larghi - memset(menu, 0, sizeof(menu)); - menu[0].tag = POPUP_FIRST; menu[0].text = (char*)TR("Prima"); menu[0].enabled = true; - menu[1].tag = POPUP_PREV; menu[1].text = (char*)TR("Indietro"); menu[1].enabled = _page > 1; - menu[2].tag = POPUP_NEXT; menu[2].text = (char*)TR("Avanti"); menu[2].enabled = _last == 0 || _page < _last; - menu[3].tag = POPUP_LAST; menu[3].text = (char*)TR("Ultima"); menu[3].enabled = true; - menu[4].tag = -1; menu[4].separator = true; - 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 > 75; - 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].checkable = true; menu[8].checked = _printer->show_preview_grid(); - - const PNT& p = ep->v.mouse.where; - xvt_menu_popup(menu, win(), p, XVT_POPUP_CENTER, 0); -} - -void TPrint_preview_window::page_select() -{ - TMask m("Ricerca", 1, 28, 4); - m.add_number(101, 0, "Pagina ", 1, 1, 4, "U").check_type(CHECK_REQUIRED); - m.add_button(DLG_OK, 0, "", -12, -1, 10, 2); - m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2); - if (m.run()) - { - _page = m.get_int(101); - if (_last > 0 && _page > _last) - _page = _last; - } -} - -void TPrint_preview_window::handler(WINDOW win, EVENT* ep) -{ - switch (ep->type) - { - case E_MOUSE_MOVE: - if (_printer->find_link(ep->v.mouse.where) != NULL) - xvt_win_set_cursor(win, CURSOR_CROSS); - else - xvt_win_set_cursor(win, CURSOR_ARROW); - break; - case E_MOUSE_DOWN: - if (ep->v.mouse.button == 0) - { - const TReport_link* lnk = _printer->find_link(ep->v.mouse.where); - if (lnk != NULL) - _printer->on_link(*lnk); - } - else - popup_menu(ep); - break; - case E_COMMAND: - { - bool processed = true; - switch(ep->v.cmd.tag) - { - case POPUP_FIRST : _page = 1; break; - case POPUP_PREV : if (_page > 1) _page--; break; - case POPUP_SEARCH : page_select(); break; - case POPUP_NEXT : if (_last == 0 || _page < _last) _page++; break; - case POPUP_LAST : - if (_last == 0) - { - _printer->print_page(9999); - _last = _printer->last_printed_page(); - } - _page = _last; - break; - case POPUP_ZOOMIN : if (_zoom < 300) { _zoom += 25; } break; - case POPUP_ZOOMOUT: if (_zoom > 75) { _zoom -= 25; } break; - case POPUP_GRID : _printer->toggle_preview_grid(); break; - default:processed = false; break; - } - if (processed) - { - _print_aborted = false; - force_update(); - } - } - break; - default: - break; - } - TField_window::handler(win, ep); -} - -bool TPrint_preview_window::on_key(KEY k) -{ - bool ok = true; - switch (k) - { - case '+' : dispatch_e_menu(win(), POPUP_ZOOMIN); break; - case '-' : dispatch_e_menu(win(), POPUP_ZOOMOUT); break; - case K_HOME : - case K_LHOME : dispatch_e_menu(win(), POPUP_FIRST); break; - case K_LEFT : dispatch_e_menu(win(), POPUP_PREV); break; - case K_RIGHT : dispatch_e_menu(win(), POPUP_NEXT); break; - case K_END: - case K_LEND : dispatch_e_menu(win(), POPUP_LAST); break; - case 'G' : - case 'g' : dispatch_e_menu(win(), POPUP_GRID); break; - default : ok = TField_window::on_key(k); break; - }; - return ok; -} - -TPrint_preview_window::TPrint_preview_window(int x, int y, int dx, int dy, WINDOW parent, - TWindowed_field* owner, TPage_printer* printer) -: TField_window(x, y, dx, dy, parent, owner), _printer(printer), - _page(1), _last(0), _zoom(120) -{ - RCT rct; xvt_vobj_get_client_rect(win(), &rct); - set_scroll_max(rct.right, rct.bottom); -} - -/////////////////////////////////////////////////////////// -// TPrint_preview_field -/////////////////////////////////////////////////////////// - -class TPrint_preview_field : public TWindowed_field -{ - TPage_printer* _printer; - -protected: - virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent); - -public: - TPrint_preview_field(TMask* m, TPage_printer* printer) : TWindowed_field(m), _printer(printer) { } -}; - -TField_window* TPrint_preview_field::create_window(int x, int y, int dx, int dy, WINDOW parent) -{ - return new TPrint_preview_window(x, y, dx, dy, parent, this, _printer); -} - -/////////////////////////////////////////////////////////// -// TPreview_mask -/////////////////////////////////////////////////////////// - -class TPreview_mask : public TAutomask -{ - TPage_printer* _printer; - -protected: - virtual bool on_key(KEY k); - virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); - virtual TMask_field* parse_field(TScanner& scanner); - -public: - TPreview_mask(TPage_printer* printer); -}; - -bool TPreview_mask::on_key(KEY k) -{ - switch (k) - { - case '+' : - case '-' : - case K_HOME : - case K_LHOME: - case K_LEFT : - case K_RIGHT: - case K_END : - case K_LEND : - case 'G' : - case 'g' : - dispatch_e_char(_printer->win(), k); - return true; - default: - break; - } - return TAutomask::on_key(k); -} - -bool TPreview_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) -{ - if (e == fe_button) - { - switch (o.dlg()) - { - case DLG_FIRSTREC: dispatch_e_menu(_printer->win(), POPUP_FIRST); break; - case DLG_PREVREC : dispatch_e_menu(_printer->win(), POPUP_PREV); break; - case DLG_FINDREC : dispatch_e_menu(_printer->win(), POPUP_SEARCH);break; - case DLG_NEXTREC : dispatch_e_menu(_printer->win(), POPUP_NEXT); break; - case DLG_LASTREC : dispatch_e_menu(_printer->win(), POPUP_LAST); break; - default: break; - } - } - return true; -} - -TMask_field* TPreview_mask::parse_field(TScanner& scanner) -{ - if (scanner.token().starts_with("PR")) - return new TPrint_preview_field(this, _printer); - return TAutomask::parse_field(scanner); -} - -TPreview_mask::TPreview_mask(TPage_printer* printer) - : _printer(printer) -{ - read_mask("ba8303", 0, -1); - set_handlers(); - - int pos = id2pos(DLG_FINDREC); - if (pos >= 0 && id2pos(DLG_FIRSTREC) >= 0) //se e' un bottone pentapartito... - { - TButton_field& f_find = (TButton_field &)fld(pos); - RCT rct_base; f_find.get_rect(rct_base); - const int bwidth = (rct_base.right - rct_base.left); - const int bheight = (rct_base.bottom - rct_base.top); - if (bwidth > 3*bheight/2) // Controllo se ho gia' ridimensionato i bottoni in precedenza - { - int bx = bwidth / 3; - int by = bheight / 2; - - RCT r = rct_base; r.left += bx-2; r.right -= bx-2; - f_find.set_rect(r); // Ridimensiona il bottone centrale di ricerca - - bx += 5; by += 3; // Aggiusta dimensioni bottoni sussidiari - - pos = id2pos(DLG_FIRSTREC); - if (pos >= 0) - { - r = rct_base; r.top = r.bottom - by; r.right = r.left + bx; - fld(pos).set_rect(r); - } - pos = id2pos(DLG_PREVREC); - if (pos >= 0) - { - r = rct_base; r.bottom = r.top + by; r.right = r.left + bx; - fld(pos).set_rect(r); - } - pos = id2pos(DLG_NEXTREC); - if (pos >= 0) - { - r = rct_base; r.bottom = r.top + by; r.left = r.right - bx; - fld(pos).set_rect(r); - } - pos = id2pos(DLG_LASTREC); - if (pos >= 0) - { - r = rct_base; r.top = r.bottom - by; r.left = r.right - bx; - fld(pos).set_rect(r); - } - } - } -} - -/////////////////////////////////////////////////////////// -// TPage_printer -/////////////////////////////////////////////////////////// - -const char* TPage_printer::form_name() const -{ - return printer().get_form_name(); -} - -const char* TPage_printer::font_name() const -{ - return printer().fontname(); -} - -int TPage_printer::font_size() const -{ - return printer().get_char_size(); -} - -bool TPage_printer::ask_pages() -{ - if (_pageto <= 0) - _pageto = pages(); - - TPrinter& p = printer(); - TMask msk("bagn003"); - msk.set(F_PRINTER, p.printername()); - msk.set(F_FORM, form_name()); - msk.set(F_FONT, font_name()); - msk.set(F_SIZE, font_size()); - msk.set(F_ISGRAPHICS, p.isgraphics() ? "X" : ""); - msk.set(F_FROMPAGE, _pagefrom); - msk.set(F_TOPAGE, _pageto); - msk.set(F_COPIES, _copies); - const bool ok = msk.run() == K_ENTER; - if (ok) - { - _copies = msk.get_int(F_COPIES); - _pagefrom = msk.get_int(F_FROMPAGE); - _pageto = msk.get_int(F_TOPAGE); - if (_pageto < _pagefrom) - _pageto = 0; - } - return ok; -} - -bool TPage_printer::main_loop() -{ - TPrinter& p = printer(); - _rcd = p.get_printrcd(); - if (!xvt_print_is_valid(_rcd)) - return false; // aborted - - WINDOW prwin = xvt_print_create_win(_rcd, (char*)(const char*)form_name()); - if (prwin == NULL_WIN) - return false; // aborted - set_win(prwin); - - xvt_app_escape (XVT_ESC_GET_PRINTER_INFO, _rcd, &_ph, &_pw, &_pvr, &_phr); - - if (_pw <= 0 || _ph <= 0) - return error_box(TR("Dimensioni pagina NULLE")); - - bool ok = true; - if (_pvr < 150 || _phr < 150) - { - ok = yesno_box(TR("Stampante obsoleta o non adeguatamente configurata:\n" - "Risoluzione %ldx%ld. Continuare ugualmente?"), _phr, _pvr); - if (!ok) - return false; - } - _print_aborted = false; - - for (word c = 0; c < _copies && ok; c++) - { - _page = 0; - ok = print_loop(); - } - _print_aborted = false; - - xvt_vobj_destroy(prwin); - set_win(NULL_WIN); - - return ok; -} - -bool TPage_printer::page_in_range() const -{ - if (_page < _pagefrom) - return false; - return _pageto < _pagefrom || _page <= _pageto; -} - -PNT TPage_printer::log2dev(long lx, long ly) const -{ - if (preview_mode()) - return _preview_window->log2dev(lx, ly); - const PNT p = { short(ly), short(lx) }; - return p; -} - -TPoint TPage_printer::dev2log(const PNT& pnt) const -{ - CHECK(0, "dev2log: Pure virtual funtion call"); - const TPoint p; - return p; -} - -bool TPage_printer::open_page() -{ - _page++; - if (page_in_range()) - { - if (print_mode()) - _page_is_open = xvt_print_open_page(_rcd) != 0; - else - { - _page_is_open = true; - - _links.destroy(); // Distrugge elenco dei links - _links_sorted = false; - } - } - else - _page_is_open = false; - - return _page_is_open; -} - -bool TPage_printer::close_page() -{ - const bool was_open = _page_is_open; - if (was_open) - { - if (print_mode()) - xvt_print_close_page(_rcd); - - _page_is_open = false; - } - return was_open; -} - -void TPage_printer::add_link(TReport_link* link) -{ - _links.add(link); - _links_sorted = false; -} - -static BOOLEAN main_loop_callback(long jolly) -{ - TPage_printer* pp = (TPage_printer*)jolly; - return pp->main_loop(); -} - -bool TPage_printer::do_print() -{ - _print_aborted = true; - bool ok = ask_pages(); - if (ok) - ok = xvt_print_start_thread(main_loop_callback, long(this)) == FALSE; - return ok; -} - -void TPage_printer::print_page(word page) -{ - _pagefrom = _pageto = page; - _page = 0; - print_loop(); -} - -bool TPage_printer::do_preview() -{ - _print_aborted = true; - - TPrinter& p = printer(); - _rcd = p.get_printrcd(); - if (!xvt_print_is_valid(_rcd)) - return error_box(TR("Stampante non valida")); - - xvt_app_escape (XVT_ESC_GET_PRINTER_INFO, _rcd, &_ph, &_pw, &_pvr, &_phr); - if (_pw <= 0 || _ph <= 0) - return error_box(TR("Dimensioni pagina NULLE")); - - _preview_mask = new TPreview_mask(this); - TPrint_preview_field& pf = (TPrint_preview_field&)_preview_mask->field(DLG_USER); - _preview_window = &pf.win(); - - set_win(_preview_window->win()); - _pagefrom = _pageto = _page = 1; - _print_aborted = false; - - const KEY key = _preview_mask->run(); - set_win(NULL_WIN); - - delete _preview_mask; - _preview_mask = NULL; - - if (key == K_INS) - print(); - - return true; -} - -const TReport_link* TPage_printer::find_link(const PNT& pnt) const -{ - if (!_links_sorted) - { - TPage_printer* myself = (TPage_printer*)this; - myself->_links.sort(); - myself->_links_sorted = true; - } - - int primo = 0, ultimo = _links.last(); - while (primo <= ultimo) - { - const int in_mezzo = (primo+ultimo)/2; - const TReport_link* lnk = (const TReport_link*)_links.objptr(in_mezzo); - const int cmp = lnk->hit_test(pnt); - if (cmp == 0) - return lnk; - if (cmp < 0) - ultimo = in_mezzo-1; - else - primo = in_mezzo+1; - } - return NULL; -} - -bool TPage_printer::on_link(const TReport_link& lnk) -{ - return false; -} - -bool TPage_printer::print(bool prev_mode) -{ - return prev_mode ? do_preview() : do_print(); -} - -TPoint TPage_printer::page_size() const -{ - return TPoint(_pw, _ph); -} - -TPoint TPage_printer::page_res() const -{ - TPoint pt(_phr, _pvr); - return pt; -} - -TPage_printer::TPage_printer() - : _pagefrom(1), _pageto(0), _copies(1), _preview_mask(NULL), _draw_grid(true) -{ - _pixmap = true; // Fondamentale!!! -} - -TPage_printer::~TPage_printer() -{ } - - -/////////////////////////////////////////////////////////// -// TReport_printer -/////////////////////////////////////////////////////////// - -const char* TReport_printer::form_name() const -{ - return _report.filename(); -} - -const char* TReport_printer::font_name() const -{ - return _report.font().name(); -} - -int TReport_printer::font_size() const -{ - return _report.font().size(); -} - -PNT TReport_printer::log2dev(long lx, long ly) const -{ - const TPoint res = page_res(); - const double cx = (double)res.x / (double)_report.cpi(); - const double cy = (double)res.y / (double)_report.lpi(); - const long x = long((lx + _delta.x) * cx / 100.0); - const long y = long((ly + _delta.y) * cy / 100.0); - - return TPage_printer::log2dev(x, y); // Useful for preview mode -} - -long TReport_printer::print_section(char type, int level) -{ - long h = 0; - TReport_section* rs = _report.find_section(type, level); - if (rs != NULL) - h = print_section(*rs); - return h; -} - -void TReport_printer::draw_preview_page() -{ - clear(COLOR_WHITE); - - if (_draw_grid) - { - const int max = 192; - const int k = 100; - for (int i = 1; i < max; i++) - { - set_pen((i%10) ? MAKE_COLOR(232,232,232) : COLOR_LTGRAY); - line(0, i*k, max*k, i*k); - line(i*k, 0, i*k, max*k); - } - } - - const PNT pag = log2dev(_logical_page_width, _logical_page_height); - hide_pen(); - set_brush(COLOR_GRAY); - RCT rct; - xvt_vobj_get_client_rect(win(), &rct); rct.left = pag.h; - xvt_dwin_draw_rect(win(), &rct); - xvt_vobj_get_client_rect(win(), &rct); rct.top = pag.v; - xvt_dwin_draw_rect(win(), &rct); -} - -bool TReport_printer::open_page() -{ - const bool ok = TPage_printer::open_page(); - - _report.set_curr_page(_page); - - _delta.reset(); - _page_break_allowed = false; - - if (ok && preview_mode()) // Clear page needed - draw_preview_page(); - - TReport_section* page_background = _report.find_section('B', 0); - if (page_background != NULL) - { - _delta = page_background->pos(); - print_section(*page_background); - _delta.reset(); - } - - if (_page == 1) - _delta.y += print_section('H', 1); - - TReport_section* page_head = _report.find_section('H', 0); - if (page_head != NULL && (_page > 1 || !page_head->hidden_if_needed())) - { - _delta += page_head->pos(); - _delta.y += print_section(*page_head); - _delta.x = 0; - } - - return ok; -} - -bool TReport_printer::close_page() -{ - if (_page_is_open) - { - TReport_section* page_foot = _report.find_section('F', 0); - if (page_foot != NULL && (!_is_last_page || !page_foot->hidden_if_needed())) - { - _delta.x = page_foot->pos().x; - _delta.y = _logical_foot_pos; - print_section(*page_foot); - } - } - return TPage_printer::close_page(); -} - -void TReport_printer::create_links(const TReport_section& rs) -{ - TAssoc_array* links = NULL; - for (int i = 0; i < rs.items(); i++) - { - const TReport_field& rf = rs.field(i); - if (rf.link().not_empty()) - { - if (links == NULL) - links = new TAssoc_array; - TToken_string tok(rf.link(), '.'); - TString table, field; - tok.get(0, table); tok.get(1, field); - TReport_link* rl = (TReport_link*)links->objptr(table); - if (rl == NULL) - { - rl = new TReport_link(table); - links->add(table, rl); - } - RCT rct; TWindow::log2dev(rf.get_rect(), rct); - rl->add_rect(rct); - rl->set(field, rf.get()); - } - } - if (links != NULL) - { - FOR_EACH_ASSOC_OBJECT((*links), h, key, l) - add_link((TReport_link*)l); - } -} - -long TReport_printer::print_section(TReport_section& rs) -{ - if (_print_aborted) - return 0; - - rs.load_fields(); - rs.execute_prescript(); - const long height = rs.compute_size().y; // Compute size after the initilization script! - - if (height > 0) // Has some visible fields - { - bool page_break = _page_break_allowed && rs.page_break(); - if (!page_break) - { - long h = height; - if (rs.keep_with_next()) - h += rs.report().section('B', 1).compute_size().y; - page_break = (_delta.y + h > _logical_foot_pos); - } - if (page_break && rs.level() > 0) // Avoid recursion - { - close_page(); - open_page(); - } - if (_page_is_open) - rs.draw(*this, preview_mode() ? rdm_print_preview : rdm_print); - - if (rs.level() > 0) // Ho stampa qualcosa che non sia lo sfondo! - _page_break_allowed = true; - } - - rs.execute_postscript(); - - if (_page_is_open && height > 0 && preview_mode()) - create_links(rs); - - return height; -} - -bool TReport_printer::print_loop() -{ - TRecordset* rex = _report.recordset(); - if (rex == NULL || rex->items() <= 0) - return false; - - const TPoint siz = page_size(); - const TPoint res = page_res(); - const double pollici_pagina_y = (double)siz.y / (double)res.y; - const double righe_pagina = pollici_pagina_y * _report.lpi(); - _logical_page_height = long(righe_pagina*100.0); - - const double pollici_pagina_x = (double)siz.x / (double)res.x; - const double colonne_pagina = pollici_pagina_x * _report.cpi(); - _logical_page_width = long(colonne_pagina*100.0); - - const TReport_section& footer = _report.section('F',0); - _logical_foot_pos = footer.pos().y; - if (_logical_foot_pos <= 0) - { - const long logical_footer_height = footer.compute_size().y; - _logical_foot_pos = _logical_page_height - logical_footer_height; - } - - _report.unmap_font(); // Gestire bene le riscalature - - TString_array oldgroup, newgroup; - const int max_group = _report.find_max_level('H'); - if (max_group >= 2) - { - for (int g = 2; g <= max_group; g++) - oldgroup.add(EMPTY_STRING, g); - } - const int max_body = _report.find_max_level('B'); - int last_body_height = 0; - - _is_last_page = false; - open_page(); - bool aborted = false; - for (bool ok = rex->move_to(0); ok; ok = rex->move_next()) - { - if (_pageto >= _pagefrom && _page > _pageto || _print_aborted) // out of range - { - aborted = true; - break; - } - - if (max_group >= 2) // Gestione raggruppamenti - { - int changed = 0; - TVariant var; - for (int g = 2; g <= max_group; g++) - { - const TString& expr = _report.section('H', g).grouped_by(); - _report.evaluate(expr, var, _alfafld); - const TString& grp = var.as_string(); - newgroup.add(grp, g); - if (newgroup.row(g) != oldgroup.row(g) || rex->current_row() == 0) - changed = g; - } - if (changed) - { - oldgroup = newgroup; - - if (_delta.x > 0) // Devo tornare a capo! - _delta.y += last_body_height; - _delta.x = 0; - - if (rex->current_row() > 0) - { - for (int g = 2; g <= changed; g++) - _delta.y += print_section('F', g); - } - for (int g = changed; g >= 2 ; g--) - _delta.y += print_section('H', g); - } - } - - for (int b = 1; b <= max_body; b++) - { - const int dy = print_section('B', b); - - int column_delta = 0; - // Cerco di vedere se e' possibile la stampa etichette - if (dy > 0) - { - const int dx = _report.section('B', b).size().x; - // Se dx > 0 ho una sezione a dimensione fissa - if (dx > 0 && _delta.x+2*dx <= _logical_page_width) - { - column_delta = dx; - last_body_height = dy; - } - } - if (column_delta > 0) - _delta.x += column_delta; - else - { - _delta.x = 0; - _delta.y += dy; - last_body_height = 0; // Non servirebbe strettamente - } - } - } - if (!aborted) - { - if (max_group >= 2) // Devo stampare tutte le code dei raggrupamenti - { - for (int g = 2; g <= max_group; g++) - _delta.y += print_section('F', g); - } - - if (rex->eof()) - print_section('F', 1); - _is_last_page = true; - close_page(); - } - _lastprinted = _page; - - return true; -} - -bool TReport_printer::print(bool preview_mode) -{ - bool ok = _report.execute_prescript(); - if (ok) - { - ok = TPage_printer::print(preview_mode); - if (ok) - _report.execute_postscript(); - } - return ok; -} - -bool TReport_printer::on_link(const TReport_link& lnk) -{ - return _report.on_link(lnk); -} - - -/////////////////////////////////////////////////////////// -// Remote control interface -/////////////////////////////////////////////////////////// - -void lock_preview_update(bool yes) -{ TPrint_preview_window::lock_preview_update(yes); } - -void abort_printing() -{ _print_aborted = true; } - diff --git a/ba/ba8303.h b/ba/ba8303.h deleted file mode 100755 index 37de28aca..000000000 --- a/ba/ba8303.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef __REPRINT_H -#define __REPRINT_H - -#ifndef __REPORT_H -#include "ba8302.h" -#endif - -class TPage_printer : public TWindow -{ - PRINT_RCD* _rcd; - long _pw, _ph, _phr, _pvr; // Printer width, height, horizontal and vertical resolution - TArray _links; - bool _links_sorted; - -protected: - word _copies, _pagefrom, _pageto, _page, _lastprinted; - bool _page_is_open, _draw_grid; - - TMask* _preview_mask; // owned object - TWindow* _preview_window; // referenced object - - virtual word pages() const { return 0; } - virtual bool print_loop() pure; - -private: - virtual TPoint dev2log(const PNT& p) const; // Never use this! - -protected: - virtual PNT log2dev(long lx, long ly) const; // Always override this! - - virtual const char* form_name() const; - virtual const char* font_name() const; - virtual int font_size() const; - virtual bool ask_pages(); - - virtual bool open_page(); - virtual bool close_page(); - bool page_in_range() const; - - // Called by print(bool) - virtual bool do_print(); - virtual bool do_preview(); - -public: - bool main_loop(); // Internal use only - virtual void print_page(word page); // Inefficient default implementation - - virtual TPoint page_size() const; - virtual TPoint page_res() const; - virtual word last_printed_page() { return _lastprinted; } - - virtual bool print(bool preview = false); - bool print_mode() const { return _preview_mask == NULL; } - bool preview_mode() const { return _preview_mask != NULL; } - - void toggle_preview_grid() { _draw_grid = !_draw_grid; } - bool show_preview_grid() const { return _draw_grid; } - - void add_link(TReport_link* link); - const TReport_link* find_link(const PNT& pnt) const; - virtual bool on_link(const TReport_link& lnk); - - TPage_printer(); - virtual ~TPage_printer(); -}; - -class TReport_printer : public TPage_printer -{ - TReport& _report; - TPoint _delta; - long _logical_page_height, _logical_page_width; - long _logical_foot_pos; - bool _is_last_page, _page_break_allowed; - -protected: - virtual const char* form_name() const; - virtual const char* font_name() const; - virtual int font_size() const; - - virtual PNT log2dev(long x, long y) const; - virtual bool print_loop(); - - virtual void draw_preview_page(); - virtual bool open_page(); - virtual bool close_page(); - long print_section(TReport_section& rs); - long print_section(char type, int level); - void create_links(const TReport_section& rs); - -public: - virtual bool print(bool preview = false); - virtual bool on_link(const TReport_link& lnk); - - TReport_printer(TReport& r) : _report(r) { } -}; - -void lock_preview_update(bool yes); -void abort_printing(); - -#endif diff --git a/ba/ba8304.cpp b/ba/ba8304.cpp deleted file mode 100755 index ffe7e6d82..000000000 --- a/ba/ba8304.cpp +++ /dev/null @@ -1,1271 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -#include "ba8303.h" -#include "ba8304.h" - -TVariant& TVariant_stack::peek(int depth) -{ - const int sp = _sp-depth-1; - return sp >= 0 ? (TVariant&)_var[sp] : NULL_VARIANT; -} - -bool TVariant_stack::drop() -{ - if (_sp > 0) - { - _sp--; - return true; - } - return false; -} - -TVariant& TVariant_stack::pop() -{ - TVariant& var = peek(0); - drop(); - return var; -} - -void TVariant_stack::roll(int depth) -{ - const int sp = _sp-depth-1; - if (sp >= 0) - { - TObject* var = _var.remove(sp, true); - _var.insert(var, _sp-1); - } -} - -void TVariant_stack::push(const TVariant& var) -{ - if (_var.objptr(_sp) == NULL) - _var.add(var, _sp); - else - (TVariant&)_var[_sp] = var; - _sp++; -} - -void TVariant_stack::push(long n) -{ - const TVariant var(n); - push(var); -} - -void TVariant_stack::push(const real& n) -{ - const TVariant var(n); - push(var); -} - -void TVariant_stack::push(const TString& str) -{ - const TVariant var(str); - push(var); -} - -void TVariant_stack::reset() -{ - _sp = 0; -} - -bool TVariant_stack::overflow() const -{ - return _sp > 2048; -} - -/////////////////////////////////////////////////////////// -// TAVM_op -/////////////////////////////////////////////////////////// - -enum AVM_opcode -{ - avm_nop, - avm_add, avm_and, - avm_begin, - avm_call_word, avm_cold, - avm_cmp_eq, avm_cmp_gt, avm_cmp_gteq, avm_cmp_lt, avm_cmp_lteq, avm_cmp_noteq, avm_cmp_nulleq, avm_cmp_zeroeq, - avm_div, avm_divide, avm_do, avm_dot, avm_drop, avm_dup, - avm_else, - avm_fetch, avm_forget, - avm_i, avm_if, avm_include, - avm_j, - avm_loop, - avm_mod, avm_mon, avm_mul, - avm_negate, avm_null, - avm_or, avm_over, - avm_perform, avm_pick, avm_plus_loop, avm_push, - avm_repeat, avm_rdrop, avm_rpeek, avm_rpush, avm_roll, avm_rot, - avm_strlen, avm_strmid, avm_store, avm_sub, avm_swap, - avm_then, avm_tok_fetch, avm_tok_store, - avm_until, avm_usrword, - avm_variable, - avm_warm, avm_while, - avm_zzz -}; - -const char* AVM_TOKENS[avm_zzz+1] = -{ - "$NOP$", - "+", "AND", - "BEGIN", - "$CALL_WORD$", "COLD", - "=", ">", ">=", "<", "<=", "<>", "NULL=", "0=", - "DIV", "/", "DO", ".", "DROP", "DUP", - "ELSE", - "@", "FORGET", - "I", "IF", "INCLUDE", - "J", - "LOOP", - "MOD", "MON", "*", - "NEGATE", "NULL", - "OR", "OVER", - "PERFORM", "PICK", "+LOOP", "PUSH", - "REPEAT", "R>", "R@", ">R", "ROLL", "ROT", - "STRLEN", "STRMID", "!", "-", "SWAP", - "THEN", "TOK@", "TOK!", - "UNTIL", "$USR$", - "VARIABLE", - "WARM", "WHILE" -}; - -enum TBreakpointType { brk_none = 0x0, brk_user = 0x1, brk_auto = 0x2 }; - -class TAVM_op : public TObject -{ - AVM_opcode _op; - TVariant _var; - int _break_pointer; - -public: - const TVariant& var() const { return _var; } - TVariant& var() { return _var; } - AVM_opcode op() const { return _op; } - bool has_break() const { return _break_pointer != brk_none; } - bool has_auto_break() const { return (_break_pointer & brk_auto) != 0; } - void set_user_break(bool on); - void set_auto_break(bool on); - - TAVM_op(AVM_opcode o, const TString& str); - TAVM_op(AVM_opcode o, const real& num); - TAVM_op(AVM_opcode o, const long num); - TAVM_op(const TAVM_op& op); - TAVM_op(AVM_opcode o); -}; - -void TAVM_op::set_user_break(bool on) -{ - _break_pointer = on ? brk_user : brk_none; -} - -void TAVM_op::set_auto_break(bool on) -{ - if (on) - _break_pointer |= brk_auto; - else - _break_pointer &= ~brk_auto; -} - - -TAVM_op::TAVM_op(AVM_opcode o, const TString& str) - : _op(o), _var(str), _break_pointer(0) -{ } - -TAVM_op::TAVM_op(AVM_opcode o, const real& num) - : _op(o), _var(num), _break_pointer(0) -{ } - -TAVM_op::TAVM_op(AVM_opcode o, const long num) - : _op(o), _var(num), _break_pointer(0) -{ } - -TAVM_op::TAVM_op(AVM_opcode o) - : _op(o), _break_pointer(0) -{ } - -TAVM_op::TAVM_op(const TAVM_op& op) : _op(op._op), _var(op._var), _break_pointer(0) -{ -} - -/////////////////////////////////////////////////////////// -// TAVM_monitor -/////////////////////////////////////////////////////////// - -class TAVM_list_window : public TField_window -{ - TBytecode* _bc; - int _ip; - const TString_array* _user_words; - -protected: - virtual void update(); - virtual void handler(WINDOW win, EVENT* ep); - -public: - void set_bytecode(const TBytecode* bc, int ip, const TString_array& uw); - TAVM_list_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner); -}; - -void TAVM_list_window::handler(WINDOW win, EVENT* ep) -{ - if (ep->type == E_MOUSE_DOWN) - { - const TPoint pt = dev2log(ep->v.mouse.where); - if (pt.x <= 5) - { - TAVM_op& op = *(TAVM_op*)_bc->objptr(pt.y-1); - op.set_user_break(ep->v.mouse.button == 0); - force_update(); - } - } - TField_window::handler(win, ep); -} - -void TAVM_list_window::update() -{ - clear(NORMAL_BACK_COLOR); - if (_bc != NULL) - { - autoscroll(false); - set_brush(DISABLED_BACK_COLOR); - bar(0, 0, columns()+1, 1); - bar(0, 0, 5, rows()+1); - set_brush(NORMAL_BACK_COLOR); - printat(0, 0, _bc->name()); - autoscroll(true); - - TString str; - int tab = 6; - - const int last = min(_bc->items(), rows()); - for (int i = 0; i < last; i++) - { - - const int y = i+1; - if (_ip == i) - { - set_brush(FOCUS_BACK_COLOR); - bar(0, y, 80, y+1); - set_brush(NORMAL_BACK_COLOR); - } - printat(0, y, "%04d", i); - const TAVM_op& op = *(const TAVM_op*)_bc->objptr(i); - const AVM_opcode co = op.op(); - const TVariant& var = op.var(); - - if (op.has_break()) - printat(4, y, "<"); - - if (co == avm_else || co == avm_then || - co == avm_loop || co == avm_plus_loop || - co == avm_repeat || co == avm_until) - tab -= 2; - if (co == avm_push) - { - if (var.is_string() && var.as_string()[0] != '#') - str.cut(0) << '"' << var.as_string() << '"'; - else - str = var.as_string(); - } else - if (co == avm_call_word) - { - str = var.as_string(); - } else - if (co == avm_usrword) - { - str = _user_words->row(var.as_int()); - str << " (#" << var.as_int() << ')'; - } - else - { - str = AVM_TOKENS[co]; - if (!var.is_null()) - str << " (" << var.as_string() << ')'; - } - printat(tab, y, str); - if (co == avm_if || co == avm_else || - co == avm_do || co == avm_begin || co == avm_while) - tab += 2; - } - } -} - -void TAVM_list_window::set_bytecode(const TBytecode* bc, int ip, const TString_array& uw) -{ - _bc = (TBytecode*)bc; - _ip = ip; - _user_words = &uw; - set_scroll_max(80, _bc->items() - rows()); -} - -TAVM_list_window::TAVM_list_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner) - : TField_window(x, y, dx, dy, parent, owner), _bc(NULL) -{ - autoscroll(true); -} - -class TAVM_stack_window : public TField_window -{ - TVariant_stack* _stack; - -protected: - virtual void update(); - -public: - void set_stack(TVariant_stack& s); - TAVM_stack_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner); -}; - -void TAVM_stack_window::update() -{ - clear(NORMAL_BACK_COLOR); - if (_stack != NULL) - { - for (int i = 0; i < _stack->items(); i++) - printat(0, i, _stack->peek(i).as_string()); - } -} - -void TAVM_stack_window::set_stack(TVariant_stack& s) -{ - _stack = &s; - set_scroll_max(80, s.items() - rows()); -} - -TAVM_stack_window::TAVM_stack_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner) - : TField_window(x, y, dx, dy, parent, owner), _stack(NULL) -{ - autoscroll(true); -} - -class TAVM_list_field : public TWindowed_field -{ -protected: - virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent); - -public: - TAVM_list_field(TMask* m) : TWindowed_field(m) { } - virtual ~TAVM_list_field() { } -}; - -TField_window* TAVM_list_field::create_window(int x, int y, int dx, int dy, WINDOW parent) -{ - return new TAVM_list_window(x, y, dx, dy, parent, this); -} - -class TAVM_stack_field : public TWindowed_field -{ -protected: - virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent); - -public: - TAVM_stack_field(TMask* m) : TWindowed_field(m) { } - virtual ~TAVM_stack_field() { } -}; - -TField_window* TAVM_stack_field::create_window(int x, int y, int dx, int dy, WINDOW parent) -{ - return new TAVM_stack_window(x, y, dx, dy, parent, this); -} - -class TAVM_monitor : public TAutomask -{ -protected: - TMask_field* parse_field(TScanner& scanner); - virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); - virtual bool on_key(KEY k); - -public: - TAVM_list_window& monitor() { return (TAVM_list_window&)((TAVM_list_field&)field(101)).win(); } - TAVM_stack_window& stacker() { return (TAVM_stack_window&)((TAVM_list_field&)field(102)).win(); } - TAVM_stack_window& rstacker() { return (TAVM_stack_window&)((TAVM_list_field&)field(103)).win(); } - TAVM_monitor(); -}; - -bool TAVM_monitor::on_field_event(TOperable_field& o, TField_event e, long jolly) -{ - return true; -} - -bool TAVM_monitor::on_key(KEY k) -{ - switch (k) - { - case K_F10: - case K_F11: - stop_run(k); - return true; - default: break; - } - return TAutomask::on_key(k); -} - -TMask_field* TAVM_monitor::parse_field(TScanner& scanner) -{ - if (scanner.token().starts_with("LI")) - return new TAVM_list_field(this); - if (scanner.token().starts_with("ST")) - return new TAVM_stack_field(this); - return TAutomask::parse_field(scanner); -} - -TAVM_monitor::TAVM_monitor() -{ - read_mask("ba8304", 0, -1); - set_handlers(); -} - - -/////////////////////////////////////////////////////////// -// TAVM -/////////////////////////////////////////////////////////// - -class TAVM -{ - TAlex_virtual_machine* _vm; - bool _interactive; - TString _last_error; - TVariant_stack _stack, _rstack; - const TBytecode* _bc; // Current word (or command line) - int _ip; // Current instruction pointer - ostream* _outstr; - - TAssoc_array _words; - TAssoc_array _vars; - TString_array _user_words; - TAVM_monitor _mon; - -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(); - int find_matching(const TBytecode& bytecode, AVM_opcode op1, AVM_opcode op2 = avm_nop) const; - void execute(const TAVM_op& op); - void do_call(const TString& func); - - const TString_array& get_user_words(); - int compile_user_word(const char* n); - -public: - const TString& get_last_error() const { return _last_error; } - - bool compile(istream& instr, TBytecode& bc); - bool execute(const TBytecode& bc, ostream* outstr = NULL); - void do_restart(bool cold); - bool do_include(const char* fname); - TVariant& do_fetch(const TString& name); - void do_store(const TString& name); - void set_interactive(bool inter) { _interactive = inter; } - bool defined(const char* w); - - TAVM(TAlex_virtual_machine* vm); - virtual ~TAVM(); -}; - -void TAVM::log_error(const char* str) -{ - _last_error = str; - if (_interactive) - error_box(str); -#ifdef DBG - else - statbar_set_title(TASK_WIN, str); -#endif -} - -bool TAVM::get_token(istream& instr, TString& str) const -{ - str.cut(0); - instr.eatwhite(); - if (instr.eof()) - return false; - char c; - instr.get(c); - str << c; - if (c == '"') - { - char* buf = str.get_buffer()+1; - const int bufsize = str.size()-1; - instr.getline(buf, bufsize, '"'); - str << '"'; - } - else - { - instr.get(c); - while (!isspace(c) && c != EOF) - { - str << c; - instr.get(c); - } - } - - return *str > ' '; -} - -#define ALEX_TOKENS 24 - - -AVM_opcode TAVM::token2opcode(const TString& str) const -{ - for (int i = 0; AVM_TOKENS[i] != NULL; i++) - { - if (str == AVM_TOKENS[i]) - return AVM_opcode(i); - } - - const TBytecode* bc =(const TBytecode*)_words.objptr(str); - if (bc != NULL) - return avm_call_word; - - return avm_nop; -} - -int TAVM::find_matching(const TBytecode& bytecode, AVM_opcode op1, AVM_opcode op2) const -{ - int i; - for (i = bytecode.last(); i >= 0; i--) - { - TAVM_op& theop = (TAVM_op&)bytecode[i]; - if ((theop.op() == op1 || theop.op() == op2) && theop.var().is_null()) - { - theop.var() = bytecode.items(); - break; - } - } - return i; -} - -const TString_array& TAVM::get_user_words() -{ - if (_user_words.items() == 0) - { - _user_words.add("***"); - _vm->get_usr_words(_user_words); - } - return _user_words; -} - -int TAVM::compile_user_word(const char* w) -{ - const TString_array& uw = get_user_words(); - const int i = uw.find(w); - return i > 0 ? i : 0; -} - -bool TAVM::compile(istream& instr, TBytecode& bytecode) -{ - TString str(256); - bytecode.destroy(); - while (get_token(instr, str)) - { - TAVM_op* op = NULL; - if (str[0] == '"') - { - str.rtrim(1); str.ltrim(1); - op = new TAVM_op(avm_push, str); - } else - if ((isdigit(str[0]) || (str[0]=='-')) && isdigit(str[str.len()-1])) - { - const real r(str); - op = new TAVM_op(avm_push, r); - } else - if (str[0] == '#') // User variable - { - op = new TAVM_op(avm_push, str); - } else - if (str == ":") // User word - { - if (get_token(instr, str)) - { - TBytecode* bc = new TBytecode; - bc->set_name(str); - _words.add(str, bc, true); - compile(instr, *bc); - op = new TAVM_op(avm_nop); - } - else - { - _last_error = "Missing word after :"; - log_error(_last_error); - return false; - } - } else - if (str == ";") - { - return true; - } else - if (str == "(") - { - TString256 str; - instr.getline(str.get_buffer(), str.size(), ')'); - op = new TAVM_op(avm_nop); - } else - if (str == "\\") - { - TString256 str; - instr.getline(str.get_buffer(), str.size()); - op = new TAVM_op(avm_nop); - } - else - { - const int oc = compile_user_word(str); - if (oc > 0) - op = new TAVM_op(avm_usrword, oc); - else - { - const AVM_opcode oc = token2opcode(str); - if (oc != avm_nop) - { - switch (oc) - { - case avm_else: - if (find_matching(bytecode, avm_if) < 0) - { - _last_error = "ELSE without matching IF"; - log_error(_last_error); - return false; - } - op = new TAVM_op(oc); - break; - case avm_then: - if (find_matching(bytecode, avm_if, avm_else) < 0) - { - _last_error = "THEN without matching IF"; - log_error(_last_error); - return false; - } - op = new TAVM_op(oc); - break; - case avm_loop: - case avm_plus_loop: - { - const do_pos = find_matching(bytecode, avm_do); - if (do_pos < 0) - { - _last_error.cut(0) << str << " without matching DO"; - log_error(_last_error); - return false; - } - op = new TAVM_op(oc, do_pos); - } - break; - case avm_repeat: - case avm_until: - { - const int begin_pos = find_matching(bytecode, avm_begin); - if (begin_pos < 0) - { - _last_error.cut(0) << str << " without matching BEGIN"; - log_error(_last_error); - return false; - } - find_matching(bytecode, avm_while); - op = new TAVM_op(oc, begin_pos); - } - break; - case avm_call_word: - { - const TBytecode* bc = (const TBytecode*)_words.objptr(str); - if (bc != NULL && bc->items() == 1) - { - const TAVM_op* inline_op = (const TAVM_op*)bc->objptr(0); - op = new TAVM_op(*inline_op); - } - else - op = new TAVM_op(oc, str); - } - break; - default: - op = new TAVM_op(oc); - break; - } - } - } - } - if (op != NULL) - { - if (op->op() != avm_nop) - bytecode.add(op); - else - delete op; - } - else - { - _last_error.cut(0) << "Unknown WORD: " << str; - log_error(_last_error); - return false; - } - } - return true; -} - -int TAVM::compare_tos_nos() -{ - const TVariant& tos = _stack.pop(); - const TVariant& nos = _stack.pop(); - return nos.compare(tos); -} - -void TAVM::do_call(const TString& func) -{ - if (_stack.overflow()) - { - log_error("Stack overflow"); - _bc = NULL; - return; - } - TBytecode* bc = (TBytecode*)_words.objptr(func); - if (bc != NULL) - { - _rstack.push(_bc->name()); - _rstack.push(_ip+1); - _ip = -1; // will be incremented! - _bc = bc; - } - else - { - _last_error = func; _last_error << " ?"; - log_error(_last_error); - _bc = NULL; - } -} - -bool TAVM::do_include(const char* fname) -{ - TFilename name = fname; - bool ok = name.custom_path(); - if (ok) - { - TBytecode bc; - ifstream inf(name); - ok = compile(inf, bc); - if (ok) - execute(bc); - } - return ok; -} - -// Mette sullo stack il valore della variabile name -TVariant& TAVM::do_fetch(const TString& name) -{ - if (name[0] == '#') - { - TVariant var; - _vm->get_usr_val(name, var); - _stack.push(var); - } - else - { - const TVariant* var = (const TVariant*)_vars.objptr(name); - if (var != NULL) - _stack.push(*var); - else - _stack.push(NULL_VARIANT); - } - return _stack.peek(); -} - -// Legge dallo stack il valore da asseganre alla variabile name -void TAVM::do_store(const TString& name) -{ - const TVariant& var = _stack.pop(); - if (name[0] == '#') - _vm->set_usr_val(name, var); - else - { - TVariant* v = (TVariant*)_vars.objptr(name); - if (v != NULL) - *v = var; - } -} - -bool TAVM::defined(const char* name) -{ - if (_words.objptr(name) != NULL) - return true; - - return compile_user_word(name) > 0; -} - -void TAVM::execute(const TAVM_op& op) -{ - switch(op.op()) - { - case avm_add : - { - const TVariant& v1 = _stack.pop(); - TVariant& v0 = (TVariant&)_stack.peek(); - v0.add(v1); - } - break; - case avm_and : - { - const TVariant& v1 = _stack.pop(); - TVariant& v0 = (TVariant&)_stack.peek(); - const long r = v0.as_int() & v1.as_int(); - v0.set(r); - } - break; - case avm_begin: break; - case avm_call_word: do_call(op.var().as_string()); break; - case avm_cold: do_restart(true); _bc = NULL; break; - case avm_cmp_eq : _stack.push(compare_tos_nos() == 0); break; - case avm_cmp_gt : _stack.push(compare_tos_nos() > 0); break; - case avm_cmp_gteq : _stack.push(compare_tos_nos() >= 0); break; - case avm_cmp_lt : _stack.push(compare_tos_nos() < 0); break; - case avm_cmp_lteq : _stack.push(compare_tos_nos() <= 0); break; - case avm_cmp_noteq: _stack.push(compare_tos_nos() != 0); break; - case avm_cmp_nulleq:_stack.push(_stack.pop().is_null()); break; - case avm_cmp_zeroeq:_stack.push(_stack.pop().is_zero()); break; - case avm_div: - { - const long r0 = _stack.pop().as_int(); - const long r1 = _stack.pop().as_int(); - if (r0 != 0) - { - const long n = r1 / r0; - _stack.push(n); - } - else - _stack.push(NULL_VARIANT); - } - - break; - case avm_divide: - { - const real& r0 = _stack.pop().as_real(); - const real& r1 = _stack.pop().as_real(); - if (!r0.is_zero()) - { - const real n = r1 / r0; - _stack.push(n); - } - else - _stack.push(NULL_VARIANT); - } - break; - case avm_do: - { - const TVariant& start = _stack.pop(); - const TVariant& limit = _stack.pop(); - if (start.compare(limit) < 0) - { - _rstack.push(limit); - _rstack.push(start); - } - else - _ip = op.var().as_int(); - } - break; - case avm_dot: - if (_outstr != NULL) - *_outstr << _stack.pop().as_string(); - break; - case avm_drop: - if (!_stack.drop()) - { - log_error("Stack underflow"); - _bc = NULL; - } - break; - case avm_dup: _stack.push(_stack.peek()); break; - case avm_else: - _ip = op.var().as_int(); - break; - case avm_fetch: do_fetch(_stack.pop().as_string()); break; - case avm_forget: - { - const TString& name = _stack.pop().as_string(); - _vars.remove(name); - _words.remove(name); - } - break; - case avm_i: _stack.push(_rstack.peek()); break; - case avm_if: - if (_stack.pop().is_zero()) - _ip = op.var().as_int(); - break; - case avm_include: do_include(_stack.pop().as_string()); break; - case avm_j: _stack.push(_rstack.peek(2)); break; - case avm_loop: - { - TVariant& start = _rstack.pop(); - const TVariant& limit = _rstack.pop(); - start.add(TVariant(UNO)); - _stack.push(limit); - _stack.push(start); - _ip = op.var().as_int()-1; - } - break; - case avm_mod: - { - const long i0 = _stack.pop().as_int(); - const long i1 = _stack.pop().as_int(); - _stack.push(i1 % i0); - } - break; - case avm_mon: - if (!_mon.is_open()) - _mon.open_modal(); - break; - case avm_mul: - { - const TVariant& v1 = _stack.pop(); - TVariant& v0 = (TVariant&)_stack.peek(); - const real m = v0.as_real() * v1.as_real(); - v0.set(m); - } - break; - case avm_negate: - { - TVariant& tos = _stack.peek(); - tos.set(~tos.as_int()); - } - break; - case avm_null: _stack.push(NULL_VARIANT); break; - case avm_or: - { - const TVariant& tos = _stack.pop(); - TVariant& nos = (TVariant&)_stack.peek(); - const long r = nos.as_int() | tos.as_int(); - nos.set(r); - } - break; - case avm_over: _stack.push(_stack.peek(1)); break; - case avm_perform: do_call(_stack.pop().as_string()); break; - case avm_pick: _stack.push(_stack.peek(_stack.pop().as_int())); break; - case avm_plus_loop: - { - TVariant& start = _rstack.pop(); - const TVariant& limit = _rstack.pop(); - start.add(_stack.pop()); - _stack.push(limit); - _stack.push(start); - _ip = op.var().as_int()-1; - } - break; - case avm_push: _stack.push(op.var()); break; - case avm_repeat: _ip = op.var().as_int(); break; - case avm_rdrop: _stack.push(_rstack.pop()); break; - case avm_rpeek: _stack.push(_rstack.peek()); break; - case avm_rpush: _rstack.push(_stack.pop()); break; - case avm_roll: _stack.roll(_stack.pop().as_int()); break; - case avm_rot: _stack.roll(2); break; - case avm_store: do_store(_stack.pop().as_string()); break; - case avm_strlen: _stack.push(_stack.peek().as_string().len()); break; - case avm_strmid: - { - const int len = _stack.pop().as_int(); - const int frm = _stack.pop().as_int(); - const TString& str = _stack.peek().as_string(); - _stack.push(str.mid(frm, len)); break; - } - break; - case avm_sub : - { - const TVariant& v1 = _stack.pop(); - TVariant& v0 = (TVariant&)_stack.peek(); - v0.sub(v1); - } - break; - case avm_swap: _stack.roll(1); break; - case avm_then: break; - case avm_tok_fetch: - { - const int pos = _stack.pop().as_int(); - const TString& name = _stack.pop().as_string(); - TVariant& var = do_fetch(name); - TToken_string str(var.as_string(), (char)0xB6); - const char* tok = str.get(pos); - var.set(tok); - } - break; - case avm_tok_store: - { - const int pos = _stack.pop().as_int(); - const TString& tok = _stack.pop().as_string(); - const TString name = _stack.pop().as_string(); - TVariant& var = do_fetch(name); - TToken_string str(var.as_string(), (char)0xB6); - str.add(tok, pos); - var.set(str); - do_store(name); - } - break; - case avm_until: - if (_stack.pop().is_zero()) - _ip = op.var().as_int(); - break; - case avm_usrword: - { - const long usrword = op.var().as_int(); - _vm->execute_usr_word(usrword, _stack); - } - break; - case avm_variable: _vars.add(_stack.pop().as_string(), NULL_VARIANT); break; - case avm_warm: do_restart(false); _bc = NULL; break; - case avm_while: _ip = op.var().as_int(); break; // Jump to BEGIN - default: - _last_error << "Unimplemented op code: " << op.op() << '\n'; - log_error(_last_error); - _bc = NULL; // force exit - break; - } -} - -bool TAVM::execute(const TBytecode& cmdline, ostream* outstr) -{ - const TBytecode* old_bc = _bc; - const int old_ip = _ip; - - _bc = &cmdline; - _ip = 0; - if (outstr != NULL) - _outstr = outstr; - while (_bc != NULL) - { - while (_ip >= _bc->items()) // Fine funzione - { - if (_rstack.items() >= 2) // Controllo il return stack - { - _ip = _rstack.pop().as_int(); - const TString& str = _rstack.pop().as_string(); - if (str == cmdline.name()) - _bc = &cmdline; - else - { - _bc = (const TBytecode*)_words.objptr(str); - if (_bc == NULL) - break; - } - } - else - { - _bc = NULL; - break; // Fine esecuzione - } - } - if (_bc == NULL || _ip > _bc->items()) - break; - - TAVM_op& op = *(TAVM_op*)_bc->objptr(_ip); - if (op.has_break() && !_mon.is_open()) - { - if (op.has_auto_break()) - op.set_auto_break(false); - _mon.open_modal(); - } - - if (_mon.is_open()) // Gestione debugger - { - lock_preview_update(true); - TAVM_list_window& monitor = _mon.monitor(); - monitor.set_bytecode(_bc, _ip, _user_words); - TAVM_stack_window& stacker = _mon.stacker(); - stacker.set_stack(_stack); - TAVM_stack_window& rstacker = _mon.rstacker(); - rstacker.set_stack(_rstack); - const KEY k = _mon.run(); - switch (k) - { - case K_F11: monitor.force_update(); stacker.force_update(); rstacker.force_update(); break; - case K_F10: - if (_ip < _bc->items()-1) - { - _mon.close_modal(); - TAVM_op& op = *(TAVM_op*)_bc->objptr(_ip+1); - op.set_auto_break(true); - } - break; - case K_QUIT: abort_printing(); - case K_F5 : _mon.close_modal(); lock_preview_update(false); break; - default: break; - } - } - - execute(op); - - _ip++; - } - - if (_mon.is_open()) // Chiudi debugger - { - _mon.close_modal(); - lock_preview_update(false); - } - - //const bool ok = _bc != NULL; // Not aborted - _bc = old_bc; - _ip = old_ip; - - return true; -} - -void TAVM::do_restart(bool cold) -{ - _stack.reset(); - _rstack.reset(); - if (cold) - { - _words.destroy(); - _vars.destroy(); - do_include("alex.alx"); - } -} - -TAVM::TAVM(TAlex_virtual_machine* vm) - : _vm(vm), _outstr(NULL), _interactive(false) -{ - do_restart(true); -} - -TAVM::~TAVM() -{ -} - -/////////////////////////////////////////////////////////// -// TAlex_virtual_machine -/////////////////////////////////////////////////////////// - -TAVM& TAlex_virtual_machine::avm() -{ - if (_avm == NULL) - _avm = new TAVM(this); - return *_avm; -} - -const TString& TAlex_virtual_machine::get_last_error() const -{ - if (_avm != NULL) - return _avm->get_last_error(); - return EMPTY_STRING; -} - -bool TAlex_virtual_machine::compile(istream& instr, TBytecode& bc) -{ - return avm().compile(instr, bc); -} - -bool TAlex_virtual_machine::execute(const TBytecode& bc, ostream& outstr) -{ - return avm().execute(bc, &outstr); -} - -bool TAlex_virtual_machine::compile(const char* cmd, TBytecode& bc) -{ - istrstream instr((char*)cmd, strlen(cmd)); - return compile(instr, bc); -} - -bool TAlex_virtual_machine::execute(const TBytecode& bc, TString& outs) -{ - char* buf = outs.get_buffer(); - memset(buf, 0, outs.size()); - ostrstream outstr(buf, outs.size()); - return execute(bc, outstr); -} - -void TAlex_virtual_machine::warm_restart() // Ripartenza a caldo -{ - avm().do_restart(false); -} - -void TAlex_virtual_machine::cold_restart() // Ripartenza a freddo -{ - avm().do_restart(true); -} - -bool TAlex_virtual_machine::get_usr_val(const TString& name, TVariant& var) const -{ - if (name.starts_with("#SYSTEM.")) - { - const TFixed_string n((const char*)name+8); - if (n == "ADMINISTATOR") - { - var.set(dongle().administrator()); - return true; - } - if (n == "CLOCK") - { - const long msec = clock() / (CLOCKS_PER_SEC / 1000); - var.set(msec); - return true; - } - if (n == "FIRM") - { - var.set(prefix().get_codditta()); - return true; - } - if (n == "STUDY") - { - var.set(firm2dir(-1)); - return true; - } - if (n == "DATE") - { - const TDate oggi(TODAY); - var.set(oggi); - return true; - } - if (n == "USER") - { - var.set(user()); - return true; - } - } - return false; -} - -bool TAlex_virtual_machine::set_usr_val(const TString& name, const TVariant& var) -{ - if (name.starts_with("#SYSTEM.")) - { - const TFixed_string n((const char*)name+8); - if (n == "FIRM") - { - return prefix().set_codditta(var.as_int()); - } - } - return false; -} - -unsigned int TAlex_virtual_machine::get_usr_words(TString_array&) const -{ - return 0; -} - -bool TAlex_virtual_machine::execute_usr_word(unsigned int opcode, TVariant_stack& stack) -{ - return false; -} - -bool TAlex_virtual_machine::include(const char* fname) -{ - return avm().do_include(fname); -} - -void TAlex_virtual_machine::set_interactive(bool inter) -{ avm().set_interactive(inter); } - -bool TAlex_virtual_machine::defined(const char* name) -{ - return avm().defined(name); -} - -TAlex_virtual_machine::TAlex_virtual_machine() : _avm(NULL) -{ -} - -TAlex_virtual_machine::~TAlex_virtual_machine() -{ - if (_avm != NULL) - delete _avm; -} - diff --git a/ba/ba8304.h b/ba/ba8304.h deleted file mode 100755 index 20f61b0a2..000000000 --- a/ba/ba8304.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef __ALEX_H -#define __ALEX_H - -#ifndef __RECORDSET_H -#include "ba8201.h" -#endif - -class TVariant_stack : public TObject -{ - TArray _var; - int _sp; - -public: - int items() const { return _sp; } - bool drop(); - TVariant& pop(); - TVariant& peek(int depth = 0); - void roll(int depth); - - void push(const TVariant& var); - void push(long n); - void push(const real& n); - void push(const TString& str); - void reset(); - bool overflow() const; - - TVariant_stack() : _sp(0) { } -}; - -// Generic bytecode for any language - -class TBytecode : public TArray -{ - TString _name; - -public: - void set_name(const char* name) { _name = name; } - const TString& name() const { return _name; } -}; - -// ALEX = Another Language EXtension - -class TAVM; - -class TAlex_virtual_machine : public TObject -{ - TAVM* _avm; // Chesire's cat class - -protected: - TAVM& avm(); - -public: - virtual size_t get_usr_words(TString_array& names) const; - virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); - 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); - bool compile(const char* cmd, TBytecode& bc); - bool execute(const TBytecode& bc, ostream& outstr); - bool execute(const TBytecode& bc, TString& outstr); - bool include(const char* fname); - void warm_restart(); - void cold_restart(); - void set_interactive(bool inter); - bool defined(const char* name); - - TAlex_virtual_machine(); - virtual ~TAlex_virtual_machine(); -}; - -#endif - diff --git a/ba/ba8400.cpp b/ba/ba8400.cpp index df64249e3..bf26f8d06 100755 --- a/ba/ba8400.cpp +++ b/ba/ba8400.cpp @@ -4,9 +4,8 @@ #include #include #include -#include +#include -#include "ba8302.h" #include "ba8400.h" /////////////////////////////////////////////////////////// @@ -83,12 +82,6 @@ void TFormer_mask::parse_field_line(const TString& line, TReport_field& rf) cons { if (fld.find("->") < 0) fld.insert("33->"); - if (fld.starts_with("33->")) - { - const TRectype doc(LF_DOC); - if (doc.type((const char*)fld + 4) == _nullfld) - fld.insert("G1:", 4); - } } rf.set_field(fld); } else diff --git a/ba/report.alx b/ba/report.alx index 28ef32e0f..6061fe47b 100755 --- a/ba/report.alx +++ b/ba/report.alx @@ -60,12 +60,12 @@ \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ : MESSAGE_ADD ( f1 -- ) - #THIS @ +! \ Incrementa f1 col contenuto del campo corrente + #THIS @ SWAP +! \ Incrementa f1 col contenuto del campo corrente ; : MESSAGE_ALIGN ( s1 -- ) "MESSAGE_ALIGN_" SWAP + \ Si crea il nome della funzione da chiamare - PERFORM + PERFORM \ Chiama MESSAGE_ALIGN_BOTTOM, ecc... ; : MESSAGE_COPY ( f1 -- ) @@ -93,7 +93,7 @@ ; : MESSAGE_PAGENO ( -- ) \ Numero di pagina corrente - #REPORT.PAGE @ THIS ! + #REPORT.PAGE @ #THIS ! ; : MESSAGE_RESET ( f1 -- ) diff --git a/ba/ve1100.alx b/ba/ve1100.alx index 85561d7db..c720a16b9 100755 --- a/ba/ve1100.alx +++ b/ba/ve1100.alx @@ -1,30 +1,46 @@ +\ Utility +: KILL_STACK + BEGIN + SP + WHILE + DROP + REPEAT +; + \ Messaggi specifici per stampa documenti : MESSAGE_CLIENTE - DROP + KILL_STACK ; : MESSAGE_DESCRIGA - #RDOC.DESCR @ - #RDOC.DESCLUNGA @ IF - #RDOC.DESCEST @ - + + #RDOC.DESCR @ \ Legge campo descrizione riga + #RDOC.DESCLUNGA @ \ Se e' presente una descrizione estesa + IF + #RDOC.DESCEST @ \ Legge memo descrizione + + \ Lo somma alla descrizione normale THEN - #THIS ! + BEGIN \ Ciclo sugli eventuali parametri successivi + SP 1 > \ Se lo stack e' ancora pieno + WHILE + " " + \ Somma uno spazio + SWAP @ + \ Somma campo successivo alla descrizione + REPEAT + #THIS ! \ Setta il campo corrente con la stringa risultante ; : MESSAGE_DITTA - DROP + KILL_STACK ; : MESSAGE_RIEPILOGOIVA - DROP + KILL_STACK ; : MESSAGE_SCADENZE - DROP + KILL_STACK ; : MESSAGE_TOTIMPONIBILI - DROP + KILL_STACK ;