309d8b23fd
Files correlati : ba8300a.msk ba8300b.msk ba8300c.msk ba8.exe Ricompilazione Demo : [ ] Commento : Riassunto 0001600: Dopo la stampa di un report in orizz ritorna in visual con il foglio in vert. Faccio l'anteprima di un report creato con orientamento foglio orrizzontale fisso, dopo aver stampato ritorna in visualizzazione con l'orientamento del foglio impostato sulla stampante (normalmente in verticale) git-svn-id: svn://10.65.10.50/trunk@20332 c028cbd2-c16b-5b4b-a496-9718f37d4682
1526 lines
35 KiB
C++
Executable File
1526 lines
35 KiB
C++
Executable File
#include <xinclude.h>
|
|
|
|
#include <applicat.h>
|
|
#include <automask.h>
|
|
#include <defmask.h>
|
|
#include <extcdecl.h>
|
|
#include <modaut.h>
|
|
#include <odbcrset.h>
|
|
#include <prefix.h>
|
|
#include <relation.h>
|
|
#include <sheet.h>
|
|
#include <tree.h>
|
|
#include <treectrl.h>
|
|
#include <utility.h>
|
|
#include <xml.h>
|
|
|
|
#include "ba8200.h"
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TRelation_node & TRelation_tree
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Informazioni relative ad un nodo della relazione:
|
|
class TRelation_node : public TObject
|
|
{
|
|
const TRelation_node* _father; // Puntatore all'eventuale padre
|
|
int _logicnum; // Numero logico
|
|
TString16 _name, _alias; // Nome ed Alias
|
|
TString_array _join_fields; // Elenco dei campi di join
|
|
|
|
public:
|
|
bool description(TString& str) const;
|
|
int num() const { return _logicnum; }
|
|
const TString& name() const { return _name; }
|
|
const TString& alias() const { return _alias; }
|
|
const TString& id() const { return _alias.not_empty() ? _alias : _name; }
|
|
const TRelation_node* father() const { return _father; }
|
|
|
|
void set_num(int num);
|
|
void set_alias(const char* alias) { _alias = alias; }
|
|
|
|
TString_array& join() { return _join_fields; }
|
|
|
|
TRelation_node(const TRelation_node* father, int ln, const char* alias);
|
|
virtual ~TRelation_node() {}
|
|
};
|
|
|
|
bool TRelation_node::description(TString& str) const
|
|
{
|
|
const bool ok = _logicnum >= LF_USER;
|
|
if (ok)
|
|
{
|
|
const FileDes& fd = prefix().get_filedes(_logicnum);
|
|
str = _name;
|
|
if (_alias.not_empty())
|
|
str << " ALIAS " << _alias;
|
|
str << " (" << fd.Des << ')';
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
void TRelation_node::set_num(int num)
|
|
{
|
|
_logicnum = num;
|
|
const FileDes& fd = prefix().get_filedes(_logicnum);
|
|
_name = fd.SysName; _name.strip("$%"); _name.upper();
|
|
}
|
|
|
|
TRelation_node::TRelation_node(const TRelation_node* father, int ln, const char* alias)
|
|
: _father(father)
|
|
{
|
|
set_num(ln);
|
|
set_alias(alias);
|
|
}
|
|
|
|
// Albero di una relazione
|
|
class TRelation_tree : public TObject_tree
|
|
{
|
|
protected:
|
|
virtual bool get_description(TString& str) const;
|
|
|
|
public:
|
|
bool find_id(const TString& id);
|
|
};
|
|
|
|
bool TRelation_tree::get_description(TString& str) const
|
|
{
|
|
const TRelation_node* rn = (const TRelation_node*)curr_node();
|
|
if (rn != NULL)
|
|
return rn->description(str);
|
|
return false;
|
|
}
|
|
|
|
static bool find_id_callback(TTree& tree, void* jolly, word flags)
|
|
{
|
|
const TRelation_node* n = (const TRelation_node*)tree.curr_node();
|
|
if (n != NULL)
|
|
{
|
|
const TString& id = *(const TString*)jolly;
|
|
return n->id() == id;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool TRelation_tree::find_id(const TString& id)
|
|
{
|
|
bool ok = goto_root();
|
|
if (ok)
|
|
{
|
|
scan_depth_first(find_id_callback, (void*)&id);
|
|
const TRelation_node* n = (const TRelation_node*)curr_node();
|
|
ok = n != NULL && n->id() == id;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TTable_mask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Maschera per inserire/editare un nodo dell'albero
|
|
class TTable_mask : public TAutomask
|
|
{
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
|
|
protected:
|
|
int father_logicnum() const;
|
|
const char* find_linked_field(int logicnum, const RecFieldDes& fd) const;
|
|
|
|
public:
|
|
int son_logicnum() const;
|
|
void mask2node(TRelation_node& node);
|
|
|
|
TTable_mask();
|
|
~TTable_mask();
|
|
};
|
|
|
|
int TTable_mask::father_logicnum() const
|
|
{
|
|
return table2logic(get(F_FATHER));
|
|
}
|
|
|
|
int TTable_mask::son_logicnum() const
|
|
{
|
|
return table2logic(get(F_SON));
|
|
}
|
|
|
|
// Dato il numero logico di una tabella ed un campo (di un'altra tabella)
|
|
// cerca il campo piu' simile all'interno del tracciato record
|
|
const char* TTable_mask::find_linked_field(int logicnum, const RecFieldDes& fd) const
|
|
{
|
|
const RecDes& rd = prefix().get_recdes(logicnum);
|
|
int nBest = -1;
|
|
double dBest = 0.0;
|
|
for (int i = 0; i < rd.NFields; i++)
|
|
{
|
|
const RecFieldDes& field = rd.Fd[i];
|
|
if (field.TypeF == fd.TypeF && field.Len == fd.Len)
|
|
{
|
|
const double fuzzy = xvt_str_fuzzy_compare(field.Name, fd.Name);
|
|
if (fuzzy > dBest)
|
|
{
|
|
nBest = i;
|
|
dBest = fuzzy;
|
|
if (dBest == 1.0)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return nBest >= 0 ? rd.Fd[nBest].Name : "";
|
|
}
|
|
|
|
bool TTable_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
case F_SON:
|
|
if (e == fe_modify)
|
|
{
|
|
const int logicnum = son_logicnum();
|
|
const int fathernum = father_logicnum();
|
|
|
|
TSheet_field& sheet = sfield(F_SHEET);
|
|
sheet.destroy();
|
|
if (logicnum >= LF_USER && fathernum >= LF_USER)
|
|
{
|
|
const RecDes& rd = prefix().get_recdes(logicnum);
|
|
const KeyDes& kd = rd.Ky[0];
|
|
TToken_string tok;
|
|
for (int j = 0; j < kd.NkFields; j++)
|
|
{
|
|
const int n = kd.FieldSeq[j] % MaxFields;
|
|
tok = rd.Fd[n].Name;
|
|
tok.add(find_linked_field(fathernum, rd.Fd[n]));
|
|
sheet.rows_array().add(tok);
|
|
}
|
|
}
|
|
sheet.force_update();
|
|
}
|
|
break;
|
|
case F_SHEET:
|
|
if (e == se_query_add || e == se_query_del)
|
|
return false;
|
|
break;
|
|
case F_FLD_TO:
|
|
if (e == fe_button)
|
|
{
|
|
const int logicnum = son_logicnum();
|
|
if (logicnum >= LF_USER)
|
|
{
|
|
TArray_sheet sheet(-1, -1, 24, 20, TR("Selezione"), HR("Nome@12|Lunghezza"));
|
|
const RecDes& rd = prefix().get_recdes(logicnum);
|
|
TToken_string row;
|
|
for (int i = 0; i < rd.NFields; i++)
|
|
{
|
|
row = rd.Fd[i].Name;
|
|
row.add(rd.Fd[i].Len);
|
|
sheet.add(row);
|
|
}
|
|
sheet.rows_array().sort();
|
|
if (sheet.run() == K_ENTER)
|
|
o.set(sheet.row(-1).get(0));
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Trasferisce le informazioni dalla maschera ad un nodo della tabella
|
|
void TTable_mask::mask2node(TRelation_node& son)
|
|
{
|
|
son.set_num(son_logicnum());
|
|
son.set_alias(get(F_SON_ALIAS));
|
|
|
|
if (son.father() != NULL)
|
|
{
|
|
TString_array& join = son.join();
|
|
join.destroy();
|
|
|
|
TSheet_field& sheet = sfield(F_SHEET);
|
|
FOR_EACH_SHEET_ROW(sheet, i, row)
|
|
{
|
|
TToken_string* newrow = new TToken_string(50, '=');
|
|
newrow->add(row->get(0));
|
|
newrow->add(row->get());
|
|
join.add(newrow);
|
|
}
|
|
}
|
|
}
|
|
|
|
TTable_mask::TTable_mask() : TAutomask("ba8200b")
|
|
{
|
|
const TDir dir(LF_DIR);
|
|
const int nfiles = (int)dir.eod();
|
|
|
|
TList_sheet& sht = *efield(F_SON).sheet();
|
|
TToken_string tt(80);
|
|
for (int logic = LF_USER; logic < nfiles; logic++)
|
|
{
|
|
const FileDes& fd = prefix().get_filedes(logic);
|
|
tt = fd.SysName;
|
|
if (tt.full())
|
|
{
|
|
tt.strip("$%"); tt.upper();
|
|
tt.add(logic);
|
|
tt.add(fd.Des);
|
|
sht.rows_array().add(tt);
|
|
}
|
|
}
|
|
sht.rows_array().sort();
|
|
}
|
|
|
|
TTable_mask::~TTable_mask()
|
|
{ }
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TQuery_mask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Maschera principale della costruzione della query
|
|
class TQuery_mask : public TAutomask
|
|
{
|
|
TRelation_tree _tree; // Albero della relazione
|
|
int _curr_num; // Numero del file corrente
|
|
bool _dragster; // Operazione di trascinamento in corso
|
|
|
|
TFilename _curr_query;// Nome completo della query in editazione
|
|
bool _is_dirty; // Maschera cambiata dall'ultimo caricamento
|
|
bool _sql_dirty; // Query modificata manualmente
|
|
|
|
protected:
|
|
virtual long handler(WINDOW win, EVENT* ep);
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
|
|
protected:
|
|
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_asterisk_to_sheet();
|
|
bool ask_vars(const char* maskname, TRecordset& recset) const;
|
|
TRecordset* new_recordset() const;
|
|
bool edit_file_in_tree();
|
|
|
|
static int sort_fields(const TObject** r1, const TObject** r2);
|
|
void fill_fields();
|
|
void enable_sql_button();
|
|
void enable_field_buttons();
|
|
void move_curr_field(int dir);
|
|
|
|
void tree2sql(TString& from, TString& where);
|
|
void tree2isam(TString_array& a);
|
|
void sheet2sql();
|
|
void sheet2isam();
|
|
|
|
bool select_query();
|
|
bool load_tables_tree(TXmlItem& tables);
|
|
bool load_fields_sheet(TXmlItem& fields);
|
|
void global_reset();
|
|
|
|
bool save_tables_tree(TXmlItem& xml);
|
|
bool save_fields_sheet(TXmlItem& xml);
|
|
|
|
public:
|
|
void edit_query();
|
|
void save_as(TRecordsetExportFormat fmt, const char* ext = NULL);
|
|
|
|
bool load_query();
|
|
bool save_query();
|
|
bool save_if_needed();
|
|
bool delete_query();
|
|
|
|
bool get_qry_path(TFilename& path) const;
|
|
|
|
TRelation_node* curr_node();
|
|
TQuery_mask();
|
|
};
|
|
|
|
// Nodo corrente dell'albero
|
|
TRelation_node* TQuery_mask::curr_node()
|
|
{
|
|
TTree_field& tf = tfield(F_TABLES);
|
|
tf.goto_selected();
|
|
TRelation_node* n = (TRelation_node*)_tree.curr_node();
|
|
return n;
|
|
}
|
|
|
|
// Aggiunge interattivamente un nodo all'albero
|
|
bool TQuery_mask::add_file_to_tree()
|
|
{
|
|
TTable_mask msk;
|
|
|
|
const TRelation_node* father = curr_node();
|
|
TString fatherid;
|
|
if (father != NULL)
|
|
{
|
|
_tree.curr_id(fatherid);
|
|
msk.set(F_FATHER, father->name());
|
|
msk.set(F_FATHER_ALIAS, father->alias());
|
|
}
|
|
msk.disable(DLG_DELREC);
|
|
|
|
bool ok = msk.run() == K_ENTER;
|
|
if (ok)
|
|
{
|
|
TRelation_node* son = new TRelation_node(father, msk.son_logicnum(), msk.get(F_SON_ALIAS));
|
|
msk.mask2node(*son);
|
|
if (fatherid.not_empty())
|
|
_tree.goto_node(fatherid);
|
|
_tree.add_son(son);
|
|
_tree.expand_all();
|
|
tfield(F_TABLES).win().force_update();
|
|
|
|
_curr_num = son->num();
|
|
fill_fields();
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
// Modifica interattivamente il nodo corrente dell'albero
|
|
bool TQuery_mask::edit_file_in_tree()
|
|
{
|
|
TRelation_node* son = curr_node();
|
|
if (son == NULL)
|
|
return false;
|
|
|
|
TString sonid; _tree.curr_id(sonid);
|
|
|
|
const TRelation_node* father = NULL;
|
|
if (_tree.goto_father())
|
|
father = (const TRelation_node*)_tree.curr_node();
|
|
|
|
TTable_mask msk;
|
|
if (father != NULL)
|
|
{
|
|
msk.set(F_FATHER, father->name());
|
|
msk.set(F_FATHER_ALIAS, father->alias());
|
|
|
|
TString_array& arr = son->join();
|
|
FOR_EACH_ARRAY_ROW(arr, i, row)
|
|
{
|
|
TToken_string& newrow = msk.sfield(F_SHEET).row(-1);
|
|
FOR_EACH_TOKEN((*row), tok)
|
|
{
|
|
TToken_string str(tok, '.');
|
|
str.strip_spaces();
|
|
if (str.items() > 1)
|
|
newrow.add(str.get(1));
|
|
else
|
|
newrow.add(str);
|
|
}
|
|
}
|
|
}
|
|
msk.set(F_SON, son->name());
|
|
msk.set(F_SON_ALIAS, son->alias());
|
|
|
|
bool update = true;
|
|
switch (msk.run())
|
|
{
|
|
case K_ENTER:
|
|
msk.mask2node(*son);
|
|
break;
|
|
case K_DEL:
|
|
if (curr_node() != NULL)
|
|
{
|
|
if (yesno_box(TR("Eliminare anche le colonne associate della query?")))
|
|
{
|
|
TSheet_field& sheet = sfield(F_SHEET);
|
|
FOR_EACH_SHEET_ROW_BACK(sheet, r, row)
|
|
{
|
|
const TString& id = row->get(0);
|
|
if (id == son->id())
|
|
sheet.destroy(r);
|
|
}
|
|
}
|
|
_tree.goto_node(sonid);
|
|
_tree.kill_node();
|
|
_tree.goto_root();
|
|
}
|
|
break;
|
|
default:
|
|
update = false;
|
|
break;
|
|
}
|
|
|
|
if (update)
|
|
{
|
|
TTree_field& tf = tfield(F_TABLES);
|
|
tf.win().force_update();
|
|
|
|
_curr_num = 0;
|
|
if (tf.select_current())
|
|
{
|
|
const TRelation_node* curr = curr_node();
|
|
if (curr != NULL)
|
|
_curr_num = curr->num();
|
|
}
|
|
fill_fields();
|
|
}
|
|
|
|
return update; // ????
|
|
}
|
|
|
|
// Ordina per importanza i campi di un tracciato record
|
|
int TQuery_mask::sort_fields(const TObject** r1, const TObject** r2)
|
|
{
|
|
TToken_string& s1 = (TToken_string&)**r1;
|
|
TToken_string& s2 = (TToken_string&)**r2;
|
|
const int w1 = s1.get_int(4);
|
|
const int w2 = s2.get_int(4);
|
|
int cmp = w2-w1;
|
|
if (cmp == 0)
|
|
cmp = strcmp(s1.get(0), s2.get(0));
|
|
return cmp;
|
|
}
|
|
|
|
// Riempie la lista dei campi del file corrente
|
|
void TQuery_mask::fill_fields()
|
|
{
|
|
TSheet_field& sht = sfield(F_FIELDS);
|
|
sht.destroy();
|
|
if (_curr_num >= LF_USER)
|
|
{
|
|
TRelation rel(_curr_num);
|
|
TRelation_description reldes(rel);
|
|
|
|
const RecDes& rd = prefix().get_recdes(_curr_num);
|
|
for (int i = 0; i < rd.NFields; i++)
|
|
{
|
|
TToken_string& row = sht.row(-1);
|
|
const RecFieldDes& fd = rd.Fd[i];
|
|
row = fd.Name;
|
|
row.add(fd.Len);
|
|
|
|
int weight = 0;
|
|
for (int k = 0; k < rd.NKeys; k++)
|
|
{
|
|
const KeyDes& kd = rd.Ky[k];
|
|
for (int j = 0; j < kd.NkFields; j++)
|
|
{
|
|
const int n = kd.FieldSeq[j] % MaxFields;
|
|
if (n == i)
|
|
{
|
|
if (weight == 0)
|
|
{
|
|
weight = (rd.NKeys-k)*100 + kd.NkFields-j;
|
|
row.add(k+1);
|
|
}
|
|
else
|
|
row << ' ' << (k+1);
|
|
}
|
|
}
|
|
}
|
|
row.add(reldes.get_field_description(fd.Name), 3);
|
|
row.add(weight, 4);
|
|
}
|
|
sht.rows_array().TArray::sort(sort_fields);
|
|
}
|
|
sht.force_update();
|
|
enable_field_buttons();
|
|
}
|
|
|
|
// Aggiunge un cmapo allo spreadsheet F_SHEET
|
|
void TQuery_mask::add_field_to_sheet(const char* fld, bool update)
|
|
{
|
|
const TRelation_node* n = curr_node();
|
|
if (n != NULL)
|
|
{
|
|
TSheet_field& ff = sfield(F_SHEET);
|
|
TToken_string& row = ff.row(-1);
|
|
row = n->id();
|
|
row.add(fld);
|
|
_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
|
|
void TQuery_mask::add_asterisk_to_sheet()
|
|
{
|
|
const TRelation_node* n = curr_node();
|
|
if (n != NULL)
|
|
{
|
|
if (yesno_box("Si desisdera aggiungere tutti i campi singolarmente?"))
|
|
{
|
|
TSheet_field& sf = sfield(F_FIELDS);
|
|
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);
|
|
}
|
|
else
|
|
add_field_to_sheet("*", true);
|
|
}
|
|
}
|
|
|
|
// Decide se attivare o meno il bottone SQL
|
|
void TQuery_mask::enable_sql_button()
|
|
{
|
|
const bool yes = sfield(F_SHEET).items() > 0;
|
|
enable(F_GENSQL, yes);
|
|
}
|
|
|
|
// Decide se attivare o meno i bottoni di aggiunta campi
|
|
void TQuery_mask::enable_field_buttons()
|
|
{
|
|
const TSheet_field& sf = sfield(F_FIELDS);
|
|
const bool ok = sf.items() > 0;
|
|
enable(-1, ok);
|
|
}
|
|
|
|
void TQuery_mask::move_curr_field(int dir)
|
|
{
|
|
TSheet_field& s = sfield(F_SHEET);
|
|
const int sel = s.selected();
|
|
if (sel >= 0 && sel < s.items())
|
|
{
|
|
const int des = sel+dir;
|
|
if (des >= 0 && des < s.items())
|
|
{
|
|
s.rows_array().swap(sel, des);
|
|
s.select(des);
|
|
s.force_update();
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool sql_tree_handler(TTree& tree, void* jolly, word flags)
|
|
{
|
|
TRelation_node* rn = (TRelation_node*)tree.curr_node();
|
|
TPointer_array& arr = *(TPointer_array*)jolly;
|
|
TToken_string& from = *(TToken_string*)arr.objptr(0);
|
|
TString& where = *(TString*)arr.objptr(1);
|
|
TString_array& join = rn->join();
|
|
TString str;
|
|
|
|
if (from.get_pos(rn->id()) < 0)
|
|
{
|
|
from.add(rn->name());
|
|
if (rn->alias().not_empty())
|
|
from << " AS " << rn->alias();
|
|
|
|
FOR_EACH_ARRAY_ROW(join, i, row)
|
|
{
|
|
if (where.find(*row) < 0)
|
|
{
|
|
if (where.not_empty())
|
|
where << "AND";
|
|
where << '(' << rn->id() << '.' << row->get(0) << '=';
|
|
str = row->get();
|
|
if (isalpha(str[0]))
|
|
where << rn->father()->id() << '.';
|
|
where << str << ')';
|
|
}
|
|
}
|
|
}
|
|
|
|
return false; // Don't stop search
|
|
}
|
|
|
|
// Riempie una stringa SQL con la relazione tra le tabelle
|
|
void TQuery_mask::tree2sql(TString& from, TString& where)
|
|
{
|
|
if (_tree.goto_root())
|
|
{
|
|
TPointer_array a;
|
|
a.add(&from);
|
|
a.add(&where);
|
|
_tree.scan_depth_first(sql_tree_handler, &a);
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
const char* str = tok.get(pos);
|
|
return str && *str > ' ';
|
|
}
|
|
|
|
static void add_where_clause(TString& where, const char* field, const char* cmp, const char* expr)
|
|
{
|
|
if (where.not_empty())
|
|
where << "AND";
|
|
where << '(' << field << cmp << expr << ')';
|
|
}
|
|
|
|
// Genera una query SQL a partire dallo spreadsheet F_SHEET
|
|
void TQuery_mask::sheet2sql()
|
|
{
|
|
const TSheet_field& sheet = sfield(F_SHEET);
|
|
TToken_string select(50, ',');
|
|
|
|
_tree.goto_root();
|
|
const bool multiple = _tree.has_son();
|
|
|
|
TToken_string from(50, ','), groupby(50, ','), orderby(50, ',');
|
|
TString where, expr_from, expr_to;
|
|
|
|
TString field;
|
|
FOR_EACH_SHEET_ROW(sheet, i, row)
|
|
{
|
|
field = row->get(1);
|
|
if (!field.blank() && !tok_get_bool(*row, 2)) // Campo valido e visibile
|
|
{
|
|
if (multiple)
|
|
{
|
|
const TString& tab = row->get(0);
|
|
if (!tab.blank())
|
|
{
|
|
field.insert(".");
|
|
field.insert(tab); // Table name
|
|
}
|
|
}
|
|
select.add(field); // Column name only
|
|
|
|
if (tok_get_bool(*row, 3)) // Sort
|
|
orderby.add(field);
|
|
if (tok_get_bool(*row, 4)) // Group
|
|
groupby.add(field);
|
|
|
|
expr_from = row->get(5); expr_from.trim();
|
|
expr_to = row->get(6); expr_to.trim();
|
|
if (expr_from.not_empty() || expr_to.not_empty())
|
|
{
|
|
if (expr_from.not_empty() && isalpha(expr_from[0]))
|
|
{
|
|
expr_from.insert("'");
|
|
expr_from << '\'';
|
|
}
|
|
if (expr_to.not_empty() && isalpha(expr_to[0]))
|
|
{
|
|
expr_to.insert("'");
|
|
expr_to << '\'';
|
|
}
|
|
|
|
if (expr_from == expr_to)
|
|
{
|
|
add_where_clause(where, field, "=", expr_from);
|
|
}
|
|
else
|
|
{
|
|
if (expr_from.not_empty())
|
|
add_where_clause(where, field, ">=", expr_from);
|
|
if (expr_to.not_empty())
|
|
add_where_clause(where, field, "<=", expr_to);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
tree2sql(from, where);
|
|
|
|
TString sql;
|
|
sql << "SELECT " << select << '\n';
|
|
sql << "FROM " << from << '\n';
|
|
if (!where.blank())
|
|
sql << "WHERE " << where << '\n';
|
|
if (groupby.not_empty())
|
|
sql << "GROUP BY " << groupby << '\n';
|
|
if (orderby.not_empty())
|
|
sql << "ORDER BY " << orderby << '\n';
|
|
sql << ";";
|
|
|
|
set(F_SQL, sql, true);
|
|
_sql_dirty = false;
|
|
TEdit_field& fs = efield(F_SQL);
|
|
fs.set_focusdirty(false); // Evita di scatenare eventi inutili
|
|
}
|
|
|
|
// Genera una query ISAM a partire dallo spreadsheet F_SHEET
|
|
void TQuery_mask::sheet2isam()
|
|
{
|
|
TString_array rel;
|
|
tree2isam(rel);
|
|
|
|
TString use;
|
|
FOR_EACH_ARRAY_ROW(rel, i, row)
|
|
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
|
|
}
|
|
|
|
bool TQuery_mask::ask_vars(const char* maskname, TRecordset& recset) const
|
|
{
|
|
if (recset.variables().items() == 0)
|
|
return true;
|
|
|
|
TFilename fname = maskname; fname.ext("msk");
|
|
KEY key = K_QUIT;
|
|
if (!fname.custom_path())
|
|
return recset.ask_variables(true);
|
|
|
|
TMask m(maskname);
|
|
TVariant var;
|
|
for (int i = m.fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = m.fld(i);
|
|
const TFieldref* ref = f.field();
|
|
if (ref != NULL)
|
|
{
|
|
TString name = ref->name();
|
|
if (name[0] != '#')
|
|
name.insert("#");
|
|
const TVariant& var = recset.get_var(name);
|
|
if (!var.is_null())
|
|
f.set(var.as_string());
|
|
}
|
|
}
|
|
key = m.run();
|
|
const bool ok = key != K_QUIT && key != K_ESC;
|
|
if (ok)
|
|
{
|
|
// Rendi visibili tutte le variabili utente al report
|
|
for (int i = m.fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = m.fld(i);
|
|
const TFieldref* ref = f.field();
|
|
if (ref != NULL)
|
|
{
|
|
switch (f.class_id())
|
|
{
|
|
case CLASS_CURRENCY_FIELD:
|
|
case CLASS_REAL_FIELD:
|
|
var = real(f.get());
|
|
break;
|
|
case CLASS_DATE_FIELD:
|
|
var = TDate(f.get());
|
|
break;
|
|
default:
|
|
var = f.get();
|
|
break;
|
|
}
|
|
TString name = ref->name();
|
|
if (name[0] != '#')
|
|
name.insert("#");
|
|
recset.set_var(name, var, true);
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
TRecordset* TQuery_mask::new_recordset() const
|
|
{
|
|
const TString& sql = get(F_SQL);
|
|
TRecordset* rex = create_recordset(sql);
|
|
|
|
if (rex != NULL)
|
|
{
|
|
if (!ask_vars(get(F_CODICE), *rex))
|
|
{
|
|
delete rex;
|
|
rex = NULL;
|
|
}
|
|
|
|
if (rex != NULL && rex->items() == 0)
|
|
{
|
|
warning_box(TR("Nessuna riga risultato"));
|
|
delete rex;
|
|
rex = NULL;
|
|
}
|
|
}
|
|
|
|
return rex;
|
|
}
|
|
|
|
void TQuery_mask::edit_query()
|
|
{
|
|
TRecordset* rex = new_recordset();
|
|
if (rex != NULL)
|
|
{
|
|
TRecordset_sheet sht(*rex);
|
|
sht.run();
|
|
delete rex;
|
|
}
|
|
}
|
|
|
|
void TQuery_mask::save_as(TRecordsetExportFormat fmt, const char* ext)
|
|
{
|
|
TRecordset* rex = new_recordset();
|
|
if (rex == NULL)
|
|
return;
|
|
|
|
if (fmt == fmt_dbf)
|
|
{
|
|
TTable_mask tm;
|
|
TList_sheet& sht = *tm.efield(F_SON).sheet();
|
|
if (sht.run() == K_ENTER)
|
|
{
|
|
const TString& table = tm.get(F_SON);
|
|
const KEY k = yesnocancel_box(FR("Si desidera azzerare il file %s prima dell'esportazione?"),
|
|
(const char*)table);
|
|
if (k != K_ESC)
|
|
rex->save_as(table, fmt_dbf, k == K_YES ? 0x5 : 0x3);
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
xvt_fsys_save_dir();
|
|
TFilename path; path.tempdir();
|
|
|
|
if (ext == NULL || *ext == '\0')
|
|
{
|
|
switch (fmt)
|
|
{
|
|
case fmt_html: ext = "html"; break;
|
|
default : ext = "txt"; break;
|
|
}
|
|
}
|
|
|
|
if (field(F_CODICE).empty())
|
|
path.add("query");
|
|
else
|
|
path.add(get(F_CODICE));
|
|
path.ext(ext);
|
|
|
|
FILE_SPEC fs;
|
|
xvt_fsys_convert_str_to_fspec(path, &fs);
|
|
|
|
xvt_fsys_save_dir();
|
|
const bool good = xvt_dm_post_file_save(&fs, TR("Esportazione")) == FL_OK;
|
|
xvt_fsys_restore_dir();
|
|
|
|
if (good)
|
|
{
|
|
xvt_fsys_convert_fspec_to_str(&fs, path.get_buffer(), path.size());
|
|
if (rex->save_as(path, fmt))
|
|
xvt_sys_goto_url(path, "open");
|
|
}
|
|
|
|
delete rex;
|
|
}
|
|
|
|
bool TQuery_mask::get_qry_path(TFilename& path) const
|
|
{
|
|
const TString& name = get(F_CODICE);
|
|
const bool ok = name.full();
|
|
if (ok)
|
|
{
|
|
path = name;
|
|
if (!path.is_absolute_path())
|
|
{
|
|
path = firm2dir(-1);
|
|
path.add("custom");
|
|
if (!path.exist())
|
|
xvt_fsys_mkdir(path);
|
|
path.add(name);
|
|
}
|
|
path.ext("qry");
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TQuery_mask::select_query()
|
|
{
|
|
TFilename path;
|
|
const bool ok = select_custom_file(path, "qry");
|
|
if (ok)
|
|
{
|
|
path = path.name(); path.ext("");
|
|
set(F_CODICE, path);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
static bool xml_save_tree_handler(TTree& tree, void* jolly, word flags)
|
|
{
|
|
TXmlItem* rel = (TXmlItem*)jolly;
|
|
TRelation_node& node = (TRelation_node&)*tree.curr_node();
|
|
|
|
TXmlItem& son = rel->AddChild("table");
|
|
TString4 num; num << node.num();
|
|
son.SetAttr("Num", num);
|
|
son.SetAttr("Name", node.name());
|
|
if (node.alias().not_empty())
|
|
son.SetAttr("Alias", node.alias());
|
|
if (node.father() != NULL)
|
|
{
|
|
son.SetAttr("Father", node.father()->id());
|
|
FOR_EACH_ARRAY_ROW(node.join(), i, row)
|
|
{
|
|
if (i > 0)
|
|
son << "AND";
|
|
son << "(" << *row << ")";
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool TQuery_mask::save_tables_tree(TXmlItem& xml)
|
|
{
|
|
const bool ok = _tree.goto_root();
|
|
if (ok)
|
|
{
|
|
TXmlItem& rel = xml.AddChild("tables");
|
|
_tree.scan_depth_first(xml_save_tree_handler, &rel);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TQuery_mask::save_fields_sheet(TXmlItem& xml)
|
|
{
|
|
TSheet_field& sf = sfield(F_SHEET);
|
|
const bool ok = sf.items() > 0;
|
|
if (ok)
|
|
{
|
|
TXmlItem& fields = xml.AddChild("fields");
|
|
FOR_EACH_SHEET_ROW(sf, i, row)
|
|
{
|
|
TXmlItem& field = fields.AddChild("field");
|
|
field.SetAttr("Table", row->get(0));
|
|
field.SetAttr("Name", row->get(1));
|
|
field.SetAttr("Hidden", tok_get_bool(*row,2));
|
|
field.SetAttr("Sort", tok_get_bool(*row,3));
|
|
field.SetAttr("Group", tok_get_bool(*row,4));
|
|
const char* str = row->get(5);
|
|
if (str && *str > ' ')
|
|
field.SetAttr("ExprFrom", str);
|
|
str = row->get(6);
|
|
if (str && *str > ' ')
|
|
field.SetAttr("ExprTo", str);
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TQuery_mask::save_query()
|
|
{
|
|
bool ok = _curr_query.not_empty();
|
|
if (!ok)
|
|
ok = get_qry_path(_curr_query);
|
|
if (!ok)
|
|
return field(F_CODICE).on_key(K_ENTER); // Segnala errore
|
|
|
|
char name[_MAX_FNAME];
|
|
xvt_fsys_parse_pathname (_curr_query, NULL, NULL, name, NULL, NULL);
|
|
ok = *name > ' ';
|
|
if (ok)
|
|
{
|
|
TXmlItem xml;
|
|
xml.SetTag("query");
|
|
xml.SetAttr("Name", name);
|
|
xml.AddChild("description") << get(F_DESCR);
|
|
save_tables_tree(xml);
|
|
save_fields_sheet(xml);
|
|
xml.AddChild("sql") << get(F_SQL);
|
|
xml.Save(_curr_query);
|
|
_is_dirty = false;
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TQuery_mask::save_if_needed()
|
|
{
|
|
if (!_is_dirty || !field(DLG_SAVEREC).active())
|
|
return true;
|
|
if (!yesno_box(TR("Si desidera registrare la query?")))
|
|
return false;
|
|
|
|
return save_query();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Caricamento da file xml
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Carica l'albero della relazione
|
|
bool TQuery_mask::load_tables_tree(TXmlItem& tables)
|
|
{
|
|
for (int i = 0; i < tables.GetChildren(); i++)
|
|
{
|
|
const TXmlItem& table = *tables.GetChild(i);
|
|
const int num = atoi(table.GetAttr("Num"));
|
|
if (num >= LF_USER)
|
|
{
|
|
_tree.find_id(table.GetAttr("Father"));
|
|
const TRelation_node* father = (const TRelation_node*)_tree.curr_node();
|
|
TRelation_node* son = new TRelation_node(father, num, table.GetAttr("Alias"));
|
|
if (father != NULL)
|
|
{
|
|
TString expr; table.GetEnclosedText(expr);
|
|
int i = expr.find('(');
|
|
while (i >= 0)
|
|
{
|
|
const int j = expr.find(')', i+1);
|
|
TToken_string* eq = new TToken_string(expr.sub(i+1, j), '=');
|
|
son->join().add(eq);
|
|
i = expr.find('(', j+1);
|
|
}
|
|
}
|
|
_tree.add_son(son);
|
|
}
|
|
}
|
|
|
|
const bool ok = _tree.goto_root();
|
|
if (ok)
|
|
{
|
|
const TRelation_node* rn = (TRelation_node*)_tree.curr_node();
|
|
_curr_num = rn->num();
|
|
fill_fields();
|
|
_tree.expand_all();
|
|
tfield(F_TABLES).win().force_update();
|
|
}
|
|
enable_field_buttons();
|
|
|
|
return ok;
|
|
}
|
|
|
|
// Carica l'elenco dei campi (o colonne)
|
|
bool TQuery_mask::load_fields_sheet(TXmlItem& xml)
|
|
{
|
|
TSheet_field& sheet = sfield(F_SHEET);
|
|
TXmlItem* fields = xml.FindFirst("fields");
|
|
const bool ok = fields != NULL;
|
|
if (ok)
|
|
{
|
|
for (int i = 0; i < fields->GetChildren(); i++)
|
|
{
|
|
const TXmlItem& field = *fields->GetChild(i);
|
|
TToken_string& row = sheet.row(-1);
|
|
row.add(field.GetAttr("Table"),0);
|
|
row.add(field.GetAttr("Name"),1);
|
|
row.add(field.GetBoolAttr("Hidden") ? "X" : "",2);
|
|
row.add(field.GetBoolAttr("Sort") ? "X" : "",3);
|
|
row.add(field.GetBoolAttr("Group") ? "X" : "",4);
|
|
row.add(field.GetAttr("ExprFrom"),5);
|
|
row.add(field.GetAttr("ExprTo"),6);
|
|
}
|
|
sheet.force_update();
|
|
}
|
|
enable_sql_button();
|
|
return ok;
|
|
}
|
|
|
|
// Azzera tutto, ma proprio tutto
|
|
void TQuery_mask::global_reset()
|
|
{
|
|
if (_tree.goto_root())
|
|
{
|
|
_tree.kill_node();
|
|
TTree_field& tf = tfield(F_TABLES);
|
|
tf.select_current();
|
|
tf.win().force_update();
|
|
}
|
|
reset();
|
|
_is_dirty = _sql_dirty = false;
|
|
}
|
|
|
|
// Caica l'intera query
|
|
bool TQuery_mask::load_query()
|
|
{
|
|
TFilename path; get_qry_path(path);
|
|
bool ok = path.exist();
|
|
if (ok)
|
|
{
|
|
TXmlItem xml;
|
|
ok = xml.Load(path);
|
|
if (ok)
|
|
{
|
|
_curr_query = path;
|
|
global_reset();
|
|
|
|
path = path.name(); path.ext("");
|
|
set(F_CODICE, path);
|
|
|
|
const TXmlItem* desc = xml.FindFirst("description");
|
|
if (desc != NULL)
|
|
{
|
|
TString str; desc->GetEnclosedText(str);
|
|
set(F_DESCR, str);
|
|
}
|
|
|
|
TXmlItem* tables = xml.FindFirst("tables");
|
|
if (tables != NULL)
|
|
load_tables_tree(*tables);
|
|
|
|
load_fields_sheet(xml);
|
|
|
|
const TXmlItem* sql = xml.FindFirst("sql");
|
|
if (sql != NULL)
|
|
{
|
|
TString str; sql->GetEnclosedText(str);
|
|
set(F_SQL, str, true); // Aggiorna anche stato bottoni di esportazione
|
|
TEdit_field& sf = efield(F_SQL);
|
|
sf.set_dirty(false); // Evita falsi allarmi di registrazione
|
|
_sql_dirty = !sf.empty();
|
|
}
|
|
_is_dirty = false; // Resetta definitivamente il dirty
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TQuery_mask::delete_query()
|
|
{
|
|
TFilename path; get_qry_path(path);
|
|
const bool ok = yesno_box(FR("Si desidera eliminare il file %s"), (const char*)path);
|
|
if (ok)
|
|
{
|
|
::remove(path);
|
|
global_reset();
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
// Gestione eventi standard
|
|
bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
case F_CODICE:
|
|
if (e == fe_button)
|
|
{
|
|
if (select_query())
|
|
e = fe_modify;
|
|
}
|
|
if (e == fe_init || e == fe_modify)
|
|
{
|
|
save_if_needed();
|
|
load_query();
|
|
}
|
|
break;
|
|
case F_TABLES:
|
|
if (e == fe_modify)
|
|
{
|
|
const TRelation_node* rn = (TRelation_node*)_tree.curr_node();
|
|
if (rn && rn->num() != _curr_num)
|
|
{
|
|
_curr_num = rn->num();
|
|
fill_fields();
|
|
}
|
|
}
|
|
break;
|
|
case F_FIELDS:
|
|
if (e == se_query_modify || e == se_query_add || e == se_query_del)
|
|
return false;
|
|
enable_field_buttons();
|
|
break;
|
|
case F_ADDFILE:
|
|
if (e == fe_button)
|
|
add_file_to_tree();
|
|
break;
|
|
case F_EDITFILE:
|
|
if (e == fe_button)
|
|
edit_file_in_tree();
|
|
break;
|
|
case DLG_USER:
|
|
if (e == fe_button)
|
|
add_field_to_sheet();
|
|
break;
|
|
case F_ASTERISK:
|
|
if (e == fe_button)
|
|
add_asterisk_to_sheet();
|
|
break;
|
|
case F_GENSQL:
|
|
case F_GENISAM:
|
|
if (e == fe_button)
|
|
{
|
|
next_page(1001);
|
|
bool ok = true;
|
|
if (_sql_dirty && !field(F_SQL).empty())
|
|
ok = yesno_box(TR("Attenzione: la query verra' rigenerata\n"
|
|
"annullando eventuali modifiche manuali.\n"
|
|
"Si desidera proseguire?"));
|
|
if (ok)
|
|
{
|
|
if (o.dlg() == F_GENSQL)
|
|
sheet2sql();
|
|
else
|
|
sheet2isam();
|
|
}
|
|
}
|
|
break;
|
|
case F_EDITQUERY:
|
|
if (e == fe_button)
|
|
edit_query();
|
|
break;
|
|
case F_SQL:
|
|
if (e == fe_init || e == fe_modify)
|
|
{
|
|
const bool on = !o.empty();
|
|
enable(F_EXPORT_DBF, on && is_power_station());
|
|
if (e == fe_modify)
|
|
{
|
|
_is_dirty = true;
|
|
_sql_dirty = !o.empty();
|
|
}
|
|
}
|
|
break;
|
|
case F_EXPORT_HTML:
|
|
if (e == fe_button)
|
|
save_as(fmt_html);
|
|
break;
|
|
case F_EXPORT_EXCEL:
|
|
if (e == fe_button)
|
|
save_as(fmt_html, "xls");
|
|
break;
|
|
case F_EXPORT_TXT:
|
|
if (e == fe_button)
|
|
save_as(fmt_text);
|
|
break;
|
|
case F_EXPORT_CAMPO:
|
|
if (e == fe_button)
|
|
save_as(fmt_campo);
|
|
break;
|
|
case F_EXPORT_DBF:
|
|
if (e == fe_button)
|
|
save_as(fmt_dbf);
|
|
break;
|
|
case F_SHEET:
|
|
enable_sql_button();
|
|
break;
|
|
case F_MOVEUP:
|
|
if (e == fe_button)
|
|
move_curr_field(-1);
|
|
break;
|
|
case F_MOVEDN:
|
|
if (e == fe_button)
|
|
move_curr_field(+1);
|
|
break;
|
|
case DLG_NEWREC:
|
|
if (e == fe_button)
|
|
{
|
|
save_if_needed();
|
|
global_reset();
|
|
next_page(1000);
|
|
}
|
|
break;
|
|
case DLG_FINDREC:
|
|
if (e == fe_button)
|
|
send_key(K_F9, F_CODICE);
|
|
case DLG_SAVEREC:
|
|
if (e == fe_button)
|
|
{
|
|
get_qry_path(_curr_query);
|
|
save_query();
|
|
next_page(1000);
|
|
}
|
|
break;
|
|
case DLG_DELREC:
|
|
if (e == fe_button && jolly == 0) // Elimina della Toolbar
|
|
{
|
|
delete_query();
|
|
next_page(1000);
|
|
return false; // Do not exit!
|
|
}
|
|
break;
|
|
case DLG_QUIT:
|
|
save_if_needed();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Gestione eventi di trascinamento
|
|
long TQuery_mask::handler(WINDOW wnd, EVENT* ep)
|
|
{
|
|
switch (ep->type)
|
|
{
|
|
case E_MOUSE_DOWN:
|
|
if (ep->v.mouse.button == 0 && wnd == page_win(0))
|
|
{
|
|
const TSheet_field& sf = sfield(F_FIELDS);
|
|
RCT rct; sf.get_rect(rct);
|
|
_dragster = xvt_rect_has_point(&rct, ep->v.mouse.where) != 0;
|
|
}
|
|
else
|
|
_dragster = false;
|
|
if (_dragster)
|
|
{
|
|
XinCursor hand = xi_get_pref(XI_PREF_HAND_CURSOR_RID);
|
|
xvt_win_set_cursor(wnd, (CURSOR)hand);
|
|
}
|
|
else
|
|
xvt_win_set_cursor(wnd, CURSOR_ARROW);
|
|
break;
|
|
case E_MOUSE_UP:
|
|
if (ep->v.mouse.button == 0 && _dragster)
|
|
{
|
|
TSheet_field& ff = sfield(F_SHEET);
|
|
RCT rct; ff.get_rect(rct);
|
|
if (xvt_rect_has_point(&rct, ep->v.mouse.where))
|
|
add_field_to_sheet();
|
|
xvt_win_set_cursor(wnd, CURSOR_ARROW);
|
|
}
|
|
_dragster = false;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return TAutomask::handler(wnd, ep);
|
|
}
|
|
|
|
TQuery_mask::TQuery_mask() : TAutomask("ba8200a"), _curr_num(0), _is_dirty(false)
|
|
{
|
|
RCT rcts, rctf, rctt;
|
|
|
|
TSheet_field& sheet = sfield(F_SHEET);
|
|
sheet.get_rect(rcts);
|
|
|
|
// Allarga a dritta lo spreadsheet coi noi dei campi
|
|
TSheet_field& fields = sfield(F_FIELDS);
|
|
fields.get_rect(rctf);
|
|
rctf.right = rcts.right;
|
|
fields.set_rect(rctf);
|
|
|
|
// Allarga a mancina l'albero della relazione
|
|
TTree_field& trf = tfield(F_TABLES);
|
|
trf.get_rect(rctt);
|
|
rctt.top -= 4;
|
|
rctt.left = rcts.left+4;
|
|
rctt.right -= 32; // Toglie scrollbar
|
|
rctt.bottom = rctf.bottom - 32;
|
|
trf.set_rect(rctt);
|
|
|
|
trf.set_tree(&_tree); // Associa l'albero al campo della maschera
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TSQL_recordset_app
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TSQL_recordset_app : public TSkeleton_application
|
|
{
|
|
TQuery_mask* _msk;
|
|
|
|
public:
|
|
virtual bool create();
|
|
virtual void main_loop();
|
|
virtual bool destroy();
|
|
};
|
|
|
|
bool TSQL_recordset_app::create()
|
|
{
|
|
if (!has_module(RSAUT))
|
|
return error_box(TR("Modulo non autorizzato"));
|
|
|
|
_msk = new TQuery_mask;
|
|
xvt_sys_sleep(500); // Lasciamo il tempo di leggere il titolo
|
|
|
|
if (argc() > 2)
|
|
{
|
|
_msk->set(F_CODICE, argv(2));
|
|
_msk->load_query();
|
|
|
|
if (argc() > 3)
|
|
{
|
|
switch (argv(3)[0])
|
|
{
|
|
case 'H':
|
|
_msk->save_as(fmt_html);
|
|
break;
|
|
case 'T':
|
|
_msk->save_as(fmt_text);
|
|
break;
|
|
case 'X':
|
|
_msk->save_as(fmt_html, "xls");
|
|
break;
|
|
case 'C':
|
|
_msk->save_as(fmt_campo);
|
|
break;
|
|
default :
|
|
_msk->save_as(fmt_html);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
_msk->edit_query();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TSkeleton_application::create();
|
|
}
|
|
|
|
void TSQL_recordset_app::main_loop()
|
|
{
|
|
if (argc() > 2)
|
|
{
|
|
_msk->set(F_CODICE, argv(2)); // Carico la query da riga di comando
|
|
_msk->disable(DLG_SAVEREC); // Non permetto modifiche di alcun genere
|
|
_msk->disable(DLG_NEWREC);
|
|
_msk->disable(DLG_DELREC);
|
|
_msk->disable(DLG_FINDREC);
|
|
}
|
|
_msk->run();
|
|
}
|
|
|
|
bool TSQL_recordset_app::destroy()
|
|
{
|
|
if (_msk != NULL)
|
|
{
|
|
delete _msk;
|
|
_msk = NULL;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int ba8200(int argc, char* argv[])
|
|
{
|
|
TSQL_recordset_app app;
|
|
app.run(argc, argv, TR("Query Generator"));
|
|
return 0;
|
|
} |