Patch level : 2.1 nopatch

Files correlati     : ba0 ba8
Ricompilazione Demo : [ ]
Commento            :

ba0 aggiunto meccanismo di chiusura automatica in caso di installazione modulo sys
ba8 aggiunto converitore di form primordiale


git-svn-id: svn://10.65.10.50/trunk@12048 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2004-05-04 08:25:23 +00:00
parent 5e9712217e
commit 2b0291afdb
22 changed files with 1471 additions and 226 deletions

View File

@ -66,7 +66,6 @@ protected: // TApplication
protected: protected:
void deconnect_user(); void deconnect_user();
bool dll_changed() const;
virtual void main_loop(); virtual void main_loop();
void test_temp(); void test_temp();
@ -1021,7 +1020,7 @@ bool TMenu_application::test_programs()
user() = old_user; // Ripristino utente normale user() = old_user; // Ripristino utente normale
more = TRUE; // ricontrolla more = TRUE; // ricontrolla
if (dll_changed()) //costringe ad uscire dal programma se si e' installato il modulo SY if (sys_dll_changed()) //costringe ad uscire dal programma se si e' installato il modulo SY
return false; return false;
} }
_menu.set_dangerous_modules(dangerous); _menu.set_dangerous_modules(dangerous);
@ -1092,19 +1091,11 @@ void TMenu_application::deconnect_user()
} }
} }
bool TMenu_application::dll_changed() const
{
TString_array list;
list_files("*.ex_", list);
list_files("*.dl_", list);
return (list.items() > 0);
}
bool TMenu_application::destroy() bool TMenu_application::destroy()
{ {
deconnect_user(); deconnect_user();
if (dll_changed()) if (sys_dll_changed())
{ {
TExternal_app ba0close("ba0close.exe"); TExternal_app ba0close("ba0close.exe");
ba0close.run(TRUE,TRUE,TRUE); // run asynchronous... ba0close.run(TRUE,TRUE,TRUE); // run asynchronous...

View File

@ -12,6 +12,18 @@
#include "ba0101.h" #include "ba0101.h"
#include "ba0100.h" #include "ba0100.h"
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
bool sys_dll_changed()
{
TString_array list;
list_files("*.ex_", list);
list_files("*.dl_", list);
return list.items() > 0;
}
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// Menu management // Menu management
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -303,6 +315,10 @@ bool TMenuitem::perform_program() const
} }
} }
prefix().set("DEF"); // Aggiorna prefix prefix().set("DEF"); // Aggiorna prefix
const bool install_app = _action.starts_with("ba1 -6", TRUE) == 0;
if (install_app && sys_dll_changed())
main_app().stop_run();
} }
return ok; return ok;

View File

@ -168,5 +168,7 @@ public:
virtual ~TMenu(); virtual ~TMenu();
}; };
bool sys_dll_changed();
#endif #endif

View File

@ -8,6 +8,7 @@ int main(int argc, char** argv)
{ {
case 1: ba8200(argc, argv); break; // Query Generator case 1: ba8200(argc, argv); break; // Query Generator
case 2: ba8300(argc, argv); break; // Report Generator case 2: ba8300(argc, argv); break; // Report Generator
case 3: ba8400(argc, argv); break; // Form Converter
default: ba8100(argc, argv); break; // Record Selector default: ba8100(argc, argv); break; // Record Selector
} }
return 0; return 0;

View File

@ -1,5 +1,6 @@
int ba8100(int argc, char* argv[]); int ba8100(int argc, char* argv[]);
int ba8200(int argc, char* argv[]); int ba8200(int argc, char* argv[]);
int ba8300(int argc, char* argv[]); int ba8300(int argc, char* argv[]);
int ba8400(int argc, char* argv[]);

View File

@ -300,6 +300,7 @@ protected:
protected: protected:
bool add_file_to_tree(); bool add_file_to_tree();
void add_field_to_sheet(const char* fld, bool update);
void add_field_to_sheet(bool update = true); void add_field_to_sheet(bool update = true);
void add_asterisk_to_sheet(); void add_asterisk_to_sheet();
bool edit_file_in_tree(); bool edit_file_in_tree();
@ -311,7 +312,9 @@ protected:
void move_curr_field(int dir); void move_curr_field(int dir);
void tree2sql(TString& from, TString& where); void tree2sql(TString& from, TString& where);
void tree2isam(TString_array& a);
void sheet2sql(); void sheet2sql();
void sheet2isam();
void edit_query(); void edit_query();
bool select_query(); bool select_query();
@ -521,53 +524,64 @@ void TQuery_mask::fill_fields()
enable_field_buttons(); enable_field_buttons();
} }
// Aggiunge il campo selezionato nello spredasheet F_FIELDS allo spreadsheet F_SHEET // Aggiunge un cmapo allo spreadsheet F_SHEET
void TQuery_mask::add_field_to_sheet(bool update) void TQuery_mask::add_field_to_sheet(const char* fld, bool update)
{ {
const TRelation_node* n = curr_node(); const TRelation_node* n = curr_node();
if (n != NULL) if (n != NULL)
{ {
TSheet_field& sf = sfield(F_FIELDS); TSheet_field& ff = sfield(F_SHEET);
const int r = sf.selected(); TToken_string& row = ff.row(-1);
if (r >= 0) row = n->id();
row.add(fld);
_is_dirty = true;
if (update)
{ {
TToken_string& rowsel = sf.row(r); ff.force_update();
TSheet_field& ff = sfield(F_SHEET); enable_sql_button();
TToken_string& row = ff.row(-1);
row = n->id();
row.add(rowsel.get(0));
_is_dirty = true;
if (update)
{
ff.force_update();
enable_sql_button();
}
} }
} }
} }
// Aggiunge il campo selezionato nello spredasheet F_FIELDS allo spreadsheet F_SHEET
void TQuery_mask::add_field_to_sheet(bool update)
{
TSheet_field& sf = sfield(F_FIELDS);
const int r = sf.selected();
if (r >= 0)
{
TToken_string& rowsel = sf.row(r);
add_field_to_sheet(rowsel.get(0), update);
}
}
// Aggiunge tutte le colonne allo sheet // Aggiunge tutte le colonne allo sheet
void TQuery_mask::add_asterisk_to_sheet() void TQuery_mask::add_asterisk_to_sheet()
{ {
const TRelation_node* n = curr_node(); const TRelation_node* n = curr_node();
if (n != NULL) if (n != NULL)
{ {
TSheet_field& sf = sfield(F_FIELDS); if (yesno_box("Si desisdera aggiungere tutti i campi singolarmente?"))
const int nLast = sf.items()-1;
for (int i = 0; i <= nLast; i++)
{ {
sf.select(i); TSheet_field& sf = sfield(F_FIELDS);
add_field_to_sheet(i == nLast); const int nLast = sf.items()-1;
for (int i = 0; i <= nLast; i++)
{
sf.select(i);
add_field_to_sheet(i == nLast);
}
sf.select(0);
} }
sf.select(0); else
add_field_to_sheet("*", true);
} }
} }
// Decide se attivare o meno il bottone SQL // Decide se attivare o meno il bottone SQL
void TQuery_mask::enable_sql_button() void TQuery_mask::enable_sql_button()
{ {
const TSheet_field& s = sfield(F_SHEET); const bool yes = sfield(F_SHEET).items() > 0;
enable(F_GENSQL, s.items() > 0); enable(F_GENSQL, yes);
} }
// Decide se attivare o meno i bottoni di aggiunta campi // Decide se attivare o meno i bottoni di aggiunta campi
@ -637,6 +651,37 @@ void TQuery_mask::tree2sql(TString& from, TString& where)
} }
} }
static bool isam_tree_handler(TTree& tree, void* jolly, word flags)
{
TRelation_node* rn = (TRelation_node*)tree.curr_node();
TString_array* a = (TString_array*)jolly;
TToken_string row;
if (a->items() == 0)
{
row << "USE " << rn->name();
}
else
{
row << "JOIN " << rn->name();
if (rn->father()->name() != a->row(0).mid(4))
row << " TO " << rn->father()->name();
if (!rn->alias().blank())
row << " ALIAS " << rn->alias();
row << " INTO ";
FOR_EACH_ARRAY_ROW(rn->join(), i, r)
row << *r << ' ';
}
a->add(row);
return false;
}
// Riempie una stringa ISAM con la relazione tra le tabelle
void TQuery_mask::tree2isam(TString_array& a)
{
if (_tree.goto_root())
_tree.scan_depth_first(isam_tree_handler, &a);
}
inline bool tok_get_bool(TToken_string& tok, int pos) inline bool tok_get_bool(TToken_string& tok, int pos)
{ {
const char* str = tok.get(pos); const char* str = tok.get(pos);
@ -719,26 +764,43 @@ void TQuery_mask::sheet2sql()
fs.set_focusdirty(false); // Evita di scatenare eventi inutili fs.set_focusdirty(false); // Evita di scatenare eventi inutili
} }
static int select_callback(void* jolly, int argc, char** value, char** field) // Genera una query ISAM a partire dallo spreadsheet F_SHEET
void TQuery_mask::sheet2isam()
{ {
TArray_sheet* sht = (TArray_sheet*)jolly; TString_array rel;
TToken_string row; tree2isam(rel);
for (int i = 0; i < argc; i++)
row.add(value[i], i); TString use;
sht->add(row); FOR_EACH_ARRAY_ROW(rel, i, row)
return SQLITE_OK; {
use << *row << '\n';
}
set(F_SQL, use, true);
_sql_dirty = false;
TEdit_field& fs = efield(F_SQL);
fs.set_focusdirty(false); // Evita di scatenare eventi inutili
} }
void TQuery_mask::edit_query() void TQuery_mask::edit_query()
{ {
TSQL_recordset qry(get(F_SQL)); const TString& sql = get(F_SQL);
if (qry.columns() > 0) TRecordset* rex = NULL;
if (sql.starts_with("SELECT "))
rex = new TSQL_recordset(sql);
else
rex = new TISAM_recordset(sql);
if (rex->columns() > 0)
{ {
TRecordset_sheet sht(qry); TRecordset_sheet sht(*rex);
sht.run(); sht.run();
} }
else else
warning_box(TR("Nessuna riga risultato")); warning_box(TR("Nessuna riga risultato"));
delete rex;
} }
@ -785,11 +847,15 @@ bool TQuery_mask::get_qry_path(TFilename& path) const
const bool ok = name.not_empty(); const bool ok = name.not_empty();
if (ok) if (ok)
{ {
path = firm2dir(-1); path = name;
path.add("custom"); if (!path.is_absolute_path())
if (!path.exist()) {
xvt_fsys_mkdir(path); path = firm2dir(-1);
path.add(name); path.add("custom");
if (!path.exist())
xvt_fsys_mkdir(path);
path.add(name);
}
path.ext("qry"); path.ext("qry");
} }
return ok; return ok;
@ -1098,6 +1164,7 @@ bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
add_asterisk_to_sheet(); add_asterisk_to_sheet();
break; break;
case F_GENSQL: case F_GENSQL:
case F_GENISAM:
if (e == fe_button) if (e == fe_button)
{ {
next_page(1001); next_page(1001);
@ -1107,7 +1174,12 @@ bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
"annullando eventuali modifiche manuali.\n" "annullando eventuali modifiche manuali.\n"
"Si desidera proseguire?")); "Si desidera proseguire?"));
if (ok) if (ok)
sheet2sql(); {
if (o.dlg() == F_GENSQL)
sheet2sql();
else
sheet2isam();
}
} }
break; break;
case F_EDITQUERY: case F_EDITQUERY:
@ -1258,15 +1330,34 @@ TQuery_mask::TQuery_mask() : TAutomask("ba8200a"), _curr_num(0), _is_dirty(false
class TSQL_recordset_app : public TSkeleton_application class TSQL_recordset_app : public TSkeleton_application
{ {
TQuery_mask* _msk;
public: public:
virtual bool create();
virtual void main_loop(); virtual void main_loop();
virtual bool destroy();
}; };
bool TSQL_recordset_app::create()
{
_msk = new TQuery_mask;
xvt_sys_sleep(500);
return TSkeleton_application::create();
}
void TSQL_recordset_app::main_loop() void TSQL_recordset_app::main_loop()
{ {
TQuery_mask* msk = new TQuery_mask; _msk->run();
msk->run(); }
delete msk;
bool TSQL_recordset_app::destroy()
{
if (_msk != NULL)
{
delete _msk;
_msk = NULL;
}
return true;
} }
int ba8200(int argc, char* argv[]) int ba8200(int argc, char* argv[])

View File

@ -7,11 +7,12 @@
#define F_EDITFILE 302 #define F_EDITFILE 302
#define F_ASTERISK 303 #define F_ASTERISK 303
#define F_GENSQL 304 #define F_GENSQL 304
#define F_EDITQUERY 305 #define F_GENISAM 305
#define F_EXPORT_HTML 306 #define F_EDITQUERY 306
#define F_EXPORT_EXCEL 307 #define F_EXPORT_HTML 307
#define F_EXPORT_TXT 308 #define F_EXPORT_EXCEL 308
#define F_EXPORT_CAMPO 309 #define F_EXPORT_TXT 309
#define F_EXPORT_CAMPO 310
#define F_SHEET 400 #define F_SHEET 400
#define F_MOVEUP 401 #define F_MOVEUP 401
#define F_MOVEDN 402 #define F_MOVEDN 402

View File

@ -68,32 +68,38 @@ END
BUTTON F_ADDFILE 10 2 BUTTON F_ADDFILE 10 2
BEGIN BEGIN
PROMPT -15 11 "~Tabella" PROMPT -16 11 "~Tabella"
END END
BUTTON F_EDITFILE 10 2 BUTTON F_EDITFILE 10 2
BEGIN BEGIN
PROMPT -25 11 "~Edit" PROMPT -26 11 "~Edit"
PICTURE BMP_EDIT PICTURE BMP_EDIT
END END
BUTTON DLG_USER 10 2 BUTTON DLG_USER 10 2
BEGIN BEGIN
PROMPT -35 11 "~Campo" PROMPT -36 11 "~Campo"
GROUP 1 GROUP 1
END END
BUTTON F_ASTERISK 10 2 BUTTON F_ASTERISK 10 2
BEGIN BEGIN
PROMPT -45 11 "Campo ~*" PROMPT -46 11 "Campo ~*"
GROUP 1 GROUP 1
END END
BUTTON F_GENSQL 10 2 BUTTON F_GENSQL 10 2
BEGIN BEGIN
PROMPT -55 11 "~SQL" PROMPT -56 11 "~SQL"
END END
BUTTON F_GENISAM 10 2
BEGIN
PROMPT -66 11 "~ISAM"
END
SPREADSHEET F_SHEET -5 SPREADSHEET F_SHEET -5
BEGIN BEGIN
PROMPT 0 13 "" PROMPT 0 13 ""

View File

@ -11,6 +11,7 @@
#include <utility.h> #include <utility.h>
#include <xml.h> #include <xml.h>
#include <statbar.h>
#include "ba8201.h" #include "ba8201.h"
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -301,11 +302,19 @@ int TTable_names::logic_num(const TString& name)
if (str == NULL) if (str == NULL)
{ {
if (isdigit(name[0])) if (isdigit(name[0]))
add_file(atoi(name), name); else {
if (name[0] == '%') if (name.right(1) == '@')
add_file(LF_TABCOM, name); else add_file(-atoi(name), name);
if (name.len() == 3) else
add_file(LF_TAB, name); else add_file(atoi(name), name);
}
else
{
if (name[0] == '%')
add_file(LF_TABCOM, name); else
if (name.len() == 3)
add_file(LF_TAB, name);
}
str = (TString*)_names.objptr(name); str = (TString*)_names.objptr(name);
} }
@ -364,7 +373,7 @@ const TString& TRecordset::query_text() const
const TToken_string& TRecordset::sheet_head() const const TToken_string& TRecordset::sheet_head() const
{ {
TToken_string& head = get_tmp_string(); TToken_string head;
TToken_string tablefield(32, '.'); TToken_string tablefield(32, '.');
for (unsigned int c = 0; c < columns(); c++) for (unsigned int c = 0; c < columns(); c++)
{ {
@ -382,10 +391,14 @@ const TToken_string& TRecordset::sheet_head() const
maxlen = len; maxlen = len;
} }
head << '@' << max(ci._width, maxlen); head << '@' << max(ci._width, maxlen);
if (ci._type == _longfld || ci._type == _realfld) if (ci._type == _wordfld || ci._type == _intfld || ci._type == _longfld || ci._type == _realfld)
head << 'R'; head << 'R';
} }
return head;
// 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) bool TRecordset::save_as_html(const char* path)
@ -661,6 +674,65 @@ bool TRecordset::set_var(const char* name, const TVariant& var, bool create)
return ok; 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) bool ask_variable(const char* name, TVariant& var)
{ {
TMask m("Richiesta variabile", 1, 52, 4); TMask m("Richiesta variabile", 1, 52, 4);
@ -1054,13 +1126,6 @@ bool TSQLite::import(int logicnum)
return true; return true;
} }
bool is_var_separator(char c)
{
if (isspace(c))
return true;
return strchr("<=>,", c) != NULL;
}
bool TSQLite::parse_select_from(const char* szSql) bool TSQLite::parse_select_from(const char* szSql)
{ {
test_path(); test_path();
@ -1170,44 +1235,20 @@ static int query_get_items(void* jolly, int argc, char** values, char** columns)
return q->on_get_items(argc, values, columns); return q->on_get_items(argc, values, columns);
} }
void TSQL_recordset::parsed_sql_text(TString& sql) const
{
sql = _sql;
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 TSQL_recordset::ask_variables(bool all) bool TSQL_recordset::ask_variables(bool all)
{ {
_page.destroy(); const bool ok = TRecordset::ask_variables(all);
return TRecordset::ask_variables(all); if (ok)
_page.destroy();
return ok;
} }
TRecnotype TSQL_recordset::items() const TRecnotype TSQL_recordset::items() const
{ {
if (_items == 0) if (_items == 0)
{ {
TString sql; parsed_sql_text(sql); TString sql; parsed_text(sql);
TProfiler prof("SQL query");
_TheDataBase.exec("PRAGMA show_datatypes = ON;", NULL, NULL); _TheDataBase.exec("PRAGMA show_datatypes = ON;", NULL, NULL);
_TheDataBase.exec(sql, query_get_items, (TSQL_recordset*)this); _TheDataBase.exec(sql, query_get_items, (TSQL_recordset*)this);
_TheDataBase.exec("PRAGMA show_datatypes = OFF;", NULL, NULL); _TheDataBase.exec("PRAGMA show_datatypes = OFF;", NULL, NULL);
@ -1277,7 +1318,7 @@ bool TSQL_recordset::move_to(TRecnotype n)
if (n < _first_row || n >= _first_row+_page.items()) if (n < _first_row || n >= _first_row+_page.items())
{ {
TString sql; parsed_sql_text(sql); TString sql; parsed_text(sql);
if (sql.find("LIMIT ") < 0) if (sql.find("LIMIT ") < 0)
{ {
const int semicolon = sql.rfind(';'); const int semicolon = sql.rfind(';');
@ -1324,24 +1365,7 @@ void TSQL_recordset::set(const char* sql)
if (_sql.find("SELECT") >= 0 || _sql.find("select") >= 0) if (_sql.find("SELECT") >= 0 || _sql.find("select") >= 0)
{ {
_TheDataBase.parse_select_from(_sql); _TheDataBase.parse_select_from(_sql);
find_and_reset_vars();
// 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
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);
}
}
}
} }
} }
@ -1350,6 +1374,573 @@ TSQL_recordset::TSQL_recordset(const char* sql)
set(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* name) const
{
char* square = strchr(name, '[');
if (square != NULL) *square = '\0'; // Per il momento tronco il nome
const TRectype& rec = _relation->curr(logic);
const TFieldtypes ft = rec.type(name);
if (square != NULL) *square = '['; // Ripristino il nome
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 (square != NULL)
{
int from = 0, to = -1;
sscanf(square, "[%d,%d]", &from, &to);
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++;
}
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 // TRecordset_sheet
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -1378,3 +1969,60 @@ TRecordset_sheet::TRecordset_sheet(TRecordset& query)
: TSheet(-1, -1, -2, -4, "Query", query.sheet_head()), _query(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();
}

View File

@ -15,7 +15,7 @@
struct TRecordset_column_info : public TObject struct TRecordset_column_info : public TObject
{ {
TString _name; TString _name; // Table.Column
int _width; int _width;
TFieldtypes _type; TFieldtypes _type;
}; };
@ -93,6 +93,9 @@ protected:
bool save_as_silk(const char* path); bool save_as_silk(const char* path);
bool save_as_text(const char* path); bool save_as_text(const char* path);
bool save_as_campo(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 public: // Absolutely needed methods
virtual TRecnotype items() const pure; virtual TRecnotype items() const pure;
@ -161,6 +164,40 @@ public:
virtual ~TSQL_recordset() { } 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 // TRecordset_sheet
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -181,6 +218,18 @@ public:
// Utility // 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); bool select_custom_file(TFilename& path, const char* ext);
const TString& logic2table(int logic_num); const TString& logic2table(int logic_num);
int table2logic(const TString& name); int table2logic(const TString& name);

View File

@ -55,9 +55,9 @@ class TReport_base_mask : public TAutomask
{ {
TReport_font _font; TReport_font _font;
bool _font_changed; bool _font_changed;
TReport& _report;
protected: protected:
TReport& _report;
char _halign, _valign; char _halign, _valign;
COLOR _fgcolor, _bgcolor; COLOR _fgcolor, _bgcolor;
@ -239,6 +239,7 @@ void TReport_field_mask::vedo_non_vedo()
show(F_BGCOLOR, type != 'L'); show(F_BGCOLOR, type != 'L');
show(F_FONT_SELECT, is_text); show(F_FONT_SELECT, is_text);
show(F_SOURCE, (is_text || type == 'I') && type != 'T'); show(F_SOURCE, (is_text || type == 'I') && type != 'T');
show(DLG_FINDREC, field(F_SOURCE).active());
show(F_CODVAL, is_currency); // Codice valuta di riferimento show(F_CODVAL, is_currency); // Codice valuta di riferimento
show(F_LINK, strchr("DNS", type) != NULL); // Chi puo' essere un link? show(F_LINK, strchr("DNS", type) != NULL); // Chi puo' essere un link?
show(F_PRESCRIPT, is_text); show(F_PRESCRIPT, is_text);
@ -295,6 +296,39 @@ bool TReport_field_mask::on_field_event(TOperable_field& o, TField_event e, long
return error_box(TR("Specificare almeno due codici")); return error_box(TR("Specificare almeno due codici"));
} }
break; break;
case DLG_FINDREC:
if (e == fe_button)
{
TRecordset* rex = _report.recordset();
if (rex != NULL && rex->columns() > 0)
{
TArray_sheet sheet(-1, -1, -1, 20, "Colonne Query", "Nome@16|Tipo@8|Dimensoni@R");
TToken_string row;
for (size_t i = 0; i < rex->columns(); i++)
{
const TRecordset_column_info& info = rex->column_info(i);
row = info._name;
switch (info._type)
{
case _alfafld: row.add("Stringa"); break;
case _boolfld: row.add("Logico"); break;
case _datefld: row.add("Data"); break;
case _memofld: row.add("Memo"); break;
default : row.add("Numero"); break;
}
row.add(info._width);
sheet.add(row);
}
if (sheet.run() == K_ENTER)
{
row = sheet.row(-1);
set(F_SOURCE, row.get(0));
}
}
else
warning_box("Query non definita");
}
break;
default: default:
break; break;
} }
@ -716,11 +750,15 @@ bool TReport_mask::get_rep_path(TFilename& path) const
const bool ok = name.not_empty(); const bool ok = name.not_empty();
if (ok) if (ok)
{ {
path = firm2dir(-1); path = name;
path.add("custom"); if (!path.is_absolute_path())
if (!path.exist()) {
xvt_fsys_mkdir(path); path = firm2dir(-1);
path.add(name); path.add("custom");
if (!path.exist())
xvt_fsys_mkdir(path);
path.add(name);
}
path.ext("rep"); path.ext("rep");
} }
return ok; return ok;
@ -826,6 +864,7 @@ void TReport_mask::add_field()
{ {
TReport_section& rs = curr_section(); TReport_section& rs = curr_section();
TReport_field* rf = new TReport_field(&rs); TReport_field* rf = new TReport_field(&rs);
rf->set_pos(0, rs.compute_size().y);
TReport_field_mask m(*rf); TReport_field_mask m(*rf);
m.disable(DLG_DELREC); m.disable(DLG_DELREC);
if (m.run() == K_ENTER) if (m.run() == K_ENTER)
@ -1062,12 +1101,23 @@ bool TReport_mask::on_field_event(TOperable_field& o, TField_event e, long jolly
case F_SHOW_QRY: case F_SHOW_QRY:
if (e == fe_button) if (e == fe_button)
{ {
TSQL_recordset qry(get(F_SQL)); TRecordset* rex = NULL;
if (qry.columns() > 0)
const TString& sql = get(F_SQL);
if (sql.starts_with("SELECT "))
rex = new TSQL_recordset(sql);
else
rex = new TISAM_recordset(sql);
if (rex->columns() > 0)
{ {
TRecordset_sheet sheet(qry); TRecordset_sheet sht(*rex);
sheet.run(); sht.run();
} }
else
warning_box(TR("Nessuna riga risultato"));
delete rex;
} }
break; break;
case DLG_PRINT: case DLG_PRINT:
@ -1146,8 +1196,13 @@ class TReporter_app : public TSkeleton_application
TReport_mask* _msk; TReport_mask* _msk;
protected: protected:
virtual void print(); virtual bool create();
virtual void main_loop(); virtual void main_loop();
virtual bool destroy();
virtual void print();
public:
TReporter_app() : _msk(NULL) { }
}; };
void TReporter_app::print() void TReporter_app::print()
@ -1156,12 +1211,26 @@ void TReporter_app::print()
_msk->on_print(); _msk->on_print();
} }
void TReporter_app::main_loop() bool TReporter_app::create()
{ {
_msk = new TReport_mask; _msk = new TReport_mask;
xvt_sys_sleep(500);
return TSkeleton_application::create();
}
bool TReporter_app::destroy()
{
if (_msk != NULL)
{
delete _msk;
_msk = NULL;
}
return true;
}
void TReporter_app::main_loop()
{
_msk->run(); _msk->run();
delete _msk;
_msk = NULL;
} }
int ba8300(int argc, char* argv[]) int ba8300(int argc, char* argv[])

View File

@ -89,6 +89,12 @@ BEGIN
PROMPT 1 10 "@bSorgente" PROMPT 1 10 "@bSorgente"
END END
BUTTON DLG_FINDREC 10 2
BEGIN
PROMPT -33, 9 ""
PICTURE BMP_FINDREC
END
BUTTON DLG_CANCEL 10 2 BUTTON DLG_CANCEL 10 2
BEGIN BEGIN
PROMPT -13 -1 "" PROMPT -13 -1 ""

View File

@ -392,7 +392,7 @@ bool TReport_window::get_selection_rect(TRectangle& rct) const
const TReport_field& f = *(const TReport_field*)o; const TReport_field& f = *(const TReport_field*)o;
if (f.selected()) if (f.selected())
{ {
const TRectangle& fr = f.get_rect(); const TRectangle fr = f.get_draw_rect();
if (!full) if (!full)
{ {
rct = fr; rct = fr;

View File

@ -495,7 +495,7 @@ TPoint TReport_section::compute_size() const
const TReport_field& rf = field(i); const TReport_field& rf = field(i);
if (rf.shown()) if (rf.shown())
{ {
const TRectangle& r = rf.get_rect(); const TRectangle r = rf.get_draw_rect();
if (_size.x <= 0 && r.right() > s.x) // Richiesto calcolo larghezza if (_size.x <= 0 && r.right() > s.x) // Richiesto calcolo larghezza
s.x = r.right(); s.x = r.right();
if (_size.y <= 0 && r.bottom() > s.y) // Richiesto calcolo altezza if (_size.y <= 0 && r.bottom() > s.y) // Richiesto calcolo altezza
@ -677,7 +677,8 @@ TString& TReport_script::translate_message() const
{ {
TToken_string source(_src, '\n'); TToken_string source(_src, '\n');
TToken_string line(256, '|'); TToken_string line(256, '|');
TString cmd, arg, fld; TToken_string args(256, ',');
TString cmd, fld;
TString& alex = get_tmp_string(); TString& alex = get_tmp_string();
FOR_EACH_TOKEN(source, srcrow) FOR_EACH_TOKEN(source, srcrow)
{ {
@ -699,26 +700,29 @@ TString& TReport_script::translate_message() const
if (comma > 0) if (comma > 0)
{ {
cmd = msg.left(comma); cmd = msg.left(comma);
arg = msg.mid(comma+1); args = msg.mid(comma+1);
fld = arg; fld = args.get(0);
if (fld[0] != '#') if (fld[0] != '#')
fld.insert("#", 0); fld.insert("#", 0);
fld.insert("REPORT.", 1);
} }
else else
{ {
cmd = msg; cmd = msg;
arg.cut(0); args.cut(0);
fld.cut(0); fld.cut(0);
} }
if (cmd.starts_with("AL")) // ALIGN
{
alex << fld << " ALIGN_FIELD_" << args.get(1) << ' ';
} else
if (cmd.starts_with("CO")) // COPY if (cmd.starts_with("CO")) // COPY
{ {
alex << "#REPORT.THIS @ " << fld << " ! "; alex << "#THIS @ " << fld << " ! ";
} else } else
if (cmd.starts_with("AD")) // ADD if (cmd.starts_with("AD")) // ADD
{ {
alex << "#REPORT.THIS @ " << fld << " @ + "<< fld << " ! "; alex << "#THIS @ " << fld << " @ + "<< fld << " ! ";
} else } else
if (cmd.starts_with("IN")) // INC if (cmd.starts_with("IN")) // INC
{ {
@ -867,6 +871,51 @@ void TReport_field::offset(const TPoint& pt)
_rct.y += pt.y; _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 const TReport_font& TReport_field::font() const
{ {
return _font != NULL ? *_font : _section->font(); return _font != NULL ? *_font : _section->font();
@ -1010,6 +1059,8 @@ bool TReport_field::load_field()
else else
_var.set_null(); _var.set_null();
} }
compute_draw_rect();
return ok; return ok;
} }
@ -1039,7 +1090,7 @@ COLOR TReport_field::link_color() const
void TReport_field::draw_text(TWindow& win, const char* text, TReport_draw_mode rdm) const void TReport_field::draw_text(TWindow& win, const char* text, TReport_draw_mode rdm) const
{ {
const TRectangle& rct = get_rect(); const TRectangle& rct = get_draw_rect();
RCT r; win.log2dev(rct, r); RCT r; win.log2dev(rct, r);
advanced_draw_rect(win, r, border(), fore_color(), back_color()); advanced_draw_rect(win, r, border(), fore_color(), back_color());
@ -1176,6 +1227,9 @@ void TReport_field::draw(TWindow& win, TReport_draw_mode rdm) const
if (rdm != rdm_edit && hidden()) if (rdm != rdm_edit && hidden())
return; return;
if (rdm == rdm_edit)
compute_draw_rect();
PAT_STYLE back_pattern = PAT_HOLLOW; PAT_STYLE back_pattern = PAT_HOLLOW;
if (rdm == rdm_edit) if (rdm == rdm_edit)
{ {
@ -1251,7 +1305,7 @@ void TReport_field::draw(TWindow& win, TReport_draw_mode rdm) const
{ {
if (border() <= 0) // Rendi piu' visibile il bordo dei campi che non ce l'hanno if (border() <= 0) // Rendi piu' visibile il bordo dei campi che non ce l'hanno
{ {
RCT r; win.log2dev(get_rect(), r); RCT r; win.log2dev(get_draw_rect(), r);
advanced_draw_rect(win, r, 1, COLOR_LTGRAY, COLOR_WHITE); advanced_draw_rect(win, r, 1, COLOR_LTGRAY, COLOR_WHITE);
} }
if (id() > 0) if (id() > 0)
@ -1378,6 +1432,7 @@ bool TReport_field::load(const TXmlItem& fld)
set_row(get_num_attr(fld, "y")); set_row(get_num_attr(fld, "y"));
set_width(get_num_attr(fld, "width")); set_width(get_num_attr(fld, "width"));
set_height(get_num_attr(fld, "height", 100)); set_height(get_num_attr(fld, "height", 100));
_rct_draw = _rct;
show(!fld.GetBoolAttr("hidden")); show(!fld.GetBoolAttr("hidden"));
activate(!fld.GetBoolAttr("deactivated")); activate(!fld.GetBoolAttr("deactivated"));
hide_zeroes(fld.GetBoolAttr("zeroes_hidden")); hide_zeroes(fld.GetBoolAttr("zeroes_hidden"));
@ -1461,6 +1516,7 @@ TReport_field::TReport_field(TReport_section* sec)
{ {
set_pos(0,0); set_pos(0,0);
set_size(1600,100); set_size(1600,100);
_rct_draw = _rct;
} }
TReport_field::TReport_field(const TReport_field& rf) : _font(NULL) TReport_field::TReport_field(const TReport_field& rf) : _font(NULL)
@ -1592,8 +1648,10 @@ bool TReport::set_recordset(TRecordset* rs)
bool TReport::set_recordset(const TString& sql) bool TReport::set_recordset(const TString& sql)
{ {
bool ok = false; bool ok = false;
if (sql.compare("SELECT", 6, true) == 0) if (sql.compare("SELECT ", 7, true) == 0)
ok = set_recordset(new TSQL_recordset(sql)); ok = set_recordset(new TSQL_recordset(sql));
else
ok = set_recordset(new TISAM_recordset(sql));
return ok; return ok;
} }
@ -1952,16 +2010,17 @@ bool TReport::set_usr_val(const TString& name, const TVariant& var)
return TAlex_virtual_machine::set_usr_val(name, var); return TAlex_virtual_machine::set_usr_val(name, var);
} }
unsigned int TReport::compile_usr_word(const TString& name) const size_t TReport::get_usr_words(TString_array& words) const
{ {
const int words = 10; const char* const name[] =
const char* const names[words] = { NULL, "DISABLE", "ENABLE", "GET_SIZE", "HIDE", {
"RUN_FORM", "SET_BACK_COLOR", "SET_FORE_COLOR", "***", "DISABLE", "ENABLE", "GET_POS",
"SET_SIZE", "SHOW" }; "GET_SIZE", "HIDE", "RUN_FORM", "SET_BACK_COLOR", "SET_FORE_COLOR",
int i; "SET_POS", "SET_SIZE", "SHOW", NULL
for (i = words-1; i > 0; i--) };
if (name == names[i]) size_t i;
break; for (i = 0; name[i] != NULL; i++)
words.add(name[i]);
return i; return i;
} }
@ -1971,10 +2030,16 @@ static void do_show(TReport_field& rf, void* jolly)
static void do_enable(TReport_field& rf, void* jolly) static void do_enable(TReport_field& rf, void* jolly)
{ rf.activate(jolly != NULL); } { 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) static void do_set_size(TReport_field& rf, void* jolly)
{ {
const TPoint& pt = *(const TPoint*)jolly; const TPoint& pt = *(const TPoint*)jolly;
rf.set_size(pt.x, pt.y); rf.set_draw_size(pt.x, pt.y);
} }
static void do_set_back_color(TReport_field& rf, void* jolly) static void do_set_back_color(TReport_field& rf, void* jolly)
@ -2082,47 +2147,70 @@ bool TReport::execute_usr_word(unsigned int opcode, TVariant_stack& stack)
{ {
switch (opcode) switch (opcode)
{ {
case 1: // DISABLE case 1: // Placeholder
break;
case 2: // DISABLE
do_message(stack.pop(), do_enable, NULL); do_message(stack.pop(), do_enable, NULL);
break; break;
case 2: // ENABLE case 3: // ENABLE
do_message(stack.pop(), do_enable, (void*)1); do_message(stack.pop(), do_enable, (void*)1);
break; break;
case 3: // GET_SIZE 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()); const TReport_field* fld = field(stack.pop().as_string());
real w, h; real w, h;
if (fld != NULL) if (fld != NULL)
{ {
const TRectangle& r = fld->get_rect(); const TRectangle& r = fld->get_draw_rect();
w = r.width() / CENTO; h = r.height() / CENTO; w = r.width() / CENTO; h = r.height() / CENTO;
} }
stack.push(w); stack.push(h); stack.push(w); stack.push(h);
} }
break; break;
case 4: // HIDE case 6: // HIDE
do_message(stack.pop(), do_show, NULL); do_message(stack.pop(), do_show, NULL);
break; break;
case 5: // RUN_FORM case 7: // RUN_FORM
{ {
const TString& msk = stack.pop().as_string(); const TString& msk = stack.pop().as_string();
const KEY key = run_form(msk); const KEY key = run_form(msk);
stack.push(key); stack.push(key);
} }
break; break;
case 6: // SET_BACK_COLOR case 8: // SET_BACK_COLOR
{ {
const COLOR rgb = stack.pop().as_color(); const COLOR rgb = stack.pop().as_color();
do_message(stack.pop(), do_set_back_color, (void*)rgb); do_message(stack.pop(), do_set_back_color, (void*)rgb);
} }
break; break;
case 7: // SET_FORE_COLOR case 9: // SET_FORE_COLOR
{ {
const COLOR rgb = stack.pop().as_color(); const COLOR rgb = stack.pop().as_color();
do_message(stack.pop(), do_set_fore_color, (void*)rgb); do_message(stack.pop(), do_set_fore_color, (void*)rgb);
} }
break; break;
case 8: // SET_SIZE 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 TVariant& fld = stack.pop();
const real h = stack.pop().as_real() * CENTO; const real h = stack.pop().as_real() * CENTO;
@ -2131,7 +2219,7 @@ bool TReport::execute_usr_word(unsigned int opcode, TVariant_stack& stack)
do_message(fld, do_set_size, (void*)&sz); do_message(fld, do_set_size, (void*)&sz);
} }
break; break;
case 9: // SHOW case 12: // SHOW
do_message(stack.pop(), do_show, (void*)1); do_message(stack.pop(), do_show, (void*)1);
break; break;
default: default:
@ -2161,9 +2249,9 @@ bool TReport::on_link(const TReport_link& lnk)
TReport::TReport() : _lpi(6), _recordset(NULL), _curr_field(NULL) TReport::TReport() : _lpi(6), _recordset(NULL), _curr_field(NULL)
{ {
// Brutte inizializzazioni, ma inevitabili
_expressions.set_report(this); _expressions.set_report(this);
fload("report.alx");
_prescript.set_description("PRESCRIPT"); _prescript.set_description("PRESCRIPT");
_postscript.set_description("POSTSCRIPT"); _postscript.set_description("POSTSCRIPT");
} }

View File

@ -226,7 +226,7 @@ class TReport_field : public TSortable
TReport_section* _section; TReport_section* _section;
int _id; int _id;
char _type; // Text, String, Numeric, Price, Valuta, Date, Line, Rectangle, Image char _type; // Text, String, Numeric, Price, Valuta, Date, Line, Rectangle, Image
TRectangle _rct; // In centesimi TRectangle _rct, _rct_draw; // In centesimi
COLOR _fgcolor, _bgcolor; COLOR _fgcolor, _bgcolor;
short _border; short _border;
char _halign, _valign; char _halign, _valign;
@ -246,6 +246,7 @@ protected:
TFieldtypes var_type() const; TFieldtypes var_type() const;
const TString& formatted_text() const; const TString& formatted_text() const;
void get_currency(TCurrency& cur) const; void get_currency(TCurrency& cur) const;
void compute_draw_rect() const;
public: public:
virtual TObject* dup() const { return new TReport_field(*this); } virtual TObject* dup() const { return new TReport_field(*this); }
@ -288,6 +289,10 @@ public:
void set_width(long dx) { _rct.set_width(dx); } void set_width(long dx) { _rct.set_width(dx); }
void set_height(long dy) { _rct.set_height(dy); } void set_height(long dy) { _rct.set_height(dy); }
const TRectangle& get_rect() const { return _rct; } 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 hidden() const { return _hidden; }
bool shown() const { return !hidden(); } bool shown() const { return !hidden(); }
@ -382,7 +387,7 @@ class TReport : public TAlex_virtual_machine
protected: protected:
virtual const char* class_name() const { return "Report"; } virtual const char* class_name() const { return "Report"; }
virtual unsigned int compile_usr_word(const TString& name) const; virtual size_t get_usr_words(TString_array& words) const;
virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack);
virtual bool get_usr_val(const TString& name, TVariant& var) const; virtual bool get_usr_val(const TString& name, TVariant& var) const;
virtual bool set_usr_val(const TString& name, const TVariant& var); virtual bool set_usr_val(const TString& name, const TVariant& var);

View File

@ -515,6 +515,7 @@ bool TPage_printer::do_preview()
set_win(_preview_window->win()); set_win(_preview_window->win());
_pagefrom = _pageto = _page = 1; _pagefrom = _pageto = _page = 1;
_print_aborted = false; _print_aborted = false;
const KEY key = _preview_mask->run(); const KEY key = _preview_mask->run();
set_win(NULL_WIN); set_win(NULL_WIN);

View File

@ -86,8 +86,8 @@ enum AVM_opcode
avm_begin, avm_begin,
avm_call_word, avm_cold, 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_eq, avm_cmp_gt, avm_cmp_gteq, avm_cmp_lt, avm_cmp_lteq, avm_cmp_noteq,
avm_div, avm_do, avm_dot, avm_drop, avm_dup, avm_div, avm_divide, avm_do, avm_dot, avm_drop, avm_dup,
avm_else, avm_execute, avm_else,
avm_false, avm_fetch, avm_fload, avm_false, avm_fetch, avm_fload,
avm_i, avm_if, avm_i, avm_if,
avm_j, avm_j,
@ -95,8 +95,8 @@ enum AVM_opcode
avm_mod, avm_mon, avm_mul, avm_mod, avm_mon, avm_mul,
avm_negate, avm_negate,
avm_or, avm_over, avm_or, avm_over,
avm_pick, avm_plus_loop, avm_push, avm_perform, avm_pick, avm_plus_loop, avm_push,
avm_repeat, avm_rdrop, avm_rpeek, avm_rpush, avm_rot, avm_repeat, avm_rdrop, avm_rpeek, avm_rpush, avm_roll, avm_rot,
avm_store, avm_sub, avm_swap, avm_store, avm_sub, avm_swap,
avm_then, avm_true, avm_then, avm_true,
avm_until, avm_usrword, avm_until, avm_usrword,
@ -111,8 +111,8 @@ const char* AVM_TOKENS[avm_zzz+1] =
"BEGIN", "BEGIN",
"$CALL_WORD$", "COLD", "$CALL_WORD$", "COLD",
"=", ">", ">=", "<", "<=", "<>", "=", ">", ">=", "<", "<=", "<>",
"/", "DO", ".", "DROP", "DUP", "DIV", "/", "DO", ".", "DROP", "DUP",
"ELSE", "EXECUTE", "ELSE",
"FALSE", "@", "FLOAD", "FALSE", "@", "FLOAD",
"I", "IF", "I", "IF",
"J", "J",
@ -120,8 +120,8 @@ const char* AVM_TOKENS[avm_zzz+1] =
"MOD", "MON", "*", "MOD", "MON", "*",
"NEGATE", "NEGATE",
"OR", "OVER", "OR", "OVER",
"PICK", "+LOOP", "PUSH", "PERFORM", "PICK", "+LOOP", "PUSH",
"REPEAT", "R>", "R@", ">R", "ROT", "REPEAT", "R>", "R@", ">R", "ROLL", "ROT",
"!", "-", "SWAP", "!", "-", "SWAP",
"THEN", "TRUE", "THEN", "TRUE",
"UNTIL", "#", "UNTIL", "#",
@ -189,13 +189,14 @@ class TAVM_list_window : public TField_window
{ {
TBytecode* _bc; TBytecode* _bc;
int _ip; int _ip;
const TString_array* _user_words;
protected: protected:
virtual void update(); virtual void update();
virtual void handler(WINDOW win, EVENT* ep); virtual void handler(WINDOW win, EVENT* ep);
public: public:
void set_bytecode(const TBytecode* bc, int ip); 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); TAVM_list_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner);
}; };
@ -263,6 +264,11 @@ void TAVM_list_window::update()
if (co == avm_call_word) if (co == avm_call_word)
{ {
str = var.as_string(); str = var.as_string();
} else
if (co == avm_usrword)
{
str = _user_words->row(var.as_int());
str << " (#" << var.as_int() << ')';
} }
else else
{ {
@ -278,10 +284,11 @@ void TAVM_list_window::update()
} }
} }
void TAVM_list_window::set_bytecode(const TBytecode* bc, int ip) void TAVM_list_window::set_bytecode(const TBytecode* bc, int ip, const TString_array& uw)
{ {
_bc = (TBytecode*)bc; _bc = (TBytecode*)bc;
_ip = ip; _ip = ip;
_user_words = &uw;
set_scroll_max(80, _bc->items() - rows()); set_scroll_max(80, _bc->items() - rows());
} }
@ -403,6 +410,7 @@ class TAVM
ostream* _outstr; ostream* _outstr;
TAssoc_array _words; TAssoc_array _words;
TString_array _user_words;
TAVM_monitor _mon; TAVM_monitor _mon;
protected: protected:
@ -413,7 +421,9 @@ protected:
int find_matching(const TBytecode& bytecode, AVM_opcode op1, AVM_opcode op2 = avm_nop) const; int find_matching(const TBytecode& bytecode, AVM_opcode op1, AVM_opcode op2 = avm_nop) const;
void execute(const TAVM_op& op); void execute(const TAVM_op& op);
void do_call(const TString& func); void do_call(const TString& func);
void do_fload(const char* fname);
const TString_array& get_user_words();
int compile_user_word(const TString& n);
public: public:
const TString& get_last_error() const { return _last_error; } const TString& get_last_error() const { return _last_error; }
@ -421,6 +431,7 @@ public:
bool compile(istream& instr, TBytecode& bc); bool compile(istream& instr, TBytecode& bc);
bool execute(const TBytecode& bc, ostream* outstr = NULL); bool execute(const TBytecode& bc, ostream* outstr = NULL);
void restart(bool cold); void restart(bool cold);
bool do_fload(const char* fname);
TAVM(TAlex_virtual_machine* vm); TAVM(TAlex_virtual_machine* vm);
virtual ~TAVM(); virtual ~TAVM();
@ -494,6 +505,23 @@ int TAVM::find_matching(const TBytecode& bytecode, AVM_opcode op1, AVM_opcode op
return i; 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 TString& 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) bool TAVM::compile(istream& instr, TBytecode& bytecode)
{ {
TString str(256); TString str(256);
@ -610,7 +638,7 @@ bool TAVM::compile(istream& instr, TBytecode& bytecode)
} }
else else
{ {
const unsigned int oc = _vm->compile_usr_word(str); const int oc = compile_user_word(str);
if (oc > 0) if (oc > 0)
op = new TAVM_op(avm_usrword, oc); op = new TAVM_op(avm_usrword, oc);
} }
@ -647,16 +675,18 @@ void TAVM::do_call(const TString& func)
_bc = (TBytecode*)_words.objptr(func); _bc = (TBytecode*)_words.objptr(func);
} }
void TAVM::do_fload(const char* fname) bool TAVM::do_fload(const char* fname)
{ {
TFilename name = fname; TFilename name = fname;
if (name.custom_path()) bool ok = name.custom_path();
if (ok)
{ {
TBytecode bc; TBytecode bc;
ifstream inf(name); ifstream inf(name);
if (compile(inf, bc)) if (compile(inf, bc))
execute(bc); execute(bc);
} }
return ok;
} }
void TAVM::execute(const TAVM_op& op) void TAVM::execute(const TAVM_op& op)
@ -687,14 +717,31 @@ void TAVM::execute(const TAVM_op& op)
case avm_cmp_lt : _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_lteq : _stack.push(compare_tos_nos() <= 0); break;
case avm_cmp_noteq: _stack.push(compare_tos_nos() != 0); break; case avm_cmp_noteq: _stack.push(compare_tos_nos() != 0); break;
case avm_div: 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& r0 = _stack.pop().as_real();
const real& r1 = _stack.pop().as_real(); const real& r1 = _stack.pop().as_real();
real n;
if (!r0.is_zero()) if (!r0.is_zero())
n = r1 / r0; {
_stack.push(n); const real n = r1 / r0;
_stack.push(n);
}
else
_stack.push(NULL_VARIANT);
} }
break; break;
case avm_do: case avm_do:
@ -719,15 +766,6 @@ void TAVM::execute(const TAVM_op& op)
case avm_else: case avm_else:
_ip = op.var().as_int(); _ip = op.var().as_int();
break; break;
case avm_execute:
{
const TString& cmd = _stack.pop().as_string();
istrstream instr((char*)(const char*)cmd, cmd.len());
TBytecode bc;
if (compile(instr, bc))
execute(bc);
}
break;
case avm_false: _stack.push(0L); break; case avm_false: _stack.push(0L); break;
case avm_fetch: case avm_fetch:
{ {
@ -794,12 +832,16 @@ void TAVM::execute(const TAVM_op& op)
} }
break; break;
case avm_over: _stack.push(_stack.peek(1)); break; case avm_over: _stack.push(_stack.peek(1)); break;
case avm_pick: case avm_perform:
{ {
const int depth = _stack.pop().as_int(); const TString& cmd = _stack.pop().as_string();
_stack.push(_stack.peek(depth)); istrstream instr((char*)(const char*)cmd, cmd.len());
TBytecode bc;
if (compile(instr, bc))
execute(bc);
} }
break; break;
case avm_pick: _stack.push(_stack.peek(_stack.pop().as_int())); break;
case avm_plus_loop: case avm_plus_loop:
{ {
TVariant& start = _rstack.pop(); TVariant& start = _rstack.pop();
@ -815,6 +857,7 @@ void TAVM::execute(const TAVM_op& op)
case avm_rdrop: _stack.push(_rstack.pop()); break; case avm_rdrop: _stack.push(_rstack.pop()); break;
case avm_rpeek: _stack.push(_rstack.peek()); break; case avm_rpeek: _stack.push(_rstack.peek()); break;
case avm_rpush: _rstack.push(_stack.pop()); 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_rot: _stack.roll(2); break;
case avm_store: case avm_store:
{ {
@ -869,7 +912,7 @@ bool TAVM::execute(const TBytecode& cmdline, ostream* outstr)
_outstr = outstr; _outstr = outstr;
while (_bc != NULL) while (_bc != NULL)
{ {
if (_ip >= _bc->items()) // Fine funzione while (_ip >= _bc->items()) // Fine funzione
{ {
if (_rstack.items() >= 2) // Controllo il return stack if (_rstack.items() >= 2) // Controllo il return stack
{ {
@ -881,10 +924,13 @@ bool TAVM::execute(const TBytecode& cmdline, ostream* outstr)
_bc = (const TBytecode*)_words.objptr(str); _bc = (const TBytecode*)_words.objptr(str);
} }
else else
{
_bc = NULL;
break; // Fine esecuzione break; // Fine esecuzione
if (_bc == NULL) }
break;
} }
if (_bc == NULL || _ip > _bc->items())
break;
TAVM_op& op = *(TAVM_op*)_bc->objptr(_ip); TAVM_op& op = *(TAVM_op*)_bc->objptr(_ip);
if (op.has_break() && !_mon.is_open()) if (op.has_break() && !_mon.is_open())
@ -898,7 +944,7 @@ bool TAVM::execute(const TBytecode& cmdline, ostream* outstr)
{ {
lock_preview_update(true); lock_preview_update(true);
TAVM_list_window& monitor = _mon.monitor(); TAVM_list_window& monitor = _mon.monitor();
monitor.set_bytecode(_bc, _ip); monitor.set_bytecode(_bc, _ip, _user_words);
TAVM_stack_window& stacker = _mon.stacker(); TAVM_stack_window& stacker = _mon.stacker();
stacker.set_stack(_stack); stacker.set_stack(_stack);
TAVM_stack_window& rstacker = _mon.rstacker(); TAVM_stack_window& rstacker = _mon.rstacker();
@ -915,8 +961,8 @@ bool TAVM::execute(const TBytecode& cmdline, ostream* outstr)
op.set_auto_break(true); op.set_auto_break(true);
} }
break; break;
case K_DEL : abort_printing(); case K_QUIT: abort_printing();
case K_QUIT: _mon.close_modal(); lock_preview_update(false); break; case K_F5 : _mon.close_modal(); lock_preview_update(false); break;
default: break; default: break;
} }
} }
@ -932,23 +978,28 @@ bool TAVM::execute(const TBytecode& cmdline, ostream* outstr)
lock_preview_update(false); lock_preview_update(false);
} }
const bool ok = _bc != NULL; // Not aborted //const bool ok = _bc != NULL; // Not aborted
_bc = old_bc; _bc = old_bc;
_ip = old_ip; _ip = old_ip;
return ok; return true;
} }
void TAVM::restart(bool cold) void TAVM::restart(bool cold)
{ {
_stack.reset(); _stack.reset();
_rstack.reset(); _rstack.reset();
if (cold)
{
_words.destroy();
do_fload("alex.alx");
}
} }
TAVM::TAVM(TAlex_virtual_machine* vm) TAVM::TAVM(TAlex_virtual_machine* vm)
: _vm(vm), _outstr(NULL) : _vm(vm), _outstr(NULL)
{ {
do_fload("alex.alx"); restart(true);
} }
TAVM::~TAVM() TAVM::~TAVM()
@ -1017,6 +1068,12 @@ bool TAlex_virtual_machine::get_usr_val(const TString& name, TVariant& var) cons
var.set(dongle().administrator()); var.set(dongle().administrator());
return true; return true;
} }
if (n == "CLOCK")
{
const long msec = clock() / (CLOCKS_PER_SEC / 1000);
var.set(msec);
return true;
}
if (n == "FIRM") if (n == "FIRM")
{ {
var.set(prefix().get_codditta()); var.set(prefix().get_codditta());
@ -1055,7 +1112,7 @@ bool TAlex_virtual_machine::set_usr_val(const TString& name, const TVariant& var
return false; return false;
} }
unsigned int TAlex_virtual_machine::compile_usr_word(const TString& name) const unsigned int TAlex_virtual_machine::get_usr_words(TString_array&) const
{ {
return 0; return 0;
} }
@ -1065,6 +1122,11 @@ bool TAlex_virtual_machine::execute_usr_word(unsigned int opcode, TVariant_stack
return false; return false;
} }
bool TAlex_virtual_machine::fload(const char* fname)
{
return avm().do_fload(fname);
}
TAlex_virtual_machine::TAlex_virtual_machine() : _avm(NULL) TAlex_virtual_machine::TAlex_virtual_machine() : _avm(NULL)
{ {
} }

View File

@ -49,7 +49,7 @@ protected:
TAVM& avm(); TAVM& avm();
public: public:
virtual unsigned int compile_usr_word(const TString& name) const; virtual size_t get_usr_words(TString_array& names) const;
virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack);
virtual bool get_usr_val(const TString& name, TVariant& var) const; virtual bool get_usr_val(const TString& name, TVariant& var) const;
virtual bool set_usr_val(const TString& name, const TVariant& var); virtual bool set_usr_val(const TString& name, const TVariant& var);
@ -59,6 +59,7 @@ public:
bool compile(const char* cmd, TBytecode& bc); bool compile(const char* cmd, TBytecode& bc);
bool execute(const TBytecode& bc, ostream& outstr); bool execute(const TBytecode& bc, ostream& outstr);
bool execute(const TBytecode& bc, TString& outstr); bool execute(const TBytecode& bc, TString& outstr);
bool fload(const char* fname);
void warm_restart(); void warm_restart();
void cold_restart(); void cold_restart();

View File

@ -15,31 +15,31 @@ BEGIN
PROMPT 27 11 "" PROMPT 27 11 ""
END END
BUTTON DLG_NEXTREC 10 2 BUTTON DLG_NEXTREC 9 2
BEGIN BEGIN
PROMPT -14 -1 "" PROMPT -14 -1 ""
PICTURE 124 PICTURE 124
MESSAGE EXIT,K_F11 MESSAGE EXIT,K_F11
END END
BUTTON DLG_LASTREC 10 2 BUTTON DLG_LASTREC 9 2
BEGIN BEGIN
PROMPT -24 -1 "" PROMPT -24 -1 ""
PICTURE 1671 PICTURE 1671
MESSAGE EXIT,K_F10 MESSAGE EXIT,K_F10
END END
BUTTON DLG_ELABORA 10 2 BUTTON DLG_ELABORA 9 2
BEGIN BEGIN
PROMPT -34 -1 "" PROMPT -34 -1 ""
PICTURE BMP_LASTREC PICTURE BMP_LASTREC
MESSAGE EXIT,K_QUIT MESSAGE EXIT,K_F5
END END
BUTTON DLG_DELREC 10 2 BUTTON DLG_QUIT 9 2
BEGIN BEGIN
PROMPT -44 -1 "Abort" PROMPT -44 -1 ""
MESSAGE EXIT,K_DEL MESSAGE EXIT,K_QUIT
END END

168
ba/ba8400.cpp Executable file
View File

@ -0,0 +1,168 @@
#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <execp.h>
#include <form.h>
#include <prefix.h>
#include <scanner.h>
#include "ba8302.h"
#include "ba8400.h"
///////////////////////////////////////////////////////////
// TFormer_mask
///////////////////////////////////////////////////////////
class TFormer_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void import();
public:
TFormer_mask();
};
void TFormer_mask::import_use()
{
}
void TFormer_mask::import_use(TReport& rep) const
{
TScanner scan(get(F_FORM));
TString use;
int parse_use = 0;
while (scan.ok())
{
const TString& line = scan.line();
if (line.empty())
break;
if (parse_use == 0 && line.starts_with("US"))
parse_use = 1;
if (parse_use == 1)
{
if (line.starts_with("EN"))
{
parse_use = 2;
break;
}
else
use << line << '\n';
}
}
if (!use.blank())
rep.set_recordset(use);
}
void TFormer_mask::import_sections(TReport& rep) const
{
TExportable_form frm(get(F_FORM));
frm.export_section('G', odd_page, rep, 'B', 0);
frm.export_section('B', odd_page, rep, 'B', 2);
}
void TFormer_mask::import()
{
TReport rep;
import_use(rep);
import_sections(rep);
rep.save(get(F_REPORT));
}
bool TFormer_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_FORM:
if (e == fe_modify)
{
TFilename output = get(F_REPORT);
TFilename path = output.path();
if (path.empty())
{
path = firm2dir(-1);
path.add("custom");
}
const TFilename input = o.get();
output = path;
output.add(input.name());
output.ext("rep");
output.lower();
set(F_REPORT, output);
enable(DLG_ELABORA, input.exist());
}
break;
case F_REPORT:
if (e == fe_modify)
{
const TFilename output = get(F_REPORT);
enable(DLG_PRINT, output.exist());
}
break;
case DLG_ELABORA:
if (e == fe_button)
{
const TFilename output = get(F_REPORT);
if (output.exist())
{
if (!yesno_box(TR("Il file %s esiste gia':\nSi desidera sovrascriverlo?"), (const char*)output))
return false;
}
import();
enable(DLG_PRINT, output.exist());
}
break;
case DLG_PRINT:
if (e == fe_button)
{
const TFilename output = get(F_REPORT);
if (output.exist())
{
TString cmd;
cmd << "ba8 -2 " << output;
TExternal_app app(cmd);
app.run();
return false; // Altrimenti esce dalla maschera
}
else
return error_box(TR("Il file %s non esiste"), (const char*)output);
}
break;
default:
break;
}
return true;
}
TFormer_mask::TFormer_mask() : TAutomask("ba8400a")
{
}
///////////////////////////////////////////////////////////
// TFormer_app
///////////////////////////////////////////////////////////
class TFormer_app : public TSkeleton_application
{
protected:
virtual void main_loop();
};
void TFormer_app::main_loop()
{
TFormer_mask m;
m.run();
}
int ba8400(int argc, char* argv[])
{
TFormer_app app;
app.run(argc, argv, TR("Form Converter"));
return 0;
}

2
ba/ba8400.h Executable file
View File

@ -0,0 +1,2 @@
#define F_FORM 101
#define F_REPORT 102

37
ba/ba8400a.uml Executable file
View File

@ -0,0 +1,37 @@
#include "ba8400.h"
PAGE "Conversione Form in Report" -1 -1 62 6
STRINGA F_FORM 256 50
BEGIN
PROMPT 1 1 "Form "
FSELECT "*.frm"
END
STRINGA F_REPORT 256 50
BEGIN
PROMPT 1 2 "Report "
END
BUTTON DLG_ELABORA 10 2
BEGIN
PROMPT -13 -1 "~Elabora"
PICTURE BMP_ELABORA
FLAGS "D"
END
BUTTON DLG_PRINT 10 2
BEGIN
PROMPT -23 -1 "~Stampa"
PICTURE BMP_PRINT
FLAGS "D"
END
BUTTON DLG_QUIT 10 2
BEGIN
PROMPT -33 -1 ""
END
ENDPAGE
ENDMASK