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:
parent
5e9712217e
commit
2b0291afdb
@ -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...
|
||||||
|
@ -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;
|
||||||
|
@ -168,5 +168,7 @@ public:
|
|||||||
virtual ~TMenu();
|
virtual ~TMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool sys_dll_changed();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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;
|
||||||
|
1
ba/ba8.h
1
ba/ba8.h
@ -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[]);
|
||||||
|
|
||||||
|
|
||||||
|
177
ba/ba8200.cpp
177
ba/ba8200.cpp
@ -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[])
|
||||||
|
11
ba/ba8200.h
11
ba/ba8200.h
@ -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
|
||||||
|
@ -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 ""
|
||||||
|
776
ba/ba8201.cpp
776
ba/ba8201.cpp
@ -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();
|
||||||
|
}
|
||||||
|
51
ba/ba8201.h
51
ba/ba8201.h
@ -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);
|
||||||
|
@ -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[])
|
||||||
|
@ -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 ""
|
||||||
|
@ -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;
|
||||||
|
152
ba/ba8302.cpp
152
ba/ba8302.cpp
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
142
ba/ba8304.cpp
142
ba/ba8304.cpp
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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
168
ba/ba8400.cpp
Executable 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
2
ba/ba8400.h
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#define F_FORM 101
|
||||||
|
#define F_REPORT 102
|
37
ba/ba8400a.uml
Executable file
37
ba/ba8400a.uml
Executable 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
|
Loading…
x
Reference in New Issue
Block a user