Patch level : 2.1 nopatch

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :

Aggiunta gestione limiti di stampa


git-svn-id: svn://10.65.10.50/trunk@11947 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2004-04-08 15:04:14 +00:00
parent 82a4637049
commit 591c49e4c5
14 changed files with 388 additions and 88 deletions

View File

@ -738,7 +738,10 @@ bool TQuery_mask::get_qry_path(TFilename& path) const
const bool ok = name.not_empty();
if (ok)
{
get_sql_directory(path);
path = firm2dir(-1);
path.add("custom");
if (!path.exist())
xvt_fsys_mkdir(path);
path.add(name);
path.ext("qry");
}
@ -748,7 +751,7 @@ bool TQuery_mask::get_qry_path(TFilename& path) const
bool TQuery_mask::select_query()
{
TFilename path;
const bool ok = select_sql_file(path, "qry");
const bool ok = select_custom_file(path, "qry");
if (ok)
{
path = path.name(); path.ext("");

View File

@ -38,9 +38,9 @@ ENDPAGE
PAGE "Query" -1 -1 78 23
STRING F_CODICE 16
STRING F_CODICE 128 24
BEGIN
PROMPT 1 0 "Codice "
PROMPT 1 0 ""
FLAGS "B"
WARNING "E' necessario specificare il codice"
CHECKTYPE REQUIRED

View File

@ -235,21 +235,34 @@ TVariant& TVariant::sub(const TVariant& var)
return *this;
}
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
static bool is_numeric(const char* str)
{
if (str == NULL || *str == '\0' || *str == '0')
return false; // Se comincia per zero va preservato!
if (*str == '-')
{
str++;
if (*str <= ' ')
return false;
}
while (*str)
{
if (strchr("0123456789.", *str) == NULL)
return false;
str++;
}
return true;
}
///////////////////////////////////////////////////////////
// TRecordset
///////////////////////////////////////////////////////////
const TVariant& TRecordset::get(const char* column_name) const
{
for (unsigned int i = 0; i < columns(); i++)
{
const TRecordset_column_info& info = column_info(i);
if (info._name == column_name)
return get(i);
}
return NULL_VARIANT;
}
const TString& TRecordset::query_text() const
{
return EMPTY_STRING;
@ -472,21 +485,97 @@ bool TRecordset::save_as(const char* path, TRecordsetExportFormat fmt)
return ok;
}
const TVariant& TRecordset::get(const char* column_name) const
{
if (*column_name == '#' && variables().items() > 0)
return get_var(column_name);
for (unsigned int i = 0; i < columns(); i++)
{
const TRecordset_column_info& info = column_info(i);
if (info._name == column_name)
return get(i);
}
return NULL_VARIANT;
}
const TVariant& TRecordset::get_var(const char* name) const
{
const TVariant* var = (const TVariant*)_var.objptr(name);
return var != NULL ? *var : NULL_VARIANT;
}
bool TRecordset::set_var(const char* name, const TVariant& var, bool create)
{
bool ok = false;
TVariant* old = (TVariant*)_var.objptr(name);
if (old != NULL)
{
*old = var;
ok = true;
}
else
{
if (create)
{
_var.add(name, var);
_varnames.add(name);
ok = true;
}
}
return ok;
}
bool ask_variable(const char* name, TVariant& var)
{
TMask m("Richiesta variabile", 1, 52, 4);
m.add_static(-1, 0, name, 1, 0);
m.add_string(101, 0, "", 1, 1, 80, "", 50);
m.add_button(DLG_OK, 0, "", -12, -1, 10, 2);
m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
m.set(101, var.as_string());
const bool ok = m.run() == K_ENTER;
if (ok)
{
const TString& str = m.get(101);
if (is_numeric(str))
var = real(str);
else
var = str;
}
return ok;
}
bool TRecordset::ask_variables(bool all) const
{
const bool ok = variables().items() > 0;
if (ok) // Se ci sono variabili faccio le sostituzioni
{
FOR_EACH_ARRAY_ROW(_varnames, i, name)
{
TVariant var = get_var(*name);
if (var.is_null() || all) // Mi serve assolutamente un valore!
{
ask_variable(*name, var);
((TSQL_recordset*)this)->set_var(*name, var);
}
}
}
return ok;
}
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
void get_sql_directory(TFilename& name)
bool select_custom_file(TFilename& path, const char* ext)
{
name = firm2dir(-1);
name.add("sql");
if (!name.exist())
make_dir(name);
}
TFilename custom = firm2dir(-1);
custom.add("custom");
if (!custom.exist())
xvt_fsys_mkdir(custom);
bool select_sql_file(TFilename& path, const char* ext)
{
get_sql_directory(path);
path = custom;
path.add("*");
path.ext(ext);
@ -521,7 +610,7 @@ bool select_sql_file(TFilename& path, const char* ext)
const bool ok = sheet.run() == K_ENTER;
if (ok)
{
get_sql_directory(path);
path = custom;
path.add(sheet.row(-1).get(0));
path.ext(ext);
}
@ -569,6 +658,14 @@ public:
virtual ~TSQLite();
} _TheDataBase;
void get_sql_directory(TFilename& name)
{
name = firm2dir(-1);
name.add("sql");
if (!name.exist())
make_dir(name);
}
void TSQLite::build_curr_path(TFilename& name) const
{
TString16 firm; firm.format("%05ldA.sql", prefix().get_codditta());
@ -841,6 +938,13 @@ bool TSQLite::import(int logicnum)
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)
{
test_path();
@ -887,25 +991,6 @@ TSQLite::~TSQLite()
// TSQL_recordset
///////////////////////////////////////////////////////////
static bool is_numeric(const char* str)
{
if (str == NULL || *str == '\0' || *str == '0')
return false; // Se comincia per zero va preservato!
if (*str == '-')
{
str++;
if (*str <= ' ')
return false;
}
while (*str)
{
if (strchr("0123456789.", *str) == NULL)
return false;
str++;
}
return true;
}
void TSQL_recordset::reset()
{
_firstrow = _items = 0;
@ -951,10 +1036,39 @@ static int query_get_items(void* jolly, int argc, char** values, char** columns)
return SQLITE_OK;
}
void TSQL_recordset::parsed_sql_text(TString& sql) const
{
sql = _sql;
if (ask_variables(false)) // 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.type() == _alfafld && s[0] != '\'') || var.is_null())
{
s.insert("'");
s << '\'';
}
sql << s << after;
}
}
}
}
TRecnotype TSQL_recordset::items() const
{
if (_items == 0)
_TheDataBase.exec(_sql, query_get_items, (TSQL_recordset*)this);
{
TString sql; parsed_sql_text(sql);
_TheDataBase.exec(sql, query_get_items, (TSQL_recordset*)this);
}
return _items;
}
@ -995,7 +1109,7 @@ bool TSQL_recordset::move_to(TRecnotype n)
if (n < _firstrow || n >= _firstrow+_page.items())
{
TString sql = _sql;
TString sql; parsed_sql_text(sql);
if (sql.find("LIMIT ") < 0)
{
const int semicolon = sql.rfind(';');
@ -1040,7 +1154,27 @@ void TSQL_recordset::set(const char* sql)
reset();
_sql = sql;
if (_sql.find("SELECT") >= 0 || _sql.find("select") >= 0)
{
_TheDataBase.parse_select_from(_sql);
// 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);
}
}
}
}
}
TSQL_recordset::TSQL_recordset(const char* sql)

View File

@ -1,6 +1,10 @@
#ifndef __RECORDSET_H
#define __RECORDSET_H
#ifndef __ASSOC_H
#include <assoc.h>
#endif
#ifndef __RECTYPES_H
#include <rectypes.h>
#endif
@ -80,6 +84,9 @@ enum TRecordsetExportFormat { fmt_unknown, fmt_html, fmt_text, fmt_silk, fmt_cam
class TRecordset : public TObject
{
TAssoc_array _var;
TString_array _varnames;
protected:
bool save_as_html(const char* path);
bool save_as_silk(const char* path);
@ -102,6 +109,11 @@ public: // Absolutely needed methods
virtual const TRecordset_column_info& column_info(unsigned int column) const pure;
virtual const TVariant& get(unsigned int column) const pure;
virtual const TString_array& variables() const { return _varnames; }
virtual const TVariant& get_var(const char* name) const;
virtual bool set_var(const char* name, const TVariant& var, bool create = false);
bool ask_variables(bool all) const;
virtual const TString& query_text() const;
virtual const TVariant& get(const char* column_name) const;
virtual const TToken_string& sheet_head() const;
@ -123,6 +135,7 @@ class TSQL_recordset : public TRecordset
protected:
void reset();
void parsed_sql_text(TString& sql) const;
public: // TRecordset
virtual TRecnotype items() const;
@ -164,8 +177,7 @@ public:
// Utility
///////////////////////////////////////////////////////////
void get_sql_directory(TFilename& path);
bool select_sql_file(TFilename& path, const char* ext);
bool select_custom_file(TFilename& path, const char* ext);
#endif

View File

@ -535,6 +535,8 @@ void TReport_properties_mask::set_report(const TReport& r)
{
set(F_DY, r.lpi());
set_font_info(r.font());
set(F_PRESCRIPT, r.prescript());
set(F_POSTSCRIPT, r.postscript());
}
void TReport_properties_mask::get_report(TReport& r) const
@ -544,6 +546,8 @@ void TReport_properties_mask::get_report(TReport& r) const
TReport_font f;
if (get_font_info(f))
r.set_font(f);
r.set_prescript(get(F_PRESCRIPT));
r.set_postscript(get(F_POSTSCRIPT));
}
///////////////////////////////////////////////////////////
@ -600,7 +604,7 @@ TMask_field* TReport_mask::parse_field(TScanner& scanner)
bool TReport_mask::select_report()
{
TFilename path;
const bool ok = select_sql_file(path, "rep");
const bool ok = select_custom_file(path, "rep");
if (ok)
{
path = path.name(); path.ext("");
@ -612,7 +616,7 @@ bool TReport_mask::select_report()
bool TReport_mask::select_query()
{
TFilename path;
bool ok = select_sql_file(path, "qry");
bool ok = select_custom_file(path, "qry");
if (ok)
{
TXmlItem item; item.Load(path);
@ -633,7 +637,10 @@ bool TReport_mask::get_rep_path(TFilename& path) const
const bool ok = name.not_empty();
if (ok)
{
get_sql_directory(path);
path = firm2dir(-1);
path.add("custom");
if (!path.exist())
xvt_fsys_mkdir(path);
path.add(name);
path.ext("rep");
}
@ -717,10 +724,7 @@ bool TReport_mask::delete_report()
void TReport_mask::on_print()
{
TReport_printer rp(_report);
if (printer().printtype() == screenvis)
rp.preview();
else
rp.print();
rp.print(printer().printtype() == screenvis);
}
TReport_section& TReport_mask::curr_section()

View File

@ -43,9 +43,9 @@ ENDPAGE
PAGE "@bReport" -1 -1 78 23
STRING F_CODICE 16
STRING F_CODICE 128 24
BEGIN
PROMPT 1 0 "Report "
PROMPT 1 0 ""
FLAGS "B"
WARNING "E' necessario specificare il codice"
CHECKTYPE REQUIRED

View File

@ -103,6 +103,7 @@ BEGIN
PROMPT -33 -1 ""
END
ENDPAGE
ENDMASK

View File

@ -25,5 +25,29 @@ END
ENDPAGE
PAGE "Avanzate" -1 -1 50 16
MEMO F_PRESCRIPT 48 6
BEGIN
PROMPT 1 0 "Script iniziale"
END
MEMO F_POSTSCRIPT 48 5
BEGIN
PROMPT 1 6 "Script finale"
END
BUTTON DLG_CANCEL 10 2
BEGIN
PROMPT -13 -1 ""
END
BUTTON DLG_OK 10 2
BEGIN
PROMPT -33 -1 ""
END
ENDPAGE
ENDMASK

View File

@ -1,6 +1,7 @@
#include <colors.h>
#include <expr.h>
#include <image.h>
#include <relation.h>
#include <xml.h>
#include "ba8201.h"
@ -694,8 +695,8 @@ void TReport_script::set(const char* source)
bool TReport_script::execute(TReport& rep, TString& output)
{
bool good = ok();
if (good)
bool good = true;
if (ok())
{
if (_bc == NULL)
{
@ -713,8 +714,8 @@ bool TReport_script::execute(TReport& rep, TString& output)
bool TReport_script::execute(TReport_field& rf)
{
bool good = ok();
if (good)
bool good = true;
if (ok())
{
TString str;
TReport& rep = rf.section().report();
@ -1396,6 +1397,9 @@ bool TReport::load(const char* fname)
sql->GetEnclosedText(str);
set_recordset(str);
}
_prescript.load(xml, "prescript");
_postscript.load(xml, "postscript");
}
return ok;
}
@ -1427,6 +1431,10 @@ bool TReport::save(const char* fname) const
if (_recordset != NULL)
xml.AddChild("sql") << _recordset->query_text();
_prescript.save(xml, "prescript");
_postscript.save(xml, "postscript");
xml.Save(fname);
}
return ok;
@ -1443,9 +1451,32 @@ void TReport::unmap_font()
}
bool TReport::execute_prescript()
{
bool ok = true;
if (_prescript.ok())
{
TString80 str;
return _prescript.execute(*this, str);
ok = _prescript.execute(*this, str);
}
else
{
// Script dei poveri: lancia la maschera associata al report
TFilename msk = _path; msk.ext("msk");
if (msk.exist())
{
const KEY key = run_form(msk.name());
ok = key != K_ESC && key != K_QUIT;
}
else
{
// Script dei poverissimi: chiede le eventuali variabili
if (recordset() != NULL)
recordset()->ask_variables(true);
}
}
return ok;
}
bool TReport::execute_postscript()
@ -1471,12 +1502,6 @@ bool TReport::get_usr_val(const TString& name, TVariant& var) const
if (_recordset != NULL)
{
if (name[0] == '#')
{
const TFixed_string str((const char*)name + 1);
var = _recordset->get(str);
}
else
var = _recordset->get(name);
if (!var.is_null())
return true;
@ -1498,9 +1523,10 @@ bool TReport::set_usr_val(const TString& name, const TVariant& var)
unsigned int TReport::compile_usr_word(const TString& name) const
{
const int words = 9;
const int words = 10;
const char* const names[words] = { NULL, "DISABLE", "ENABLE", "GET_SIZE", "HIDE",
"SET_BACK_COLOR", "SET_FORE_COLOR", "SET_SIZE", "SHOW" };
"RUN_FORM", "SET_BACK_COLOR", "SET_FORE_COLOR",
"SET_SIZE", "SHOW" };
int i;
for (i = words-1; i > 0; i--)
if (name == names[i])
@ -1566,6 +1592,61 @@ bool TReport::do_message(const TVariant& var, FLDMSG_FUNC msg, void* jolly)
return true;
}
KEY TReport::run_form(const TString& maskname)
{
TFilename fname = maskname; fname.ext("msk");
KEY key = K_QUIT;
if (fname.custom_path())
{
TMask m(maskname);
TVariant var;
for (int i = m.fields()-1; i >= 0; i--)
{
TMask_field& f = m.fld(i);
const TFieldref* ref = f.field();
if (ref != NULL)
{
TString name = ref->name();
if (name[0] != '#')
name.insert("#");
if (get_usr_val(name, var))
f.set(var.as_string());
}
}
key = m.run();
if (key != K_QUIT && key != K_ESC)
{
TRecordset* rset = recordset();
if (rset != NULL && rset->variables().items() == 0)
rset = NULL;
// Rendi visibili tutte le variabili utente al report
for (int i = m.fields()-1; i >= 0; i--)
{
TMask_field& f = m.fld(i);
const TFieldref* ref = f.field();
if (ref != NULL)
{
switch (f.class_id())
{
case CLASS_CURRENCY_FIELD:
case CLASS_REAL_FIELD: var = real(f.get()); break;
case CLASS_DATE_FIELD: var = TDate(f.get()); break;
default: var = f.get(); break;
}
TString name = ref->name();
if (name[0] != '#')
name.insert("#");
set_usr_val(name, var);
if (rset != NULL)
rset->set_var(name, var);
}
}
}
}
return key;
}
bool TReport::execute_usr_word(unsigned int opcode, TVariant_stack& stack)
{
switch (opcode)
@ -1591,19 +1672,26 @@ bool TReport::execute_usr_word(unsigned int opcode, TVariant_stack& stack)
case 4: // HIDE
do_message(stack.pop(), do_show, NULL);
break;
case 5: // SET_BACK_COLOR
case 5: // RUN_FORM
{
const TString& msk = stack.pop().as_string();
const KEY key = run_form(msk);
stack.push(key);
}
break;
case 6: // SET_BACK_COLOR
{
const COLOR rgb = stack.pop().as_color();
do_message(stack.pop(), do_set_back_color, (void*)rgb);
}
break;
case 6: // SET_FORE_COLOR
case 7: // SET_FORE_COLOR
{
const COLOR rgb = stack.pop().as_color();
do_message(stack.pop(), do_set_fore_color, (void*)rgb);
}
break;
case 7: // SET_SIZE
case 8: // SET_SIZE
{
const TVariant& fld = stack.pop();
const real h = stack.pop().as_real() * CENTO;
@ -1612,7 +1700,7 @@ bool TReport::execute_usr_word(unsigned int opcode, TVariant_stack& stack)
do_message(fld, do_set_size, (void*)&sz);
}
break;
case 8: // SHOW
case 9: // SHOW
do_message(stack.pop(), do_show, (void*)1);
break;
default:

View File

@ -337,6 +337,7 @@ protected:
virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack);
virtual bool get_usr_val(const TString& name, TVariant& var) const;
virtual bool set_usr_val(const TString& name, const TVariant& var);
KEY run_form(const TString& msk);
int parse_field(const char* code, char& type, int& level, int& id) const;
bool do_message(const TVariant& var, FLDMSG_FUNC msg, void* jolly);

View File

@ -418,7 +418,7 @@ static BOOLEAN main_loop_callback(long jolly)
return pp->main_loop();
}
bool TPage_printer::print()
bool TPage_printer::do_print()
{
bool ok = ask_pages();
if (ok)
@ -433,7 +433,7 @@ void TPage_printer::print_page(word page)
print_loop();
}
bool TPage_printer::preview()
bool TPage_printer::do_preview()
{
TPrinter& p = printer();
_rcd = p.get_printrcd();
@ -462,6 +462,11 @@ bool TPage_printer::preview()
return true;
}
bool TPage_printer::print(bool prev_mode)
{
return prev_mode ? do_preview() : do_print();
}
TPoint TPage_printer::page_size() const
{
return TPoint(_pw, _ph);
@ -681,3 +686,15 @@ bool TReport_printer::print_loop()
return true;
}
bool TReport_printer::print(bool preview_mode)
{
bool ok = _report.execute_prescript();
if (ok)
{
ok = TPage_printer::print(preview_mode);
if (ok)
_report.execute_postscript();
}
return ok;
}

View File

@ -35,16 +35,19 @@ protected:
virtual bool close_page();
bool page_in_range() const;
// Called by print(bool)
virtual bool do_print();
virtual bool do_preview();
public:
bool main_loop(); // Internal use only
virtual bool print(); // Use this ...
virtual bool preview(); // ... and this
virtual void print_page(word page); // Inefficient default implementation
virtual TPoint page_size() const;
virtual TPoint page_res() const;
virtual word last_printed_page() { return _lastprinted; }
virtual bool print(bool preview = false);
bool print_mode() const { return _preview_mask == NULL; }
bool preview_mode() const { return _preview_mask != NULL; }
@ -74,6 +77,8 @@ protected:
long print_section(char type, int level);
public:
virtual bool print(bool preview = false);
TReport_printer(TReport& r) : _report(r) { }
};

View File

@ -380,7 +380,12 @@ bool TAVM::execute(const TBytecode& bc, ostream& outstr)
break;
case avm_swap: _stack.roll(1); break;
case avm_then: break;
case avm_usrword: _vm->execute_usr_word(op.var().as_int(), _stack); break;
case avm_usrword:
{
const long usrword = op.var().as_int();
_vm->execute_usr_word(usrword, _stack);
}
break;
default:
_last_error << "Bad op code: " << op.op() << '\n';
log_error(_last_error);
@ -394,6 +399,13 @@ bool TAVM::execute(const TBytecode& bc, ostream& outstr)
// TAlex_virtual_machine
///////////////////////////////////////////////////////////
TAVM& TAlex_virtual_machine::avm()
{
if (_avm == NULL)
_avm = new TAVM(this);
return *_avm;
}
const TString& TAlex_virtual_machine::get_last_error() const
{
if (_avm != NULL)
@ -403,16 +415,12 @@ const TString& TAlex_virtual_machine::get_last_error() const
bool TAlex_virtual_machine::compile(istream& instr, TBytecode& bc)
{
if (_avm == NULL)
_avm = new TAVM(this);
return _avm->compile(instr, bc);
return avm().compile(instr, bc);
}
bool TAlex_virtual_machine::execute(const TBytecode& bc, ostream& outstr)
{
if (_avm == NULL)
_avm = new TAVM(this);
return _avm->execute(bc, outstr);
return avm().execute(bc, outstr);
}
bool TAlex_virtual_machine::compile(const char* cmd, TBytecode& bc)

View File

@ -43,6 +43,9 @@ class TAlex_virtual_machine : public TObject
{
TAVM* _avm; // Chesire's cat class
protected:
TAVM& avm();
public:
virtual unsigned int compile_usr_word(const TString& name) const;
virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack);