Patch level :
Files correlati : Ricompilazione Demo : [ ] Commento : Gestione postino e permessi di esecuzione git-svn-id: svn://10.65.10.50/trunk@7553 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
6e30f9c6dd
commit
1855e56994
@ -60,15 +60,10 @@ TField_event TAutomask::key2event(TMask_field& f, KEY key) const
|
||||
if (!f.is_edit())
|
||||
{
|
||||
const TMask& wm = f.mask();
|
||||
if (wm.is_running())
|
||||
{
|
||||
if (f.is_kind_of(CLASS_BUTTON_FIELD))
|
||||
fe = fe_button;
|
||||
else
|
||||
fe = fe_modify;
|
||||
}
|
||||
if (f.is_kind_of(CLASS_BUTTON_FIELD))
|
||||
fe = fe_button;
|
||||
else
|
||||
fe = fe_init;
|
||||
fe = wm.is_running() ? fe_modify : fe = fe_init;
|
||||
}
|
||||
break;
|
||||
case K_ENTER:
|
||||
|
@ -113,7 +113,7 @@ void TConfig::_write_file()
|
||||
|
||||
bool skip = FALSE, done = FALSE, skip_empty = TRUE;
|
||||
|
||||
while (!in.eof())
|
||||
while (in && !in.eof())
|
||||
{
|
||||
in.getline(l.get_buffer(), l.size());
|
||||
l.trim();
|
||||
|
@ -293,21 +293,13 @@ void customize_colors()
|
||||
FOCUS_COLOR = colors.get_color("Focus", NULL, -1, FOCUS_COLOR);
|
||||
FOCUS_BACK_COLOR = colors.get_color("FocusBack", NULL, -1, FOCUS_BACK_COLOR);
|
||||
TOOL_BACK_COLOR = colors.get_color("ToolBack", NULL, -1, MASK_DARK_COLOR);
|
||||
CAMPI_SCAVATI = colors.get_bool("Campi3D", NULL, -1, (bool)CAMPI_SCAVATI);
|
||||
AUTOSELECT = colors.get_bool("AutoSelect", NULL, -1, (bool)AUTOSELECT);
|
||||
CAMPI_SCAVATI = colors.get_bool("Campi3D", NULL, -1, CAMPI_SCAVATI);
|
||||
AUTOSELECT = colors.get_bool("AutoSelect", NULL, -1, AUTOSELECT);
|
||||
|
||||
xi_set_pref(XI_PREF_NATIVE_CTRLS, FALSE);
|
||||
xi_set_pref(XI_PREF_3D_LOOK, TRUE);
|
||||
|
||||
xi_set_pref(XI_PREF_COLOR_LIGHT, MASK_LIGHT_COLOR);
|
||||
xi_set_pref(XI_PREF_COLOR_CTRL, MASK_BACK_COLOR);
|
||||
xi_set_pref(XI_PREF_COLOR_DARK, MASK_DARK_COLOR);
|
||||
xi_set_pref(XI_PREF_COLOR_DISABLED, DISABLED_COLOR);
|
||||
#ifdef XI_R4
|
||||
xi_set_pref(XI_PREF_COMBO_ICON, ICO_COMBO);
|
||||
#else
|
||||
xi_set_pref(XI_PREF_COMBO_ICON, COMBO_ICON);
|
||||
#endif
|
||||
|
||||
BTN_BACK_COLOR = colors.get_color("ButtonBack", NULL, -1, BTN_BACK_COLOR);
|
||||
aga_set_pref(AGA_PREF_BTN_COLOR_CTRL, BTN_BACK_COLOR);
|
||||
@ -330,7 +322,15 @@ void init_controls()
|
||||
{
|
||||
xi_set_font_id(xvt_load_default_font());
|
||||
|
||||
xi_set_pref(XI_PREF_NATIVE_CTRLS, FALSE);
|
||||
xi_set_pref(XI_PREF_3D_LOOK, TRUE);
|
||||
xi_set_pref(XI_PREF_CARET_WIDTH, 2);
|
||||
#ifdef XI_R4
|
||||
xi_set_pref(XI_PREF_COMBO_ICON, ICO_COMBO);
|
||||
xi_set_pref(XI_PREF_OPTIMIZE_CELL_REQUESTS, TRUE);
|
||||
#else
|
||||
xi_set_pref(XI_PREF_COMBO_ICON, COMBO_ICON);
|
||||
#endif
|
||||
|
||||
xi_init();
|
||||
|
||||
@ -1205,19 +1205,25 @@ void TField_control::create(WINDOW win, short cid,
|
||||
def->app_data = (long)this;
|
||||
XI_FIELD_DEF* f = def->v.field;
|
||||
f->well = CAMPI_SCAVATI;
|
||||
f->auto_tab = TRUE;
|
||||
f->active_back_color = FOCUS_BACK_COLOR;
|
||||
if (button)
|
||||
|
||||
if (height == 1)
|
||||
{
|
||||
f->button = TRUE;
|
||||
f->pixel_button_distance = 1;
|
||||
f->auto_tab = TRUE;
|
||||
if (button)
|
||||
{
|
||||
f->button = TRUE;
|
||||
f->pixel_button_distance = 1;
|
||||
}
|
||||
}
|
||||
if (height != 1) // E' un multiline, quindi setto il rettangolo
|
||||
else // E' un multiline, quindi setto il rettangolo
|
||||
{
|
||||
f->xi_rct.top = rct.top;
|
||||
f->xi_rct.bottom = rct.bottom;
|
||||
f->xi_rct.right = rct.right;
|
||||
f->xi_rct.left = rct.left;
|
||||
f->cr_ok = TRUE;
|
||||
f->var_len_text = TRUE;
|
||||
}
|
||||
|
||||
XI_OBJ* itf = get_interface(win);
|
||||
|
@ -204,17 +204,17 @@ bool TDongle::hardlock_login(bool test_all_keys)
|
||||
if (test_all_keys)
|
||||
{
|
||||
HL_LOGOUT();
|
||||
if (HL_LOGIN(AGAADR, DONT_CARE, REFKEY, VERKEY) == STATUS_OK)
|
||||
if (HL_LOGIN(AGAADR, LOCAL_DEVICE, REFKEY, VERKEY) == STATUS_OK)
|
||||
_type = _aga_dongle;
|
||||
else
|
||||
{
|
||||
HL_LOGOUT();
|
||||
if (HL_LOGIN(PRASSIADR, DONT_CARE, REFKEY, VERKEY) == STATUS_OK)
|
||||
if (HL_LOGIN(PRASSIADR, LOCAL_DEVICE, REFKEY, VERKEY) == STATUS_OK)
|
||||
_type = _prassi_dongle;
|
||||
else
|
||||
{
|
||||
HL_LOGOUT();
|
||||
if (HL_LOGIN(PROCOMADR, DONT_CARE, REFKEY, VERKEY) == STATUS_OK)
|
||||
if (HL_LOGIN(PROCOMADR, LOCAL_DEVICE, REFKEY, VERKEY) == STATUS_OK)
|
||||
_type = _procom_dongle;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <execp.h>
|
||||
#include <os_dep.h>
|
||||
#include <prefix.h>
|
||||
#include <recarray.h>
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
@ -53,50 +54,6 @@ word TExternal_app::run(
|
||||
xvt_fsys_set_dir(&d);
|
||||
}
|
||||
|
||||
/* Gestione programmi spezzati
|
||||
if (our_app)
|
||||
{
|
||||
TString parms(_path);
|
||||
TString new_suffix;
|
||||
int p = parms.find(' ');
|
||||
|
||||
if (p < 0)
|
||||
{
|
||||
parms = "";
|
||||
new_suffix = "_0";
|
||||
}
|
||||
else
|
||||
{
|
||||
parms = parms.mid(p + 1);
|
||||
p = parms.find(' ');
|
||||
if (p >= 0)
|
||||
new_suffix = parms.left(p);
|
||||
else new_suffix = parms;
|
||||
if (new_suffix[0] == '-') new_suffix[0] = '_';
|
||||
else new_suffix = "__";
|
||||
}
|
||||
|
||||
TFilename newpath(dir);
|
||||
|
||||
if (newpath.not_empty())
|
||||
newpath << '/';
|
||||
newpath << name << new_suffix;
|
||||
newpath.ext("exe");
|
||||
if (fexist(newpath))
|
||||
{
|
||||
newpath.ext("");
|
||||
newpath << parms;
|
||||
path = newpath;
|
||||
if (utente)
|
||||
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
|
||||
path << " /u" << user();
|
||||
#else
|
||||
path << " -u" << user();
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!async)
|
||||
safely_close_closeable_isamfiles();
|
||||
|
||||
@ -124,6 +81,31 @@ word TExternal_app::run(
|
||||
return _exitcode;
|
||||
}
|
||||
|
||||
bool TExternal_app::can_run() const
|
||||
{
|
||||
TRecord_cache users(LF_USER);
|
||||
TToken_string perm(4096, '\n'), row(80);
|
||||
for (TString16 u = user();
|
||||
u.not_empty() && !users.already_loaded(u);
|
||||
u = users.get(u, "GROUPNAME"))
|
||||
{
|
||||
perm = users.get(u, "PERMISSION");
|
||||
if (!perm.blank())
|
||||
{
|
||||
FOR_EACH_TOKEN(perm, tok)
|
||||
{
|
||||
row = tok;
|
||||
if (_path == row.get(0)) // Il nome corrisponde
|
||||
{
|
||||
if (*row.get(1) == 'N')
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TExternal_app::TExternal_app(const char* p)
|
||||
: _path(p), _exitcode(0)
|
||||
{
|
||||
|
@ -32,6 +32,8 @@ protected:
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Controlla se l'utente puo' eseguire il programma
|
||||
bool can_run() const;
|
||||
// @cmember Esegue il processo
|
||||
word run(bool async = FALSE, byte user = TRUE, bool iconize = TRUE, bool show = TRUE);
|
||||
// @cmember Ritorna l'ultimo codice di uscita
|
||||
|
148
include/expr.cpp
148
include/expr.cpp
@ -84,7 +84,6 @@ const real& TVararray::getnum(const char* name)
|
||||
for (int i = items()-1; i >= 0; i--)
|
||||
{
|
||||
const TVar* var = (const TVar*)objptr(i);
|
||||
CHECKS(var, "Variabile NULLA ", name);
|
||||
if (strcmp(var->getname(), name) == 0)
|
||||
return var->number();
|
||||
}
|
||||
@ -92,16 +91,19 @@ const real& TVararray::getnum(const char* name)
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
|
||||
const real& TVararray::getnum(int varnum)
|
||||
{
|
||||
if (varnum >= items())
|
||||
fatal_box("invalid variable number : %d", varnum);
|
||||
return ((TVar*)objptr(varnum))->number();
|
||||
const TVar* var = (const TVar*)objptr(varnum);
|
||||
if (var == NULL)
|
||||
{
|
||||
NFCHECK("Invalid variable number : %d", varnum);
|
||||
return ZERO;
|
||||
}
|
||||
return var->number();
|
||||
}
|
||||
|
||||
|
||||
const char* TVararray::getstring(const char* name)
|
||||
const TString& TVararray::getstring(const char* name)
|
||||
{
|
||||
for (int i = items()-1; i >= 0; i--)
|
||||
{
|
||||
@ -110,19 +112,17 @@ const char* TVararray::getstring(const char* name)
|
||||
return var->string();
|
||||
}
|
||||
NFCHECK("Unknown variable : %s", name);
|
||||
return "";
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
|
||||
const char* TVararray::getstring(int varnum)
|
||||
const TString& TVararray::getstring(int varnum)
|
||||
{
|
||||
if (varnum < 0 || varnum >= items())
|
||||
const TVar* var = (const TVar*)objptr(varnum);
|
||||
if (var == NULL)
|
||||
{
|
||||
NFCHECK("Invalid variable number : %d", varnum);
|
||||
return "";
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
const TVar* var = (const TVar*)objptr(varnum);
|
||||
CHECKD(var, "Variabile nulla: ", varnum);
|
||||
return var->string();
|
||||
}
|
||||
|
||||
@ -130,13 +130,46 @@ const char* TVararray::getstring(int varnum)
|
||||
// TEval_stack
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
void TEval_stack::push(const real& r)
|
||||
{
|
||||
if (_data.items() > _sp)
|
||||
{
|
||||
_sp++;
|
||||
peek_real() = r;
|
||||
}
|
||||
else
|
||||
TStack::push(r);
|
||||
}
|
||||
|
||||
void TEval_stack::push(const TString& s)
|
||||
{
|
||||
if (_data.items() > _sp)
|
||||
{
|
||||
_sp++;
|
||||
peek_string() = s;
|
||||
}
|
||||
else
|
||||
TStack::push(s);
|
||||
}
|
||||
|
||||
void TEval_stack::push(const char* s)
|
||||
{
|
||||
if (_data.items() > _sp)
|
||||
{
|
||||
_sp++;
|
||||
peek_string() = s;
|
||||
}
|
||||
else
|
||||
TStack::push(new TString80(s));
|
||||
}
|
||||
|
||||
real& TEval_stack::pop_real()
|
||||
{
|
||||
TObject& o = pop();
|
||||
if (o.class_id() == CLASS_STRING)
|
||||
{
|
||||
real* r = new real((TString&)o);
|
||||
push(r);
|
||||
TStack::push(r);
|
||||
return (real&)pop();
|
||||
}
|
||||
return (real&)o;
|
||||
@ -149,7 +182,7 @@ real& TEval_stack::peek_real()
|
||||
{
|
||||
pop();
|
||||
real* r = new real((TString&)o);
|
||||
push(r);
|
||||
TStack::push(r);
|
||||
return *r;
|
||||
}
|
||||
return (real&)o;
|
||||
@ -161,8 +194,8 @@ TString& TEval_stack::pop_string()
|
||||
if (o.class_id() == CLASS_STRING)
|
||||
return (TString&)o;
|
||||
|
||||
TString* s = new TString(((real&)o).string());
|
||||
push(s);
|
||||
TString* s = new TString80(((real&)o).string());
|
||||
TStack::push(s);
|
||||
return (TString&)pop();
|
||||
}
|
||||
|
||||
@ -173,11 +206,23 @@ TString& TEval_stack::peek_string()
|
||||
return (TString&)o;
|
||||
|
||||
pop();
|
||||
TString* s = new TString(((real&)o).string());
|
||||
push(s);
|
||||
TString* s = new TString80(((real&)o).string());
|
||||
TStack::push(s);
|
||||
return *s;
|
||||
}
|
||||
|
||||
bool TEval_stack::pop_bool()
|
||||
{
|
||||
TObject& o = pop();
|
||||
if (o.class_id() == CLASS_STRING)
|
||||
{
|
||||
const real r = (TString&)o;
|
||||
return !r.is_zero();
|
||||
}
|
||||
return !((real&)o).is_zero();
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TExpression
|
||||
@ -192,12 +237,7 @@ TExpression::TExpression(const char* expression, TTypeexp type, bool ignore_err)
|
||||
_val = ZERO;
|
||||
_dirty = TRUE;
|
||||
_type = type;
|
||||
if (!compile(_original, type))
|
||||
{
|
||||
TString msg(256);
|
||||
msg.format("Wrong expression : %s", expression);
|
||||
print_error(msg);
|
||||
}
|
||||
compile(_original, type);
|
||||
}
|
||||
|
||||
|
||||
@ -254,12 +294,12 @@ void TExpression::print_on(ostream& out) const
|
||||
void TExpression::evaluate_user_func(int index, int nparms, TEval_stack& stack, TTypeexp curtype) const
|
||||
{
|
||||
NFCHECK("Unknown function %d.", index);
|
||||
for ( int i = nparms ; i > 0; i--)
|
||||
for (int i = nparms ; i > 0; i--)
|
||||
stack.pop();
|
||||
if (curtype == _numexpr)
|
||||
stack.push(ZERO);
|
||||
else
|
||||
stack.push(TString(""));
|
||||
stack.push("");
|
||||
}
|
||||
|
||||
void TExpression::setvar(const char* varname, const real& val)
|
||||
@ -383,9 +423,8 @@ void TExpression::eval()
|
||||
{
|
||||
if (!evalstack.peek_real().is_zero())
|
||||
{
|
||||
if (_ignore_error)
|
||||
_error=1;
|
||||
else
|
||||
_error=1;
|
||||
if (!_ignore_error)
|
||||
print_error("Divisione per zero!");
|
||||
}
|
||||
}
|
||||
@ -401,16 +440,16 @@ void TExpression::eval()
|
||||
break;
|
||||
case _and:
|
||||
{
|
||||
const real & r2 = evalstack.pop_real();
|
||||
real & r1 = evalstack.peek_real();
|
||||
r1 = (!r1.is_zero() && !r2.is_zero()) ? 1.0 : 0.0;
|
||||
const bool r2 = evalstack.pop_bool();
|
||||
const bool r1 = evalstack.pop_bool();
|
||||
evalstack.push(real(r1 && r2 ? 1.0 : 0.0));
|
||||
}
|
||||
break;
|
||||
case _or:
|
||||
{
|
||||
const real & r2 = evalstack.pop_real();
|
||||
real & r1 = evalstack.peek_real();
|
||||
r1 = (r1 != ZERO || r2 != ZERO) ? 1.0 : 0.0;
|
||||
const bool r2 = evalstack.pop_bool();
|
||||
const bool r1 = evalstack.pop_bool();
|
||||
evalstack.push(real(r1 || r2 ? 1.0 : 0.0));
|
||||
}
|
||||
break;
|
||||
case _not:
|
||||
@ -435,9 +474,9 @@ void TExpression::eval()
|
||||
break;
|
||||
case _match:
|
||||
{
|
||||
const TString & s2 = evalstack.pop_string();
|
||||
const TString & s1 = evalstack.pop_string();
|
||||
evalstack.push(real((s1.match(s2)) ? 1.0 : 0.0));
|
||||
const TString& s2 = evalstack.pop_string();
|
||||
const TString& s1 = evalstack.pop_string();
|
||||
evalstack.push(real(s1.match(s2) ? 1.0 : 0.0));
|
||||
}
|
||||
break;
|
||||
case _noteq:
|
||||
@ -523,9 +562,8 @@ void TExpression::eval()
|
||||
real& r = evalstack.peek_real();
|
||||
if (r < ZERO)
|
||||
{
|
||||
if (_ignore_error)
|
||||
_error=1;
|
||||
else
|
||||
_error=1;
|
||||
if (!_ignore_error)
|
||||
print_error("Radice negativa!");
|
||||
r = -r;
|
||||
}
|
||||
@ -662,8 +700,8 @@ void TExpression::eval()
|
||||
{
|
||||
const TString & s1 = evalstack.pop_string();
|
||||
const TString & s2 = evalstack.pop_string();
|
||||
const real & cond = evalstack.pop_real();
|
||||
evalstack.push(cond.is_zero() ? s1 : s2);
|
||||
const bool cond = evalstack.pop_bool();
|
||||
evalstack.push(cond ? s2 : s1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1151,7 +1189,7 @@ bool TExpression::set(const char* expression, TTypeexp type)
|
||||
return compile(_original, type);
|
||||
}
|
||||
|
||||
bool TExpression::compile(const char* expression, TTypeexp type)
|
||||
bool TExpression::compile(const TString& expression, TTypeexp type)
|
||||
{
|
||||
_error=0;
|
||||
_user_func_defined = FALSE;
|
||||
@ -1159,13 +1197,25 @@ bool TExpression::compile(const char* expression, TTypeexp type)
|
||||
_type = type;
|
||||
_val = ZERO;
|
||||
_code.clear();
|
||||
if (*_s == '\0')
|
||||
if (expression.blank())
|
||||
return TRUE;
|
||||
|
||||
TCodesym currsym = __gettoken();
|
||||
if (currsym == _invalid)
|
||||
return FALSE;
|
||||
return __expression(currsym) == _endsym;
|
||||
bool ok = currsym != _invalid;
|
||||
if (ok)
|
||||
ok = __expression(currsym) == _endsym;
|
||||
if (!ok)
|
||||
{
|
||||
_error = 2;
|
||||
if (!_ignore_error)
|
||||
{
|
||||
TString msg;
|
||||
msg << "Wrong expression : " << _original;
|
||||
print_error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
const char* TExpression::last_token() const
|
||||
|
@ -179,7 +179,7 @@ public:
|
||||
const real& number() const
|
||||
{ return _val.number();}
|
||||
// @cmember Ritorna il valore come stringa
|
||||
const char* string() const
|
||||
const TString& string() const
|
||||
{ return _val.string();}
|
||||
|
||||
// @cmember Costruttore, inizializza simbolo con "invalid", valore a nullvalue
|
||||
@ -292,7 +292,7 @@ public:
|
||||
const real& number() const
|
||||
{ return _val.number();}
|
||||
// @cmember Ritorna il valore stringa della variabile
|
||||
const char* string() const
|
||||
const TString& string() const
|
||||
{ return _val.string();}
|
||||
|
||||
// @cmember Costruttore (assegna "" al campo <p _name> ed il valore nulltvalue al campo <p val>)
|
||||
@ -353,9 +353,9 @@ public:
|
||||
// @cmember Ritorna il valore della variabile di posto <p varnum>-esimo
|
||||
const real& getnum(int varnum);
|
||||
// @cmember Ritorna il nome della variabile con nome <p varname>
|
||||
const char* getstring(const char* varname);
|
||||
const TString& getstring(const char* varname);
|
||||
// @cmember Ritorna il nome della variabile di posto <p varnum>-esimo
|
||||
const char* getstring(int varnum);
|
||||
const TString& getstring(int varnum);
|
||||
|
||||
// @cmember Ritorna il numero di variabili utilizzate
|
||||
int numvar() const
|
||||
@ -371,10 +371,15 @@ public:
|
||||
class TEval_stack : public TStack
|
||||
{
|
||||
public:
|
||||
void push(const real& r);
|
||||
void push(const TString& s);
|
||||
void push(const char* s);
|
||||
|
||||
real& pop_real();
|
||||
real& peek_real();
|
||||
TString& pop_string();
|
||||
TString& peek_string();
|
||||
bool pop_bool();
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
@ -385,11 +390,12 @@ public:
|
||||
// @base public | TObject
|
||||
class TExpression : public TObject
|
||||
|
||||
// @author:(INTERNAL) Sandro
|
||||
// @author:(INTERNAL) Alex
|
||||
|
||||
// @access:(INTERNAL) Private Member
|
||||
{
|
||||
|
||||
// @access Protected Member
|
||||
protected:
|
||||
// @cmember:(INTERNAL) Array di codice
|
||||
TCodearray _code;
|
||||
// @cmember:(INTERNAL) Array di variabili
|
||||
@ -431,7 +437,7 @@ protected:
|
||||
// @cmember Esegue la compilazione di un una funzione
|
||||
TCodesym __function(int nparms = -1, bool fixed_num = TRUE);
|
||||
// @cmember Compila l'espressione
|
||||
bool compile(const char* expression, TTypeexp type);
|
||||
bool compile(const TString& expression, TTypeexp type);
|
||||
|
||||
protected: // TObject
|
||||
// @cmember Stampa l'espressione su <p out> (serve per implementare l'insertore)
|
||||
@ -488,7 +494,7 @@ public:
|
||||
bool set(const char* expression, TTypeexp type = _numexpr);
|
||||
const char* last_token() const;
|
||||
// @cmember Ritorna l'espressione originale
|
||||
const char * string() const { return _original; }
|
||||
const char* string() const { return _original; }
|
||||
// @cmember Ritorna eventuali errori
|
||||
int error() {return _error;}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#define STRICT
|
||||
#define WIN32_EXTRA_LEAN
|
||||
#define XVT_INCL_NATIVE
|
||||
|
||||
#include <controls.h>
|
||||
@ -9,6 +10,7 @@
|
||||
#include <relation.h>
|
||||
#include <urldefid.h>
|
||||
#include <utility.h>
|
||||
#include <window.h>
|
||||
|
||||
#include <mapi.h>
|
||||
#include <shellapi.h>
|
||||
@ -660,9 +662,37 @@ TGolem_field::~TGolem_field()
|
||||
{ }
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Mail message
|
||||
// MAPI session
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TMAPI_session : public TObject
|
||||
{
|
||||
HINSTANCE _hlibMAPI;
|
||||
LHANDLE _hSession;
|
||||
LONG _hWnd;
|
||||
|
||||
protected:
|
||||
bool load_mapi();
|
||||
void unload_mapi();
|
||||
|
||||
public:
|
||||
operator LHANDLE() const { return _hSession; }
|
||||
LONG hWnd() const { return _hWnd; }
|
||||
|
||||
bool open();
|
||||
|
||||
bool send(MapiMessage& msg, FLAGS flags = MAPI_DIALOG);
|
||||
bool remove(const TString& id);
|
||||
|
||||
void close();
|
||||
|
||||
virtual bool ok() const
|
||||
{ return _hlibMAPI != NULL && _hSession != NULL; }
|
||||
|
||||
TMAPI_session();
|
||||
virtual ~TMAPI_session();
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
const char* const szMAPIDLL = "MAPI32.DLL";
|
||||
const int MAPI_USE_DEFAULT = 0;
|
||||
@ -670,8 +700,6 @@ TGolem_field::~TGolem_field()
|
||||
const char* const szMAPIDLL = "MAPI.DLL";
|
||||
#endif
|
||||
|
||||
static HINSTANCE _hlibMAPI = NULL;
|
||||
|
||||
LPMAPILOGON lpfnMAPILogon = NULL;
|
||||
LPMAPILOGOFF lpfnMAPILogoff = NULL;
|
||||
LPMAPISENDMAIL lpfnMAPISendMail = NULL;
|
||||
@ -685,7 +713,7 @@ LPMAPIADDRESS lpfnMAPIAddress = NULL;
|
||||
LPMAPIDETAILS lpfnMAPIDetails = NULL;
|
||||
LPMAPIRESOLVENAME lpfnMAPIResolveName = NULL;
|
||||
|
||||
bool TMail_message::load_mapi(void)
|
||||
bool TMAPI_session::load_mapi()
|
||||
{
|
||||
if (_hlibMAPI) // Check in already loaded
|
||||
return TRUE;
|
||||
@ -719,84 +747,160 @@ bool TMail_message::load_mapi(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void TMail_message::unload_mapi()
|
||||
void TMAPI_session::unload_mapi()
|
||||
{
|
||||
if (_hlibMAPI)
|
||||
if (_hlibMAPI)
|
||||
{
|
||||
FreeLibrary(_hlibMAPI);
|
||||
_hlibMAPI = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool TMail_message::send()
|
||||
{
|
||||
TWait_cursor hourglass;
|
||||
bool ok = load_mapi();
|
||||
if (!ok)
|
||||
return error_box("Impossibile inizializzare MAPI");
|
||||
|
||||
LHANDLE lhSession = 0;
|
||||
ULONG err = lpfnMAPILogon(0L, "", "",
|
||||
MAPI_LOGON_UI | MAPI_USE_DEFAULT,
|
||||
0L, &lhSession);
|
||||
if (err == SUCCESS_SUCCESS)
|
||||
{
|
||||
const int MAX_RECIPIENTS = _recipients.items() + _copy_recipients.items() + 1;
|
||||
MapiRecipDesc* msgRecipient = new MapiRecipDesc[MAX_RECIPIENTS];
|
||||
memset(msgRecipient, 0, MAX_RECIPIENTS*sizeof(MapiRecipDesc));
|
||||
|
||||
int nr = 0;
|
||||
if (_sender.not_empty())
|
||||
{
|
||||
msgRecipient[nr].ulRecipClass = MAPI_ORIG;
|
||||
msgRecipient[nr++].lpszName = _sender.get_buffer();
|
||||
}
|
||||
FOR_EACH_ARRAY_ROW(_recipients, rec, recipient)
|
||||
{
|
||||
msgRecipient[nr].ulRecipClass = MAPI_TO;
|
||||
msgRecipient[nr++].lpszName = recipient->get_buffer();
|
||||
}
|
||||
FOR_EACH_ARRAY_ROW(_copy_recipients, cc_rec, cc_recipient)
|
||||
{
|
||||
msgRecipient[nr].ulRecipClass = MAPI_CC;
|
||||
msgRecipient[nr++].lpszName = cc_recipient->get_buffer();
|
||||
}
|
||||
|
||||
const int MAX_ATTACHMENTS = _attachments.items() + 1;
|
||||
MapiFileDesc* msgAttachment = new MapiFileDesc[MAX_ATTACHMENTS];
|
||||
memset(msgAttachment, 0, MAX_ATTACHMENTS*sizeof(MapiFileDesc));
|
||||
int na = 0;
|
||||
FOR_EACH_ARRAY_ROW(_attachments, att, attachment)
|
||||
{
|
||||
TString80 tmp; tmp.spaces(32);
|
||||
*this << '\n' << tmp;
|
||||
msgAttachment[na].nPosition = len()-1;
|
||||
msgAttachment[na++].lpszPathName = attachment->get_buffer();
|
||||
}
|
||||
bool TMAPI_session::open()
|
||||
{
|
||||
if (_hSession == NULL)
|
||||
{
|
||||
TWait_cursor hourglass;
|
||||
if (!load_mapi())
|
||||
return error_box("Impossibile inizializzare MAPI");
|
||||
|
||||
MapiMessage msgSend;
|
||||
memset(&msgSend, 0, sizeof(MapiMessage));
|
||||
msgSend.lpszNoteText = get_buffer();
|
||||
msgSend.lpszSubject = _subject.get_buffer();
|
||||
msgSend.nRecipCount = nr;
|
||||
msgSend.lpRecips = msgRecipient;
|
||||
msgSend.nFileCount = na;
|
||||
msgSend.lpFiles = msgAttachment;
|
||||
|
||||
err = lpfnMAPISendMail(lhSession, 0, &msgSend, MAPI_DIALOG, 0L);
|
||||
|
||||
delete msgRecipient;
|
||||
delete msgAttachment;
|
||||
FLAGS flags = MAPI_USE_DEFAULT | MAPI_LOGON_UI;
|
||||
ULONG err = lpfnMAPILogon(_hWnd, "", "", flags, 0L, &_hSession);
|
||||
|
||||
err = lpfnMAPILogoff(lhSession, 0L, 0L, 0L);
|
||||
if (err != SUCCESS_SUCCESS)
|
||||
return error_box("Impossibile collegarsi a MAPI: %lu", err);
|
||||
|
||||
_hWnd = xvt_vobj_get_attr(cur_win(), ATTR_NATIVE_WINDOW);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void TMAPI_session::close()
|
||||
{
|
||||
if (_hlibMAPI)
|
||||
{
|
||||
if (_hSession)
|
||||
{
|
||||
lpfnMAPILogoff(_hSession, _hWnd, 0L, 0L);
|
||||
_hSession = NULL;
|
||||
}
|
||||
unload_mapi();
|
||||
}
|
||||
}
|
||||
|
||||
bool TMAPI_session::send(MapiMessage& msg, FLAGS flags)
|
||||
{
|
||||
bool ok = FALSE;
|
||||
if (open())
|
||||
{
|
||||
LONG err = lpfnMAPISendMail(_hSession, _hWnd, &msg, flags, 0L);
|
||||
if (err == SUCCESS_SUCCESS)
|
||||
ok = TRUE;
|
||||
else
|
||||
error_box("Can't send mail message: %ld", err);
|
||||
}
|
||||
else
|
||||
ok = error_box("Impossibile collegarsi a MAPI");
|
||||
|
||||
unload_mapi();
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TMAPI_session::remove(const TString& id)
|
||||
{
|
||||
bool ok = FALSE;
|
||||
if (open())
|
||||
{
|
||||
LONG err = lpfnMAPIDeleteMail(_hSession, _hWnd,
|
||||
(char*)(const char*)id, 0L, 0L);
|
||||
if (err == SUCCESS_SUCCESS)
|
||||
ok = TRUE;
|
||||
else
|
||||
error_box("Can't delete mail message: %ld", err);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
TMAPI_session::TMAPI_session()
|
||||
: _hlibMAPI(NULL), _hSession(NULL), _hWnd(NULL)
|
||||
{ }
|
||||
|
||||
TMAPI_session::~TMAPI_session()
|
||||
{ close(); }
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TMail_message
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
bool TMail_message::send(TMAPI_session& lhSession, bool hide_ui)
|
||||
{
|
||||
const int MAX_RECIPIENTS = _recipients.items() + _copy_recipients.items() + 1;
|
||||
MapiRecipDesc* msgRecipient = new MapiRecipDesc[MAX_RECIPIENTS];
|
||||
memset(msgRecipient, 0, MAX_RECIPIENTS*sizeof(MapiRecipDesc));
|
||||
|
||||
int nr = 0;
|
||||
if (_sender.not_empty())
|
||||
{
|
||||
msgRecipient[nr].ulRecipClass = MAPI_ORIG;
|
||||
msgRecipient[nr++].lpszName = _sender.get_buffer();
|
||||
}
|
||||
FOR_EACH_ARRAY_ROW(_recipients, rec, recipient)
|
||||
{
|
||||
msgRecipient[nr].ulRecipClass = MAPI_TO;
|
||||
msgRecipient[nr].lpszName = recipient->get_buffer();
|
||||
nr++;
|
||||
}
|
||||
FOR_EACH_ARRAY_ROW(_copy_recipients, cc_rec, cc_recipient)
|
||||
{
|
||||
msgRecipient[nr].ulRecipClass = MAPI_CC;
|
||||
msgRecipient[nr].lpszName = cc_recipient->get_buffer();
|
||||
nr++;
|
||||
}
|
||||
|
||||
const int MAX_ATTACHMENTS = _attachments.items() + 1;
|
||||
MapiFileDesc* msgAttachment = new MapiFileDesc[MAX_ATTACHMENTS];
|
||||
memset(msgAttachment, 0, MAX_ATTACHMENTS*sizeof(MapiFileDesc));
|
||||
int na = 0;
|
||||
FOR_EACH_ARRAY_ROW(_attachments, att, attachment)
|
||||
{
|
||||
TString80 tmp; tmp.spaces(32);
|
||||
*this << '\n' << tmp;
|
||||
msgAttachment[na].nPosition = len()-1;
|
||||
msgAttachment[na].lpszPathName = attachment->get_buffer();
|
||||
na++;
|
||||
}
|
||||
|
||||
MapiMessage msgSend;
|
||||
memset(&msgSend, 0, sizeof(MapiMessage));
|
||||
msgSend.lpszNoteText = empty() ? NULL : get_buffer();
|
||||
msgSend.lpszSubject = _subject.empty() ? NULL : _subject.get_buffer();
|
||||
msgSend.nRecipCount = nr;
|
||||
msgSend.lpRecips = nr == 0 ? NULL : msgRecipient;
|
||||
msgSend.nFileCount = na;
|
||||
msgSend.lpFiles = na == 0 ? NULL : msgAttachment;
|
||||
|
||||
bool ok = lhSession.send(msgSend, hide_ui ? 0 : MAPI_DIALOG);
|
||||
|
||||
delete msgRecipient;
|
||||
delete msgAttachment;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TMail_message::send(bool hide_ui)
|
||||
{
|
||||
TMAPI_session lhSession; // Open MAPI session
|
||||
return send(lhSession, hide_ui);
|
||||
}
|
||||
|
||||
bool TMail_message::remove(TMAPI_session& lhSession)
|
||||
{
|
||||
bool ok = _id.not_empty() && lhSession.remove(_id);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TMail_message::remove()
|
||||
{
|
||||
TMAPI_session lhSession; // Open MAPI session
|
||||
return remove(lhSession);
|
||||
}
|
||||
|
||||
bool TMail_message::add_recipient_ex(const char* recipient, int type)
|
||||
{
|
||||
TFilename rec(recipient);
|
||||
@ -821,13 +925,147 @@ bool TMail_message::add_recipient_ex(const char* recipient, int type)
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
void TMail_message::set_date_time(const char* str)
|
||||
{
|
||||
if (str == NULL)
|
||||
str = "";
|
||||
|
||||
int anno, mese, giorno;
|
||||
int ora = 12, minuto = 0, secondo = 0;
|
||||
const int num = sscanf(str, "%d/%d/%d %d:%d:%d",
|
||||
&anno, &mese, &giorno, &ora, &minuto, &secondo);
|
||||
if (num >= 3)
|
||||
{
|
||||
_date = TDate(giorno, mese, anno);
|
||||
_hms = ora*10000L + minuto*100L + secondo;
|
||||
}
|
||||
else
|
||||
{
|
||||
_date = TODAY;
|
||||
_hms = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Certified 100%
|
||||
const TString& TMail_message::recipient(int n) const
|
||||
{
|
||||
if (n >= 0 && n < recipients())
|
||||
return _recipients.row(n);
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
TMail_message::TMail_message(const char* recipient, const char* subject,
|
||||
const char* text, const char* sender)
|
||||
: TString(text), _subject(subject), _sender(sender)
|
||||
: TString(text), _subject(subject), _sender(sender), _hms(0)
|
||||
{
|
||||
add_recipient(recipient);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TMail_messages
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
TMail_messages::TMail_messages()
|
||||
{ }
|
||||
|
||||
int TMail_messages::get(const char* senderFilter,
|
||||
const char* subjectFilter,
|
||||
const char* bodyFilter,
|
||||
bool attach, bool mark)
|
||||
{
|
||||
TMAPI_session lhSession;
|
||||
if (!lhSession.open())
|
||||
return 0;
|
||||
|
||||
TString str_msg_id(512); // Accept MAPI_LONG_MSGID
|
||||
char* msg_id = str_msg_id.get_buffer();
|
||||
|
||||
LONG err = lpfnMAPIFindNext(lhSession, lhSession.hWnd(), NULL, NULL,
|
||||
MAPI_GUARANTEE_FIFO | MAPI_LONG_MSGID,
|
||||
0, msg_id);
|
||||
|
||||
FLAGS flags = 0;
|
||||
if (!mark) flags |= MAPI_PEEK;
|
||||
if (!attach) flags |= MAPI_SUPPRESS_ATTACH;
|
||||
|
||||
while (err == SUCCESS_SUCCESS)
|
||||
{
|
||||
MapiMessage FAR* pMessage = NULL;
|
||||
err = lpfnMAPIReadMail(lhSession, lhSession.hWnd(), msg_id,
|
||||
flags, 0, &pMessage);
|
||||
|
||||
if (err == SUCCESS_SUCCESS)
|
||||
{
|
||||
const char* id = NULL;
|
||||
const char* sender = NULL;
|
||||
const char* subject = NULL;
|
||||
const char* body = NULL;
|
||||
const char* recipient = NULL;
|
||||
|
||||
bool should_add = TRUE;
|
||||
if (should_add)
|
||||
{
|
||||
const MapiRecipDesc* pSender = pMessage->lpOriginator;
|
||||
sender = pSender->lpszName;
|
||||
if (senderFilter && *senderFilter)
|
||||
should_add = stricmp(senderFilter, sender) == 0;
|
||||
}
|
||||
|
||||
if (should_add)
|
||||
{
|
||||
subject = pMessage->lpszSubject;
|
||||
if (subjectFilter && *subjectFilter)
|
||||
{
|
||||
const unsigned lenFilter = strlen(subjectFilter);
|
||||
should_add = strncmp(subject, subjectFilter, lenFilter) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (should_add)
|
||||
{
|
||||
body = pMessage->lpszNoteText;
|
||||
if (bodyFilter && *bodyFilter)
|
||||
should_add = strstr(body, bodyFilter) != NULL;
|
||||
}
|
||||
|
||||
if (should_add)
|
||||
{
|
||||
TMail_message* msg = new TMail_message(recipient, subject, body, sender);
|
||||
msg->set_date_time(pMessage->lpszDateReceived);
|
||||
msg->set_id(msg_id);
|
||||
add(msg);
|
||||
}
|
||||
|
||||
lpfnMAPIFreeBuffer(pMessage);
|
||||
}
|
||||
|
||||
err = lpfnMAPIFindNext(lhSession, lhSession.hWnd(), NULL,
|
||||
msg_id, MAPI_LONG_MSGID, 0, msg_id);
|
||||
}
|
||||
|
||||
return items();
|
||||
}
|
||||
|
||||
bool TMail_messages::send(bool hide_ui)
|
||||
{
|
||||
TMAPI_session lhSession;
|
||||
bool ok = TRUE;
|
||||
for (int i = 0; i < items(); i++)
|
||||
ok &= msg(i).send(lhSession, hide_ui);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TMail_messages::remove()
|
||||
{
|
||||
TMAPI_session lhSession;
|
||||
bool ok = TRUE;
|
||||
for (int i = 0; ok && i < items(); i++)
|
||||
ok &= msg(i).remove(lhSession);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Obsolete DDE management
|
||||
///////////////////////////////////////////////////////////
|
||||
|
@ -1,6 +1,10 @@
|
||||
#ifndef __GOLEM_H
|
||||
#define __GOLEM_H
|
||||
|
||||
#ifndef __DATE_H
|
||||
#include <date.h>
|
||||
#endif
|
||||
|
||||
#ifndef __STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
@ -9,17 +13,23 @@ bool goto_url(const char* url);
|
||||
bool edit_url(const char* url);
|
||||
bool print_url(const char* url);
|
||||
|
||||
class TMAPI_session;
|
||||
|
||||
class TMail_message : public TString
|
||||
{
|
||||
TString_array _recipients, _copy_recipients, _attachments;
|
||||
TString _subject;
|
||||
TString _sender;
|
||||
TString _id;
|
||||
TDate _date;
|
||||
long _hms;
|
||||
|
||||
protected:
|
||||
bool load_mapi();
|
||||
void unload_mapi();
|
||||
|
||||
bool add_recipient_ex(const char* recipient, int type);
|
||||
|
||||
public: // Semiprotected: You don't have access to TMAPI_session
|
||||
bool send(TMAPI_session& lhSession, bool hide_ui = FALSE);
|
||||
bool remove(TMAPI_session& lhSession);
|
||||
|
||||
public:
|
||||
bool add_recipient(const char* address) { return add_recipient_ex(address, 0); }
|
||||
@ -27,17 +37,49 @@ public:
|
||||
bool add_copy_recipient(const char* address) { return add_recipient_ex(address, 1); }
|
||||
bool attach(const char* filename) { return add_recipient_ex(filename, 2); }
|
||||
void set_sender(const char* address) { _sender = address; _sender.trim(); }
|
||||
void set_id(const char* id) { _id = id; }
|
||||
|
||||
TString& operator = (const char* msg) { set(msg); return *this; }
|
||||
TString& operator = (const TString& msg) { set(msg); return *this; }
|
||||
|
||||
bool send();
|
||||
bool send(bool hide_ui = FALSE);
|
||||
bool remove();
|
||||
|
||||
const TString& sender() const { return _sender; }
|
||||
const TString& subject() const { return _subject; }
|
||||
const TString& id() const { return _id; }
|
||||
|
||||
void set_date_time(const char* date_time);
|
||||
const TDate& date() const { return _date; }
|
||||
long time() const { return _hms; }
|
||||
|
||||
int recipients() const { return _recipients.items(); }
|
||||
const TString& recipient(int n = 0) const;
|
||||
|
||||
TMail_message(const char* recipient, const char* subject = NULL,
|
||||
TMail_message(const char* recipient = NULL, const char* subject = NULL,
|
||||
const char* text = NULL, const char* sender = NULL);
|
||||
virtual ~TMail_message() { }
|
||||
};
|
||||
|
||||
class TMail_messages : public TArray
|
||||
{
|
||||
public:
|
||||
int get(const char* sender = NULL, const char* subject = NULL,
|
||||
const char* body = NULL, bool attachments = FALSE, bool mark_as_read = FALSE);
|
||||
|
||||
bool send(bool hide_ui = TRUE);
|
||||
bool remove();
|
||||
|
||||
TMail_message& msg(int i)
|
||||
{ return (TMail_message&)(*this)[i]; }
|
||||
|
||||
const TMail_message& msg(int i) const
|
||||
{ return (const TMail_message&)(*this)[i]; }
|
||||
|
||||
TMail_messages();
|
||||
virtual ~TMail_messages() { }
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TDDE | Classe per la gestione del DDE
|
||||
|
@ -1192,6 +1192,35 @@ bool TBaseisamfile::is_changed_since(long clk) const
|
||||
return clk < last;
|
||||
}
|
||||
|
||||
struct TCallbackFileinfo
|
||||
{
|
||||
TString16 _var;
|
||||
TFilename _app;
|
||||
};
|
||||
|
||||
HIDDEN int find_relapp(TConfig& cfg, void* jolly)
|
||||
{
|
||||
TCallbackFileinfo& info = *((TCallbackFileinfo*)jolly);
|
||||
if (cfg.exist(info._var))
|
||||
{
|
||||
info._app = cfg.get(info._var);
|
||||
return info._app.not_empty();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool TBaseisamfile::get_relapp(TString& app) const
|
||||
{
|
||||
TConfig ini("install.ini");
|
||||
TCallbackFileinfo fi;
|
||||
fi._var.format("Edit_%d", num());
|
||||
ini.for_each_paragraph(find_relapp, &fi);
|
||||
if (fi._app.not_empty())
|
||||
app = fi._app;
|
||||
return app.not_empty();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TLocalisamfile
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -2372,7 +2401,7 @@ TRectype::TRectype(const TRectype& r)
|
||||
{
|
||||
if (r._memo_data)
|
||||
{
|
||||
init_memo();
|
||||
init_memo(r._memo_recno); // ??
|
||||
*_memo_data = *r._memo_data;
|
||||
CHECK(r._memo_dirty, "memo_dirty NULL con memo_data valido");
|
||||
*_memo_dirty= *r._memo_dirty;
|
||||
|
@ -284,7 +284,6 @@ protected:
|
||||
// @access Protected Member
|
||||
protected:
|
||||
// @cmember:(INTERNAL) IO su file:
|
||||
// int _next(word lockop = _nolock);
|
||||
virtual int _read(TRectype& rec, word op = _isequal, word lockop = _nolock);
|
||||
virtual int _readat(TRectype& rec, TRecnotype nrec, word lockop = _nolock);
|
||||
virtual int _write(const TRectype& rec);
|
||||
@ -497,6 +496,8 @@ public:
|
||||
TRectype& operator =(const TRectype& rec)
|
||||
{ return curr() = rec;}
|
||||
|
||||
virtual bool get_relapp(TString& app) const;
|
||||
|
||||
// @cmember Notifica che il file e' stato modificato
|
||||
void notify_change() const;
|
||||
// @cmember Testa se il file e' cambiato dal ciclo di clock <p clk>
|
||||
|
@ -4,9 +4,6 @@
|
||||
#include <isamrpc.h>
|
||||
|
||||
#define NO_MFC
|
||||
#define CObject TObject
|
||||
#define CString TString
|
||||
#define CStringArray TString_array
|
||||
#include <netsock.h>
|
||||
|
||||
static TSocketClient* _client = NULL;
|
||||
@ -317,8 +314,8 @@ bool http_dir(const char* server, const char* remote_dir, TString_array& list)
|
||||
bool ok = connection != 0;
|
||||
if (ok)
|
||||
{
|
||||
ok = client.HttpGetDir(remote_dir, list) != 0;
|
||||
client.RemoveConnection(connection);
|
||||
ok = client.HttpGetDir(remote_dir, list) != 0;
|
||||
client.RemoveConnection(connection);
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
@ -1397,8 +1397,10 @@ void TEditable_field::show(bool on)
|
||||
|
||||
void TEditable_field::set_prompt(const char* p)
|
||||
{
|
||||
CHECKD(_prompt, "Can't set prompt to control", dlg());
|
||||
_prompt->set_caption(p);
|
||||
if (_prompt)
|
||||
_prompt->set_caption(p);
|
||||
else
|
||||
NFCHECK("Can't set prompt to control %d", dlg());
|
||||
}
|
||||
|
||||
// Certified 90%
|
||||
@ -2184,6 +2186,7 @@ bool TBrowse::do_link(bool insert)
|
||||
|
||||
if (_insert[0] == 'M')
|
||||
{
|
||||
/*
|
||||
TString nm(_insert.mid(1));
|
||||
if (nm.compare("tb", 2, TRUE) == 0) // Programma gestione tabelle
|
||||
{
|
||||
@ -2205,6 +2208,8 @@ bool TBrowse::do_link(bool insert)
|
||||
app = "ba3 -3 ";
|
||||
app << nm << ' ' << _cursor->file().num();
|
||||
}
|
||||
*/
|
||||
_cursor->file().get_relapp(app);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2575,9 +2580,12 @@ KEY TFile_select::run()
|
||||
return good ? K_ENTER : K_ESC;
|
||||
}
|
||||
|
||||
bool TFile_select::check(CheckTime)
|
||||
bool TFile_select::check(CheckTime ct)
|
||||
{
|
||||
const TFilename name = field().get();
|
||||
if (ct != STARTING_CHECK && name.empty() &&
|
||||
field().check_type() == CHECK_REQUIRED)
|
||||
return FALSE;
|
||||
bool ok = _filter.empty() || name.match(_filter);
|
||||
if (ok && field().roman()) // Must exist
|
||||
ok = name.exist();
|
||||
@ -4292,6 +4300,13 @@ const char* TMemo_field::reformat(const char* data) const
|
||||
|
||||
const char* TMemo_field::raw2win(const char* data) const
|
||||
{
|
||||
#ifdef XI_R4
|
||||
if (strchr(data, '\r') == NULL)
|
||||
return data;
|
||||
TString& s = _ctl_data._park;
|
||||
s = data;
|
||||
s.replace('\r', '\n');
|
||||
#else
|
||||
if (strchr(data, '\n') == NULL)
|
||||
return data;
|
||||
|
||||
@ -4299,17 +4314,22 @@ const char* TMemo_field::raw2win(const char* data) const
|
||||
s = data;
|
||||
for (int i = 0; s[i]; i++)
|
||||
if (s[i] == '\n') s[i] = '\r';
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
const char* TMemo_field::win2raw(const char* data) const
|
||||
{
|
||||
#ifdef XI_R4
|
||||
return data;
|
||||
#else
|
||||
if (strchr(data, '\r') == NULL)
|
||||
return data;
|
||||
_ctl_data._park = data;
|
||||
for (char* s = (char*)(const char*)_ctl_data._park; *s; s++)
|
||||
if (*s == '\r') *s = '\n';
|
||||
return _ctl_data._park;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool TMemo_field::on_key(KEY k)
|
||||
|
@ -949,6 +949,8 @@ public:
|
||||
// @cmember Controlla la validita' del campo
|
||||
virtual bool check(CheckTime = RUNNING_CHECK);
|
||||
|
||||
virtual bool is_filesel() const { return TRUE; }
|
||||
|
||||
TFile_select(TEdit_field* ef, const char* filter);
|
||||
virtual ~TFile_select() { }
|
||||
};
|
||||
|
@ -199,6 +199,8 @@ public:
|
||||
// @cmember Permette di invertire la posizione di due righe
|
||||
void swap_rows(const int fromindex, const int toindex);
|
||||
|
||||
// @cmember L'utente ha salvato la disposizione delle colonne?
|
||||
bool user_saved_columns_order() const;
|
||||
// @cmember Salva la disposizione delle colonne
|
||||
void save_columns_order() const;
|
||||
// @cmember Salva la disposizione delle colonne
|
||||
@ -723,7 +725,7 @@ int TSpreadsheet::insert(
|
||||
|
||||
if (ok)
|
||||
{
|
||||
TToken_string* toktok = new TToken_string(80);
|
||||
TToken_string* toktok = new TToken_string(80, owner().separator());
|
||||
r = _str.insert(toktok, rec);
|
||||
|
||||
_property.insert(NULL, r, TRUE); // Crea lo spazio necessario per le proprieta'
|
||||
@ -1948,6 +1950,15 @@ HIDDEN TFilename& field2parag(const TMask_field& f, TFilename& name)
|
||||
return name;
|
||||
}
|
||||
|
||||
bool TSpreadsheet::user_saved_columns_order() const
|
||||
{
|
||||
TFilename parag; field2parag(owner(), parag);
|
||||
TConfig config(CONFIG_USER, parag); // Apre il file di configurazione
|
||||
const int index = owner().dlg();
|
||||
TToken_string order = config.get("Browse", NULL, index);
|
||||
return !order.empty_items();
|
||||
}
|
||||
|
||||
void TSpreadsheet::save_columns_order() const
|
||||
{
|
||||
if (_save_columns_order)
|
||||
@ -2142,8 +2153,9 @@ KEY TSpreadsheet::edit(int n)
|
||||
// Certified 100%
|
||||
TSheet_field::TSheet_field(TMask* m)
|
||||
: TLoadable_field(m), _append(TRUE),
|
||||
_enable_autoload(FALSE),_sheetfile(NULL),_linee_rec(NULL),_external_record(FALSE),
|
||||
_userput(NULL),_userget(NULL)
|
||||
_enable_autoload(FALSE),_sheetfile(NULL),_linee_rec(NULL),
|
||||
_external_record(FALSE), _userput(NULL),_userget(NULL),
|
||||
_separator('|')
|
||||
{
|
||||
}
|
||||
|
||||
@ -2211,9 +2223,17 @@ bool TSheet_field::parse_item(TScanner& scanner)
|
||||
|
||||
if (scanner.key() == "FL") // FLAGS
|
||||
{
|
||||
TString16 flags(scanner.string());
|
||||
_enable_autoload=(flags.find("A")>=0);
|
||||
_append=(flags.find("I")<0);
|
||||
const char* flags = scanner.string();
|
||||
for (const char* f = flags; *f; f++)
|
||||
{
|
||||
switch(*f)
|
||||
{
|
||||
case 'A': _enable_autoload = TRUE; break;
|
||||
case 'I': _append = FALSE; break;
|
||||
case '|': _separator = '¦'; break;
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (scanner.key() == "US") // USE
|
||||
@ -2343,7 +2363,7 @@ TToken_string& TSheet_field::row(
|
||||
{
|
||||
if (n < 0) n = first_empty();
|
||||
if (n >= max)
|
||||
n = (int)s->add(new TToken_string(80));
|
||||
n = (int)s->add(new TToken_string(80, _separator));
|
||||
}
|
||||
return s->row(n);
|
||||
}
|
||||
@ -2477,6 +2497,18 @@ void TSheet_field::swap_columns(const int fromid, const int toid) const
|
||||
s->swap_columns(fromid, toid);
|
||||
}
|
||||
|
||||
bool TSheet_field::user_saved_columns_order() const
|
||||
{
|
||||
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
||||
return s->user_saved_columns_order();
|
||||
}
|
||||
|
||||
void TSheet_field::set_columns_order(TToken_string* order)
|
||||
{
|
||||
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
||||
s->set_columns_order(order);
|
||||
}
|
||||
|
||||
void TSheet_field::swap_rows( const int fromindex, const int toindex)
|
||||
{
|
||||
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
||||
|
@ -49,6 +49,9 @@ class TSheet_field : public TLoadable_field
|
||||
// @cmember:(INTERNAL) Indica se aggiungere a fondo dello spreadsheet o nella riga in cui ti trovi
|
||||
bool _append;
|
||||
|
||||
// @cmember:(INTERNAL) Separatore delle TToken_string
|
||||
char _separator;
|
||||
|
||||
// @cmember:(INTERNAL) Flag di autoload
|
||||
bool _enable_autoload;
|
||||
// @cmember:(INTERNAL) Campi di input sulla maschera (key field names)
|
||||
@ -136,6 +139,8 @@ public:
|
||||
const char* cell(int r, int c)
|
||||
{ const char*v=row(r).get(c); return v ? v: " "; }
|
||||
|
||||
char separator() const { return _separator; }
|
||||
|
||||
// @cmember Ritorna la prima riga vuota nello spreadsheet
|
||||
int first_empty() const;
|
||||
// @cmember Ritorna il numero di righe presenti nello spreadsheet
|
||||
@ -198,6 +203,11 @@ public:
|
||||
// @cmember Permette di invertire la posizione di due righe
|
||||
void swap_rows( const int fromindex, const int toindex ) ;
|
||||
|
||||
// @cmember Controlla se l'utente ha salvato la disposizione delle colonne
|
||||
bool user_saved_columns_order() const;
|
||||
// @cmember Setta la disposizione delle colonne
|
||||
void set_columns_order(TToken_string* order = NULL);
|
||||
|
||||
// @cmember Setta la larghezza della colonna
|
||||
void set_column_width( const int col, const int width ) const;
|
||||
// @cmember Setta il titolo della colonna
|
||||
|
@ -516,14 +516,25 @@ TConnection* TSocketClient::OnQueryConnection(const char* service,
|
||||
TConnection* pConnection = NULL;
|
||||
|
||||
if (cur_socket == NULL)
|
||||
{
|
||||
{
|
||||
int porta = service != NULL ? atoi(service) : 0;
|
||||
|
||||
TString strServer = server;
|
||||
if (strServer.compare("http://", 7, TRUE) == 0)
|
||||
strServer.ltrim(7);
|
||||
int pos = strServer.find("://");
|
||||
if (pos > 0)
|
||||
strServer.ltrim(pos+3);
|
||||
|
||||
pos = strServer.rfind(':');
|
||||
if (pos > 0)
|
||||
{
|
||||
porta = atoi(strServer.mid(pos+1));
|
||||
strServer.cut(pos);
|
||||
}
|
||||
|
||||
if (strServer.empty() || stricmp(strServer, "localhost") == 0)
|
||||
strServer = "127.0.0.1";
|
||||
|
||||
cur_socket = new skstream(strServer, (skstream::service)atoi(service));
|
||||
cur_socket = new skstream(strServer, (skstream::service)porta);
|
||||
|
||||
if (cur_socket->is_open())
|
||||
pConnection = OnCreateConnection((DWORD)cur_socket);
|
||||
@ -586,35 +597,51 @@ BYTE* TSocketClient::GetBuffer(DWORD& dwSize)
|
||||
return m_pData;
|
||||
}
|
||||
|
||||
BOOL TSocketClient::HttpGetFile(const char* remote, const char* local)
|
||||
BOOL TSocketClient::WriteLine(DWORD, const char* str)
|
||||
{
|
||||
if (!cur_socket->is_open())
|
||||
return FALSE;
|
||||
|
||||
|
||||
if (str && *str)
|
||||
{
|
||||
cur_socket->sync();
|
||||
cur_socket->write(str, strlen(str));
|
||||
cur_socket->flush();
|
||||
}
|
||||
|
||||
return cur_socket->good();
|
||||
}
|
||||
|
||||
BOOL TSocketClient::ReadLine(DWORD, TString& str)
|
||||
{
|
||||
char *buf = str.get_buffer(4096);
|
||||
cur_socket->getline(buf, str.size(), '\n');
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TSocketClient::HttpGetFile(const char* remote, const char* local)
|
||||
{
|
||||
BOOL ok = FALSE;
|
||||
|
||||
TString buf(4096);
|
||||
TString buf;
|
||||
buf << "GET " << remote << " HTTP/1.0\r\n\r\n";
|
||||
|
||||
cur_socket->sync();
|
||||
cur_socket->write(buf, buf.len());
|
||||
cur_socket->flush();
|
||||
if (cur_socket->good())
|
||||
if (WriteLine(0, buf))
|
||||
{
|
||||
const clock_t start = clock();
|
||||
|
||||
long size = 0;
|
||||
for (int r = 0; !cur_socket->eof(); r++)
|
||||
{
|
||||
cur_socket->getline(buf.get_buffer(), buf.size(), '\n');
|
||||
ReadLine(0, buf);
|
||||
if (buf.blank())
|
||||
break;
|
||||
if (r == 0 && buf.find("404") > 0)
|
||||
return FALSE; // File not found
|
||||
if (buf.compare("Content-length:", 15, TRUE) == 0)
|
||||
{
|
||||
const int colon = buf.find(':');
|
||||
size = atol(buf.mid(colon+1));
|
||||
const int colon = buf.find(':');
|
||||
size = atol(buf.mid(colon+1));
|
||||
}
|
||||
}
|
||||
ofstream outfile(local, ios::out | ios::binary);
|
||||
@ -676,7 +703,7 @@ BOOL TSocketClient::HttpGetDir(const char* remote, TString_array& list)
|
||||
if (ok)
|
||||
{
|
||||
ifstream s(local);
|
||||
TString riga(1024);
|
||||
TString riga;
|
||||
while (!s.eof())
|
||||
{
|
||||
s.getline(riga.get_buffer(), riga.size());
|
||||
|
@ -53,6 +53,9 @@ public:
|
||||
virtual void ReleaseBuffer();
|
||||
virtual BOOL IsOk() const { return TRUE; }
|
||||
|
||||
BOOL WriteLine(DWORD id, const char* str);
|
||||
BOOL ReadLine(DWORD id, TString& str);
|
||||
|
||||
BOOL HttpGetFile(const char* remote, const char* local);
|
||||
BOOL HttpGetDir(const char* remote, TString_array& list);
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
#define BOOL int
|
||||
#define BYTE unsigned char
|
||||
#define DWORD unsigned long
|
||||
#define CObject TObject
|
||||
#define CString TString
|
||||
#define CStringArray TString_array
|
||||
#include "assoc.h"
|
||||
#endif
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
enum os_type { os_Unknown, os_Windows, os_Win32s, os_Windows95, os_WindowsNT };
|
||||
enum os_type { os_Unknown, os_Windows, os_Win32s, os_Windows95, os_Windows98, os_WindowsNT };
|
||||
os_type os_get_type();
|
||||
|
||||
void os_post_menu_event(WINDOW win, MENU_TAG tag);
|
||||
|
@ -592,12 +592,12 @@ void os_set_event_hook()
|
||||
|
||||
long twin_style = WSF_ICONIZABLE | WSF_CLOSE | WSF_SIZE;
|
||||
const int scx = GetSystemMetrics(SM_CXSCREEN);
|
||||
if (scx == 640 && os_get_type() == os_Windows95)
|
||||
static RCT rct;
|
||||
if (scx <= 640 && os_get_type() >= os_Windows95)
|
||||
{
|
||||
const int scy = GetSystemMetrics(SM_CYSCREEN);
|
||||
const int bcx = GetSystemMetrics(SM_CXFRAME);
|
||||
const int bcy = GetSystemMetrics(SM_CYFRAME);
|
||||
static RCT rct;
|
||||
rct.left = -bcx;
|
||||
rct.top = GetSystemMetrics(SM_CYCAPTION)-bcy-1;
|
||||
rct.right = scx+bcx;
|
||||
@ -605,7 +605,20 @@ void os_set_event_hook()
|
||||
xvt_vobj_set_attr(NULL_WIN, ATTR_WIN_PM_TWIN_STARTUP_RCT, long(&rct));
|
||||
}
|
||||
else
|
||||
twin_style |= WSF_MAXIMIZED;
|
||||
{
|
||||
TConfig cfg(CONFIG_USER, "Colors");
|
||||
const int res = cfg.get_int("Resolution");
|
||||
if (res >= 640 && res < scx)
|
||||
{
|
||||
rct.left = 0;
|
||||
rct.top = GetSystemMetrics(SM_CYCAPTION);
|
||||
rct.right = res + 2*GetSystemMetrics(SM_CXFRAME);
|
||||
rct.bottom = (res * 3) / 4 + 2*GetSystemMetrics(SM_CYFRAME);
|
||||
xvt_vobj_set_attr(NULL_WIN, ATTR_WIN_PM_TWIN_STARTUP_RCT, long(&rct));
|
||||
}
|
||||
else
|
||||
twin_style |= WSF_MAXIMIZED;
|
||||
}
|
||||
|
||||
xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_TWIN_STARTUP_STYLE, twin_style);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define XVT_INCL_NATIVE
|
||||
#define WIN32_EXTRA_LEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <os_dep.h>
|
||||
|
||||
#include <commdlg.h>
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include <applicat.h>
|
||||
#include <colors.h>
|
||||
#include <config.h>
|
||||
#include <utility.h>
|
||||
#include <window.h>
|
||||
|
||||
@ -429,12 +430,12 @@ void os_set_event_hook()
|
||||
|
||||
long twin_style = WSF_ICONIZABLE | WSF_CLOSE | WSF_SIZE;
|
||||
const int scx = GetSystemMetrics(SM_CXSCREEN);
|
||||
if (scx == 640)
|
||||
static RCT rct;
|
||||
if (scx <= 640 && os_get_type() >= os_Windows95)
|
||||
{
|
||||
const int scy = GetSystemMetrics(SM_CYSCREEN);
|
||||
const int bcx = GetSystemMetrics(SM_CXFRAME);
|
||||
const int bcy = GetSystemMetrics(SM_CYFRAME);
|
||||
static RCT rct;
|
||||
rct.left = -bcx;
|
||||
rct.top = GetSystemMetrics(SM_CYCAPTION)-bcy-1;
|
||||
rct.right = scx+bcx;
|
||||
@ -442,7 +443,20 @@ void os_set_event_hook()
|
||||
xvt_vobj_set_attr(NULL_WIN, ATTR_WIN_PM_TWIN_STARTUP_RCT, long(&rct));
|
||||
}
|
||||
else
|
||||
twin_style |= WSF_MAXIMIZED;
|
||||
{
|
||||
TConfig cfg(CONFIG_USER, "Colors");
|
||||
const int res = cfg.get_int("Resolution");
|
||||
if (res >= 640 && res < scx)
|
||||
{
|
||||
rct.left = 0;
|
||||
rct.top = GetSystemMetrics(SM_CYCAPTION);
|
||||
rct.right = res + 2*GetSystemMetrics(SM_CXFRAME);
|
||||
rct.bottom = (res * 3) / 4 + 2*GetSystemMetrics(SM_CYFRAME);
|
||||
xvt_vobj_set_attr(NULL_WIN, ATTR_WIN_PM_TWIN_STARTUP_RCT, long(&rct));
|
||||
}
|
||||
else
|
||||
twin_style |= WSF_MAXIMIZED;
|
||||
}
|
||||
|
||||
xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_TWIN_STARTUP_STYLE, twin_style);
|
||||
}
|
||||
|
401
include/postman.cpp
Executable file
401
include/postman.cpp
Executable file
@ -0,0 +1,401 @@
|
||||
#include <config.h>
|
||||
#include <expr.h>
|
||||
#include <golem.h>
|
||||
#include <postman.h>
|
||||
#include <prefix.h>
|
||||
#include <recarray.h>
|
||||
#include <relapp.h>
|
||||
#include <scanner.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TRecipient
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TRecipient : public TObject
|
||||
{
|
||||
TString _address;
|
||||
TString _group;
|
||||
TString _expr;
|
||||
|
||||
public:
|
||||
const TString& address() const { return _address; }
|
||||
const TString& group() const { return _group; }
|
||||
void add_expr(char op, const TString& expr);
|
||||
bool can_receive(const TRectype& rec) const;
|
||||
|
||||
virtual bool ok() const
|
||||
{ return _address.not_empty() && _expr.not_empty(); }
|
||||
|
||||
TRecipient(const TToken_string& str);
|
||||
virtual ~TRecipient() { }
|
||||
};
|
||||
|
||||
TRecipient::TRecipient(const TToken_string& str)
|
||||
{
|
||||
str.get(0, _address);
|
||||
str.get(1, _group);
|
||||
}
|
||||
|
||||
void TRecipient::add_expr(char op, const TString& expr)
|
||||
{
|
||||
if (_expr.not_empty())
|
||||
_expr << (op == 'A' ? "AND" : "OR");
|
||||
|
||||
if (expr.blank())
|
||||
_expr << 1;
|
||||
else
|
||||
_expr << '(' << expr << ')';
|
||||
}
|
||||
|
||||
bool TRecipient::can_receive(const TRectype& rec) const
|
||||
{
|
||||
TExpression e(_expr, _strexpr, TRUE);
|
||||
for (int v = 0; v < e.numvar(); v++)
|
||||
{
|
||||
const char* name = e.varname(v);
|
||||
if (rec.exist(name))
|
||||
e.setvar(name, rec.get(name));
|
||||
else
|
||||
e.setvar(name, "");
|
||||
}
|
||||
bool yes = e.as_bool();
|
||||
return yes;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TPostman
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TPostman : public TObject
|
||||
{
|
||||
long _firm;
|
||||
bool _recipients_ok;
|
||||
TArray _recipient;
|
||||
TAssoc_array _expr;
|
||||
|
||||
protected:
|
||||
void test_firm();
|
||||
|
||||
TRecipient& recipient(int r) const
|
||||
{ return (TRecipient&)_recipient[r]; }
|
||||
|
||||
void add_expr(const TString& addr,
|
||||
char op, const TString& expr);
|
||||
|
||||
void load_filters();
|
||||
|
||||
public:
|
||||
bool can_dispatch_transaction(const TRectype& rec);
|
||||
bool dispatch_transaction(const TRectype& rec,
|
||||
const TFilename& name);
|
||||
|
||||
TExpression* get_filter_expr(const char* flt);
|
||||
const char* get_filter(const char* flt);
|
||||
bool user_can(const char* flt, const TRelation* rel);
|
||||
|
||||
TPostman();
|
||||
virtual ~TPostman() { }
|
||||
};
|
||||
|
||||
void TPostman::test_firm()
|
||||
{
|
||||
const long firm = prefix().get_codditta();
|
||||
if (firm != _firm)
|
||||
{
|
||||
_firm = firm;
|
||||
_recipients_ok = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void TPostman::add_expr(const TString& addr,
|
||||
char op, const TString& expr)
|
||||
{
|
||||
for (int r = _recipient.last(); r >= 0; r--)
|
||||
{
|
||||
TRecipient& rec = recipient(r);
|
||||
if (rec.address() == addr)
|
||||
{
|
||||
rec.add_expr(op, expr);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rec.group() == addr)
|
||||
rec.add_expr(op, expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TPostman::can_dispatch_transaction(const TRectype& rec)
|
||||
{
|
||||
test_firm();
|
||||
if (!_recipients_ok)
|
||||
{
|
||||
_recipients_ok = TRUE;
|
||||
_recipient.destroy();
|
||||
|
||||
TConfig cfg(CONFIG_DITTA, "MailTransactions");
|
||||
TToken_string str;
|
||||
TString addr, opr, expr;
|
||||
|
||||
// Costruisce la lista dei destinatari
|
||||
for (int r = 0; cfg.exist("Recipient", r); r++)
|
||||
{
|
||||
str = cfg.get("Recipient", NULL, r);
|
||||
TRecipient* rcp = new TRecipient(str);
|
||||
_recipient.add(rcp);
|
||||
}
|
||||
|
||||
// Costruisce i filtri per i destinatari
|
||||
for (int f = 0; cfg.exist("Filter", f); f++)
|
||||
{
|
||||
str = cfg.get("Filter", NULL, f);
|
||||
const int num = str.get_int(1);
|
||||
if (num != rec.num()) continue;
|
||||
|
||||
str.get(0, addr);
|
||||
str.get(2, opr);
|
||||
str.get(3, expr);
|
||||
add_expr(addr, opr[0], expr);
|
||||
}
|
||||
|
||||
// Elimina destinatari inutili
|
||||
for (int d = _recipient.last(); d >= 0; d--)
|
||||
{
|
||||
if (!recipient(d).ok())
|
||||
_recipient.destroy(d, TRUE);
|
||||
}
|
||||
}
|
||||
return _recipient.items() > 0;
|
||||
}
|
||||
|
||||
bool TPostman::dispatch_transaction(const TRectype& rec,
|
||||
const TFilename& name)
|
||||
{
|
||||
bool ok = can_dispatch_transaction(rec);
|
||||
if (ok)
|
||||
{
|
||||
TToken_string dest;
|
||||
for (int r = 0; r < _recipient.items(); r++)
|
||||
{
|
||||
const TRecipient& a = recipient(r);
|
||||
if (a.can_receive(rec))
|
||||
dest.add(a.address());
|
||||
}
|
||||
|
||||
ok = dest.items() > 0;
|
||||
if (ok)
|
||||
{
|
||||
TMail_message msg(dest.get(0));
|
||||
for (const char* r = dest.get(1); r; r = dest.get())
|
||||
msg.add_copy_recipient(r);
|
||||
|
||||
TScanner trans(name);
|
||||
while (trans.good())
|
||||
{
|
||||
TString& line = trans.line();
|
||||
msg << line << '\n';
|
||||
}
|
||||
ok = msg.send(TRUE);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TPostman::load_filters()
|
||||
{
|
||||
TRecord_cache users(LF_USER);
|
||||
TToken_string perm(4096, '\n');
|
||||
TAuto_token_string row(80);
|
||||
|
||||
// Costruisce il nome dell'applicazione principale
|
||||
TFilename app(main_app().argv(0));
|
||||
app.ext("");
|
||||
app = app.name();
|
||||
|
||||
for (int a = 1; a < main_app().argc(); a++)
|
||||
{
|
||||
row = main_app().argv(a);
|
||||
if (row[0] != '/')
|
||||
app << ' ' << row;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Stringhe delle espressioni i filtro
|
||||
TAssoc_array expr;
|
||||
|
||||
// Scandisce l'albero degli utenti/gruppi
|
||||
for (TString16 u = user();
|
||||
u.not_empty() && !users.already_loaded(u);
|
||||
u = users.get(u, "GROUPNAME"))
|
||||
{
|
||||
perm = users.get(u, "PERMISSION"); // Permessi del nodo corrente
|
||||
if (!perm.blank())
|
||||
{
|
||||
FOR_EACH_TOKEN(perm, tok)
|
||||
{
|
||||
row = tok;
|
||||
const TString80 appmod = row.get(0);
|
||||
const bool is_mod = appmod.len() == 2;
|
||||
// Il programma corrisponde
|
||||
if ((is_mod && app.compare(appmod, 2, TRUE) == 0) ||
|
||||
app.compare(appmod, -1, TRUE) == 0)
|
||||
{
|
||||
TString80 key = row.get(); key.trim(); // Tipo di filtro
|
||||
if (is_mod) key << "-MOD";
|
||||
row = row.get(); row.trim(); // Espressione di filtro
|
||||
if (key.not_empty() && row.not_empty() && row != "1")
|
||||
{
|
||||
key.upper();
|
||||
TString* str = (TString*)expr.objptr(key);
|
||||
if (str == NULL)
|
||||
{
|
||||
str = new TString(row); // Crea una nuova stringa
|
||||
expr.add(key, str);
|
||||
}
|
||||
else
|
||||
{ // Somma alla stringa precendente
|
||||
if (*str != "0") // Se sono FALSE lasciami stare
|
||||
{
|
||||
if (row != "0") // Se aggiungo qualcosa di non ovvio
|
||||
{
|
||||
str->insert("(", 0);
|
||||
*str << ")AND(";
|
||||
*str << row << ')';
|
||||
}
|
||||
else
|
||||
*str = "0";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trasforma le stringhe in espressioni
|
||||
TString esp, mod;
|
||||
FOR_EACH_ASSOC_STRING(expr, hash, key, str)
|
||||
{
|
||||
mod = key;
|
||||
if (mod.find("-MOD") < 0)
|
||||
{
|
||||
mod << "-MOD";
|
||||
const TString* modexp = (const TString*)expr.objptr(mod);
|
||||
if (modexp != NULL && *modexp != "1")
|
||||
{
|
||||
if (*modexp != "0")
|
||||
{
|
||||
esp.cut(0);
|
||||
esp << '(' << *modexp << ")AND(" << str << ')';
|
||||
}
|
||||
else
|
||||
esp = "0";
|
||||
}
|
||||
else
|
||||
esp = str;
|
||||
|
||||
TExpression* e = new TExpression(esp, _strexpr, TRUE);
|
||||
_expr.add(key, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Inserisce un elemento fasullo per segnalare l'avvenuta lettura
|
||||
if (_expr.items() == 0)
|
||||
_expr.add("", NULL);
|
||||
}
|
||||
|
||||
TExpression* TPostman::get_filter_expr(const char* flt)
|
||||
{
|
||||
if (_expr.items() == 0)
|
||||
load_filters();
|
||||
TString80 f(flt); f.upper();
|
||||
TExpression* e = (TExpression*)_expr.objptr(f);
|
||||
return e;
|
||||
}
|
||||
|
||||
const char* TPostman::get_filter(const char* flt)
|
||||
{
|
||||
TExpression* e = get_filter_expr(flt);
|
||||
return e ? e->string() : NULL;
|
||||
}
|
||||
|
||||
bool TPostman::user_can(const char* flt, const TRelation* rel)
|
||||
{
|
||||
bool yes_he_can = TRUE;
|
||||
TExpression* e = get_filter_expr(flt);
|
||||
if (e != NULL)
|
||||
{
|
||||
if (rel != NULL)
|
||||
{
|
||||
for (int i = e->numvar()-1; i >= 0; i--)
|
||||
{
|
||||
const TString& name = e->varname(i);
|
||||
const TFieldref ref(name, 0);
|
||||
const TString& val = ref.read(*rel);
|
||||
e->setvar(name, val);
|
||||
}
|
||||
yes_he_can = e->as_bool();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e->numvar() == 0)
|
||||
yes_he_can = e->as_bool();
|
||||
}
|
||||
}
|
||||
return yes_he_can;
|
||||
}
|
||||
|
||||
TPostman::TPostman() : _firm(-1), _recipients_ok(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
TPostman& postman()
|
||||
{
|
||||
static TPostman* _postman = NULL;
|
||||
if (_postman == NULL)
|
||||
_postman = new TPostman;
|
||||
return *_postman;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Public interface
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
bool can_dispatch_transaction(const TRectype& rec)
|
||||
{
|
||||
return postman().can_dispatch_transaction(rec);
|
||||
}
|
||||
|
||||
bool dispatch_transaction(const TRectype& rec, const TFilename& name)
|
||||
{
|
||||
return postman().dispatch_transaction(rec, name);
|
||||
}
|
||||
|
||||
const char* get_user_filter(const char* flt)
|
||||
{
|
||||
return postman().get_filter(flt);
|
||||
}
|
||||
|
||||
const char* get_user_read_filter()
|
||||
{
|
||||
return get_user_filter("Lettura");
|
||||
}
|
||||
|
||||
const char* get_user_write_filter()
|
||||
{
|
||||
return get_user_filter("Scrittura");
|
||||
}
|
||||
|
||||
bool user_can_read(const TRelation* rel)
|
||||
{
|
||||
return postman().user_can("Lettura", rel);
|
||||
}
|
||||
|
||||
bool user_can_write(const TRelation* rel)
|
||||
{
|
||||
return user_can_read(rel) && postman().user_can("Scrittura", rel);
|
||||
}
|
||||
|
||||
|
28
include/postman.h
Executable file
28
include/postman.h
Executable file
@ -0,0 +1,28 @@
|
||||
#ifndef __POSTMAN_H
|
||||
#define __POSTMAN_H
|
||||
|
||||
#ifndef __ISAM_H
|
||||
class TRectype;
|
||||
#endif
|
||||
|
||||
#ifndef __RELATION_H
|
||||
class TRelation;
|
||||
#endif
|
||||
|
||||
#ifndef __STRINGS_H
|
||||
class TFilename;
|
||||
#endif
|
||||
|
||||
// Mail management
|
||||
bool can_dispatch_transaction(const TRectype& rec);
|
||||
bool dispatch_transaction(const TRectype& rec, const TFilename& ini);
|
||||
|
||||
// Permission management
|
||||
const char* get_user_filter(const char* flt);
|
||||
const char* get_user_read_filter();
|
||||
const char* get_user_write_filter();
|
||||
|
||||
bool user_can_read(const TRelation* rel);
|
||||
bool user_can_write(const TRelation* rel);
|
||||
|
||||
#endif
|
@ -504,13 +504,24 @@ void TFile_cache::flush()
|
||||
// Needed by read/write cache
|
||||
}
|
||||
|
||||
bool TFile_cache::already_loaded(const char* code) const
|
||||
{
|
||||
return _cache.objptr(code) != NULL;
|
||||
}
|
||||
|
||||
bool TFile_cache::already_loaded(long code) const
|
||||
{
|
||||
TString16 str; str << code;
|
||||
return already_loaded(str);
|
||||
}
|
||||
|
||||
const TObject& TFile_cache::query(const char* code)
|
||||
{
|
||||
test_firm();
|
||||
|
||||
_error = NOERR;
|
||||
_code = code;
|
||||
|
||||
test_firm();
|
||||
|
||||
TObject* obj = _cache.objptr(_code);
|
||||
if (obj == NULL)
|
||||
{
|
||||
|
@ -170,6 +170,9 @@ public:
|
||||
const int key_number() const
|
||||
{ return _key; }
|
||||
|
||||
bool already_loaded(const char* code) const;
|
||||
bool already_loaded(long code) const;
|
||||
|
||||
long items() const
|
||||
{ return _cache.items(); }
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include <defmask.h>
|
||||
#include <mailbox.h>
|
||||
#include <msksheet.h>
|
||||
#include <postman.h>
|
||||
#include <progind.h>
|
||||
#include <sheet.h>
|
||||
#include <recarray.h>
|
||||
#include <relapp.h>
|
||||
#include <defmask.h>
|
||||
#include <utility.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -32,6 +33,39 @@ void TRelation_application::setkey()
|
||||
}
|
||||
|
||||
|
||||
void TRelation_application::set_key_filter()
|
||||
{
|
||||
TString rf = get_user_read_filter(); rf.trim();
|
||||
if (rf.not_empty())
|
||||
{
|
||||
TString expr;
|
||||
for (int f = _mask->fields()-1; f >= 0; f--)
|
||||
{
|
||||
TMask_field& fld= _mask->fld(f);
|
||||
if (fld.is_edit() && fld.in_key(0))
|
||||
{
|
||||
TBrowse* b = ((TEdit_field&)fld).browse();
|
||||
if (b)
|
||||
{
|
||||
expr = b->get_filter();
|
||||
if (expr.find(rf) < 0)
|
||||
{
|
||||
if (expr.not_empty())
|
||||
{
|
||||
expr.insert("(", 0);
|
||||
expr << ")AND(" << rf << ')';
|
||||
}
|
||||
else
|
||||
expr = rf;
|
||||
b->set_filter(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// @doc INTERNAL
|
||||
|
||||
// @mfunc Setta i limiti
|
||||
@ -101,6 +135,7 @@ bool TRelation_application::create()
|
||||
write_enable();
|
||||
_mask = get_mask(MODE_QUERY);
|
||||
filter();
|
||||
set_key_filter();
|
||||
set_limits();
|
||||
}
|
||||
return TSkeleton_application::create();
|
||||
@ -158,20 +193,22 @@ void TRelation_application::enable_query()
|
||||
|
||||
void TRelation_application::set_toolbar(bool all)
|
||||
{
|
||||
const int mode = _mask->mode();
|
||||
int pos;
|
||||
|
||||
if (all)
|
||||
{
|
||||
pos = _mask->id2pos(DLG_SAVEREC);
|
||||
bool can_edit = !_mask->query_mode();
|
||||
if (can_edit)
|
||||
can_edit = user_can_write(get_relation());
|
||||
|
||||
int pos = _mask->id2pos(DLG_SAVEREC);
|
||||
if (pos >= 0)
|
||||
_mask->fld(pos).enable(mode != MODE_QUERY);
|
||||
_mask->fld(pos).enable(can_edit);
|
||||
|
||||
pos = _mask->id2pos(DLG_DELREC);
|
||||
if (pos >= 0)
|
||||
{
|
||||
bool enabdel = mode != MODE_INS;
|
||||
if (mode == MODE_MOD)
|
||||
const int mode = _mask->mode();
|
||||
bool enabdel = mode != MODE_INS && can_edit;
|
||||
if (enabdel && mode == MODE_MOD)
|
||||
{
|
||||
TRelation& r = *get_relation();
|
||||
const TRecnotype oldpos = r.lfile().recno();
|
||||
@ -188,7 +225,11 @@ void TRelation_application::set_toolbar(bool all)
|
||||
|
||||
pos = _mask->id2pos(DLG_NEWREC);
|
||||
if (pos >= 0)
|
||||
_mask->fld(pos).enable(mode == MODE_QUERY || _lnflag == 0 );
|
||||
{
|
||||
bool enabins = (_mask->query_mode() || _lnflag == 0) &&
|
||||
user_can_write(NULL);
|
||||
_mask->fld(pos).enable(enabins);
|
||||
}
|
||||
}
|
||||
|
||||
enable_query();
|
||||
@ -252,8 +293,10 @@ bool TRelation_application::autonum(
|
||||
if (!get_next_key(k))
|
||||
{
|
||||
k = get_next_key();
|
||||
/*
|
||||
if (k.not_empty())
|
||||
NFCHECK("La 'const char* get_next_key()' verra' sostituita dalla 'bool get_next_key(TToken_string&)'");
|
||||
*/
|
||||
}
|
||||
|
||||
if (!rec && !m->query_mode())
|
||||
@ -331,7 +374,21 @@ void TRelation_application::insert_mode()
|
||||
query_insert_mode();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
TRelation* r = get_relation();
|
||||
for (int f = _mask->fields()-1; f >= 0; f--)
|
||||
{
|
||||
TMask_field& fld = _mask->fld(f);
|
||||
if (fld.is_loadable() && fld.shown() && fld.in_key(0))
|
||||
((TLoadable_field&)fld).autosave(*r);
|
||||
}
|
||||
if (!user_can_write(r))
|
||||
{
|
||||
error_box("L'utente %s non puo' inserire questo documento",
|
||||
(const char*)user());
|
||||
return;
|
||||
}
|
||||
|
||||
const bool changing = changing_mask(MODE_INS);
|
||||
TFilename workname; workname.temp("msk");
|
||||
if (changing)
|
||||
@ -351,7 +408,7 @@ void TRelation_application::insert_mode()
|
||||
}
|
||||
|
||||
set_mode(MODE_INS);
|
||||
get_relation()->zero(); // Azzera tutta la relazione!
|
||||
r->zero(); // Azzera tutta la relazione!
|
||||
|
||||
init_insert_mode(*_mask);
|
||||
|
||||
@ -362,7 +419,13 @@ void TRelation_application::insert_mode()
|
||||
|
||||
bool TRelation_application::modify_mode()
|
||||
{
|
||||
int err = get_relation()->read(_isequal, _testandlock);
|
||||
TRelation* rel = get_relation();
|
||||
if (!user_can_read(rel))
|
||||
return warning_box("I dati non sono accessibili per l'utente %s",
|
||||
(const char*)user());
|
||||
|
||||
const TReclock block = user_can_write(rel) ? _testandlock : _nolock;
|
||||
int err = rel->read(_isequal, block);
|
||||
if (err != NOERR)
|
||||
{
|
||||
if (err == _islocked)
|
||||
@ -391,7 +454,7 @@ bool TRelation_application::modify_mode()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
get_relation()->save_status();
|
||||
rel->save_status();
|
||||
init_modify_mode(*_mask);
|
||||
|
||||
// ....possibilmente spostare questa chiamata .....
|
||||
@ -681,7 +744,7 @@ bool TRelation_application::save(bool check_dirty)
|
||||
}
|
||||
was_dirty = FALSE;
|
||||
|
||||
begin_wait();
|
||||
TWait_cursor hourglass;
|
||||
if (mode == MODE_INS)
|
||||
{
|
||||
bool changed = TRUE;
|
||||
@ -718,12 +781,12 @@ bool TRelation_application::save(bool check_dirty)
|
||||
get_relation()->restore_status();
|
||||
err = rewrite(*_mask);
|
||||
}
|
||||
end_wait();
|
||||
|
||||
switch(err)
|
||||
{
|
||||
case NOERR:
|
||||
_recins = get_relation()->lfile().recno();
|
||||
mask2mail(*_mask);
|
||||
break;
|
||||
case _isreinsert:
|
||||
warning_box("Esiste gia' un documento con la stessa chiave");
|
||||
@ -833,16 +896,20 @@ bool TRelation_application::remove()
|
||||
{
|
||||
TMask &m=*_mask;
|
||||
int err = get_relation()->remove();
|
||||
const int max = m.fields();
|
||||
for (int i = 0; i < max; i++)
|
||||
for (int i = 0; i < m.fields(); i++)
|
||||
{
|
||||
if (m.fld(i).is_sheet())
|
||||
{
|
||||
TSheet_field& f = (TSheet_field& )m.fld(i);
|
||||
if (f.record()&& !f.external_record())
|
||||
err|=f.record()->remove();
|
||||
if (f.record() && !f.external_record())
|
||||
err |= f.record()->remove();
|
||||
}
|
||||
}
|
||||
if (err == NOERR)
|
||||
{
|
||||
m.set_mode(NO_MODE);
|
||||
mask2mail(m);
|
||||
}
|
||||
return err == NOERR;
|
||||
}
|
||||
|
||||
@ -935,8 +1002,10 @@ void TRelation_application::main_loop()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (find(0)) modify_mode();
|
||||
else insert_mode();
|
||||
if (find(0))
|
||||
modify_mode();
|
||||
else
|
||||
insert_mode();
|
||||
}
|
||||
if (_curr_trans_mode == TM_AUTOMATIC)
|
||||
_mask->send_key(K_CTRL+'R', 0);
|
||||
@ -1347,8 +1416,8 @@ void TRelation_application::edit_mask2ini()
|
||||
{
|
||||
if (_trans_ini.row(_trans_counter).not_empty())
|
||||
{
|
||||
TString head;
|
||||
head.format("%d", get_relation()->lfile().num());
|
||||
TString16 head;
|
||||
head << get_relation()->lfile().num();
|
||||
TConfig ini(_trans_ini.row(_trans_counter), head);
|
||||
mask2ini(*_mask, ini);
|
||||
}
|
||||
@ -1356,19 +1425,52 @@ void TRelation_application::edit_mask2ini()
|
||||
|
||||
void TRelation_application::mask2ini(const TMask& m, TConfig& ini)
|
||||
{
|
||||
ini.set("Firm", get_firm(), "Transaction");
|
||||
|
||||
TString16 defpar; defpar << get_relation()->lfile().num();
|
||||
TString str(80);
|
||||
|
||||
ini.set("Firm", get_firm(), "Transaction");
|
||||
for (int f = m.fields()-1; f >= 0; f--)
|
||||
{
|
||||
TMask_field& campo = m.fld(f);
|
||||
if (campo.field() && campo.shown())
|
||||
{
|
||||
str = campo.get();
|
||||
const TString& str = campo.get();
|
||||
campo.field()->write(ini, defpar, str);
|
||||
}
|
||||
}
|
||||
ini.set_paragraph(defpar);
|
||||
}
|
||||
|
||||
bool TRelation_application::mask2mail(const TMask& m)
|
||||
{
|
||||
if (::can_dispatch_transaction(get_relation()->curr()))
|
||||
{
|
||||
TWait_cursor hourglass;
|
||||
TFilename ininame; ininame.temp();
|
||||
if (!ininame.exist()) // Test qualunque per usare {}
|
||||
{
|
||||
TConfig ini(ininame, "Transaction");
|
||||
const char* action = "";
|
||||
char mode[2] = { TM_AUTOMATIC, '\0' };
|
||||
switch (m.mode())
|
||||
{
|
||||
case NO_MODE:
|
||||
action = TRANSACTION_DELETE;
|
||||
break;
|
||||
case MODE_MOD:
|
||||
action = TRANSACTION_MODIFY;
|
||||
break;
|
||||
default:
|
||||
action = TRANSACTION_INSERT;
|
||||
break;
|
||||
}
|
||||
ini.set("Action", action);
|
||||
ini.set("Mode", mode);
|
||||
mask2ini(m, ini);
|
||||
}
|
||||
::dispatch_transaction(get_relation()->curr(), ininame);
|
||||
::remove(ininame);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,6 +85,8 @@ private:
|
||||
|
||||
// @cmember:(INTERNAL) Seleziona il nuovo modo e ritorna il vecchio
|
||||
int set_mode(int mode);
|
||||
// @Setta i filtri di lettura
|
||||
void set_key_filter();
|
||||
// @cmember:(INTERNAL) Setta i limiti
|
||||
void set_limits(byte what = 0x3);
|
||||
// @cmember:(INTERNAL) Posiziona l'applicazione in modo richiesta/inserimento (chiama <mf TRelation_application::query_mode>)
|
||||
@ -221,6 +223,7 @@ protected:
|
||||
void edit_mask2ini();
|
||||
virtual void ini2mask(TConfig& ini, TMask& m, bool query);
|
||||
virtual void mask2ini(const TMask& m, TConfig& ini);
|
||||
virtual bool mask2mail(const TMask& m);
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
|
@ -914,7 +914,7 @@ HIDDEN bool __evalcondition(const TRelation& r,TExpression* cond, const TArray &
|
||||
// f = cond->varname(i);
|
||||
cond->setvar(i, (const char *) (TRecfield &)frefs[i]);
|
||||
}
|
||||
return (bool) *cond;
|
||||
return cond->as_bool();
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
@ -1903,10 +1903,12 @@ void TFieldref::write(TConfig& ini, const char* defpar, const char* val) const
|
||||
return;
|
||||
|
||||
const char* para = _id.empty() ? defpar : _id;
|
||||
if (_from > 0)
|
||||
if (_from > 0 || _to > 0)
|
||||
{
|
||||
buffer = ini.get(_name, para);
|
||||
buffer.overwrite(val, _from);
|
||||
buffer.overwrite(val, _from + buffer[0] == '"');
|
||||
if (buffer[0] == ' ') // Metto le virgolette
|
||||
{ buffer.insert("\"", 0); buffer << '"'; }
|
||||
ini.set(_name, buffer, para);
|
||||
}
|
||||
else
|
||||
|
@ -618,7 +618,7 @@ void TSheet_control::load_columns_order(const TMask_field& field)
|
||||
void TSheet_control::align_column(int c, bool right)
|
||||
{
|
||||
XI_OBJ* column = find_column(c);
|
||||
CHECK(column, "Can't find numeric column");
|
||||
CHECKD(column, "Can't find numeric column ", c);
|
||||
dword attr = xi_get_attrib(column);
|
||||
if (right)
|
||||
attr |= XI_ATR_RJUST;
|
||||
|
@ -16,6 +16,7 @@ class TStack : public TObject
|
||||
|
||||
// @access:(INTERNAL) Private Member
|
||||
{
|
||||
protected:
|
||||
// @cmember:(INTERNAL) Dati dello stack
|
||||
TArray _data;
|
||||
// @cmember:(INTERNAL) Puntatore alla cima dello stack
|
||||
|
@ -434,6 +434,8 @@ int TString::find(const char* s, int from) const
|
||||
|
||||
bool TString::match(const char* pat) const
|
||||
{
|
||||
if (pat == NULL || *pat =='\0')
|
||||
return empty();
|
||||
return ::match(pat, _str);
|
||||
}
|
||||
|
||||
@ -1709,6 +1711,28 @@ void TToken_string::destroy(int n)
|
||||
restart();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TAuto_token_string
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
TAuto_token_string& TAuto_token_string::create(const char* ts)
|
||||
{
|
||||
// Copia la stringa
|
||||
set(ts);
|
||||
|
||||
// Calcola il separatore
|
||||
for (const char* s = ts; *s; s++)
|
||||
{
|
||||
if (strchr("|¦\t\n^;,!&+", *s) != NULL)
|
||||
{
|
||||
separator(*s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Paragraph string
|
||||
///////////////////////////////////////////////////////////
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __STRINGS_H
|
||||
#define __STRINGS_H
|
||||
|
||||
#ifndef __STRING_H
|
||||
#ifndef _INC_STRING
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
@ -311,6 +311,9 @@ class TString16 : public TFixed_string
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Duplica una stringa di 16 caratteri
|
||||
virtual TObject* dup() const { return new TString16(_str16); }
|
||||
|
||||
// @cmember Costruttore
|
||||
TString16(const char* s = "") : TFixed_string(_str16, 17)
|
||||
{ set(s); }
|
||||
@ -350,6 +353,9 @@ class TString80 : public TFixed_string
|
||||
char _str80[81];
|
||||
|
||||
public:
|
||||
// @cmember Duplica una stringa di 80 caratteri
|
||||
virtual TObject* dup() const { return new TString80(_str80); }
|
||||
|
||||
TString80(const char* s = "") : TFixed_string(_str80, 81) { set(s); }
|
||||
TString80(const TString& s) : TFixed_string(_str80, 81) { set(s); }
|
||||
TString80(const TString80& s) : TFixed_string(_str80, 81) { set(s); }
|
||||
@ -373,6 +379,9 @@ class TString256 : public TFixed_string
|
||||
char _str256[257];
|
||||
|
||||
public:
|
||||
// @cmember Duplica una stringa di 256 caratteri
|
||||
virtual TObject* dup() const { return new TString256(_str256); }
|
||||
|
||||
TString256(const char* s = "") : TFixed_string(_str256, 257) { set(s); }
|
||||
TString256(const TString& s) : TFixed_string(_str256, 257) { set(s); }
|
||||
TString256(const TString256& s) : TFixed_string(_str256, 257) { set(s); }
|
||||
@ -548,10 +557,28 @@ public:
|
||||
#define FOR_EACH_TOKEN_STRING(__tok, __count, __str) \
|
||||
TString __str; \
|
||||
for (int __count = 0; __tok.get(__count, __str); __count++)
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Mitica token string che sceglie da sola il separatore
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TAuto_token_string : public TToken_string
|
||||
{
|
||||
protected:
|
||||
TAuto_token_string& create(const char* ts);
|
||||
|
||||
public:
|
||||
TAuto_token_string& operator=(const char* ts) { return create(ts); }
|
||||
TAuto_token_string& operator=(const TString& ts) { return create(ts); }
|
||||
TAuto_token_string& operator=(const TToken_string& ts) { return create(ts); }
|
||||
TAuto_token_string& operator=(const TAuto_token_string& ts) { return create(ts); }
|
||||
TAuto_token_string(int sz = 50) : TToken_string(sz) { }
|
||||
TAuto_token_string(const char* ts) { create(ts); }
|
||||
virtual ~TAuto_token_string() { }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// DES Paragraph
|
||||
// TParagraph_string
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// @doc EXTERNAL
|
||||
@ -643,15 +670,15 @@ const TToken_string& empty_string();
|
||||
|
||||
#define FOR_EACH_ARRAY_ROW(__arr, __r, __riga) \
|
||||
TToken_string* __riga; \
|
||||
for (int __r = __arr.first(); \
|
||||
__riga = (TToken_string*)__arr.objptr(__r); \
|
||||
__r = __arr.succ(__r))
|
||||
for (int __r = (__arr).first(); \
|
||||
__riga = (TToken_string*)(__arr).objptr(__r); \
|
||||
__r = (__arr).succ(__r))
|
||||
|
||||
#define FOR_EACH_ARRAY_ROW_BACK(__arr, __r, __riga) \
|
||||
TToken_string* __riga; \
|
||||
for (int __r = __arr.last(); \
|
||||
__riga = (TToken_string*)__arr.objptr(__r); \
|
||||
__r = __arr.pred(__r))
|
||||
for (int __r = (__arr).last(); \
|
||||
__riga = (TToken_string*)(__arr).objptr(__r); \
|
||||
__r = (__arr).pred(__r))
|
||||
|
||||
const char SLASH =
|
||||
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#define __TABUTIL_CPP
|
||||
#include <tabutil.h>
|
||||
|
||||
#include <config.h>
|
||||
#include <extcdecl.h>
|
||||
#include <scanner.h>
|
||||
#include <utility.h>
|
||||
@ -189,16 +191,70 @@ void TTable::load_module_description()
|
||||
_module = "ba";
|
||||
}
|
||||
|
||||
const char* TTable::module()
|
||||
const char* TTable::module()
|
||||
{
|
||||
if (!_des_mod_loaded)
|
||||
load_module_description();
|
||||
return _module;
|
||||
}
|
||||
|
||||
const char* TTable::description()
|
||||
const char* TTable::description()
|
||||
{
|
||||
if (!_des_mod_loaded)
|
||||
load_module_description();
|
||||
return _description;
|
||||
}
|
||||
|
||||
struct TCallbackTableinfo
|
||||
{
|
||||
TString16 _var1, _var2;
|
||||
TString16 _module;
|
||||
TFilename _app;
|
||||
};
|
||||
|
||||
HIDDEN int find_relapp(TConfig& cfg, void* jolly)
|
||||
{
|
||||
TCallbackTableinfo& info = *((TCallbackTableinfo*)jolly);
|
||||
if (cfg.get_paragraph().compare(info._module, 2, TRUE) == 0)
|
||||
{
|
||||
for (int v = 1; v <= 2; v++)
|
||||
{
|
||||
const TString& var = v == 1 ? info._var1 : info._var2;
|
||||
if (cfg.exist(var))
|
||||
{
|
||||
info._app = cfg.get(var);
|
||||
return info._app.not_empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool TTable::get_relapp(TString& app) const
|
||||
{
|
||||
TConfig ini("install.ini");
|
||||
TCallbackTableinfo fi;
|
||||
fi._var1.format("Edit_%d", num());
|
||||
fi._var2.format("Edit_%d", num() == LF_TAB ? LF_TABCOM : LF_TAB);
|
||||
fi._module = ((TTable*)this)->module();
|
||||
ini.for_each_paragraph(find_relapp, &fi);
|
||||
|
||||
if (fi._app.not_empty())
|
||||
app = fi._app;
|
||||
else
|
||||
{
|
||||
app = "ba3 -0";
|
||||
if (fi._module.compare("ba", 2, TRUE) != 0)
|
||||
{
|
||||
TConfig c(CONFIG_STUDIO, fi._module);
|
||||
if (c.exist("TabPrg"))
|
||||
app = c.get("TabPrg");
|
||||
}
|
||||
app << ' ';
|
||||
if (num() == LF_TABCOM)
|
||||
app << '%';
|
||||
app << _tabname;
|
||||
}
|
||||
return app.not_empty();
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,8 @@ public:
|
||||
// @cmember Distruttore
|
||||
virtual ~TTable();
|
||||
|
||||
virtual bool get_relapp(TString& app) const;
|
||||
|
||||
// @cmember Ritorna il numero logico della tabella <p tabname>
|
||||
static int name2log(const char* tabname);
|
||||
};
|
||||
|
@ -226,11 +226,14 @@ bool TTree::expanded() const
|
||||
|
||||
bool TTree::expand()
|
||||
{
|
||||
TString str;
|
||||
curr_id(str);
|
||||
bool ok = !_expanded.is_key(str) && has_son();
|
||||
bool ok = enabled() && has_son();
|
||||
if (ok)
|
||||
_expanded.add(str);
|
||||
{
|
||||
TString str; curr_id(str);
|
||||
ok = !_expanded.is_key(str);
|
||||
if (ok)
|
||||
_expanded.add(str);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -394,7 +397,7 @@ bool TObject_tree::expanded() const
|
||||
|
||||
bool TObject_tree::expand()
|
||||
{
|
||||
bool ok = _current && _current->_son && !_current->_expanded;
|
||||
bool ok = _current && _current->_son && !_current->_expanded && enabled();
|
||||
if (ok)
|
||||
_current->_expanded = TRUE;
|
||||
return ok;
|
||||
@ -507,7 +510,7 @@ bool TObject_tree::create_root()
|
||||
bool TObject_tree::add_son(TObject* obj)
|
||||
{
|
||||
bool ok = FALSE;
|
||||
if (_current)
|
||||
if (_root)
|
||||
{
|
||||
TTree_node*& curson = _current->_son;
|
||||
TTree_node* newson = new TTree_node;
|
||||
@ -701,6 +704,7 @@ class TNode_info : public TSortable
|
||||
{
|
||||
public:
|
||||
bool _valid : 1;
|
||||
bool _enabled : 1;
|
||||
bool _expandable : 1;
|
||||
bool _expanded : 1;
|
||||
TString _id;
|
||||
@ -711,6 +715,7 @@ public:
|
||||
const TNode_info& operator =(const TNode_info& ni)
|
||||
{
|
||||
_valid = ni._valid;
|
||||
_enabled = ni._enabled;
|
||||
_expanded = ni._expanded;
|
||||
_expandable = ni._expandable;
|
||||
_id = ni._id;
|
||||
@ -884,21 +889,16 @@ bool TTree_window::callback_draw_node(TTree& node, void* jolly, word when)
|
||||
{
|
||||
node.curr_id(ui->_str);
|
||||
const bool is_selected = ui->_str == ui->_curr_info->_id;
|
||||
const bool is_enabled = node.enabled();
|
||||
int text_len = 0;
|
||||
if (node.get_description(ui->_str))
|
||||
{
|
||||
text_len = ui->_str.len();
|
||||
if (is_selected)
|
||||
{
|
||||
ui->_win->set_color(FOCUS_COLOR, FOCUS_BACK_COLOR);
|
||||
ui->_win->set_opaque_text(TRUE);
|
||||
}
|
||||
else
|
||||
ui->_win->set_color(is_enabled ? NORMAL_COLOR : DISABLED_COLOR, NORMAL_BACK_COLOR);
|
||||
ui->_win->stringat(int(ui->_x+2), int(ui->_y), ui->_str);
|
||||
if (is_selected)
|
||||
{
|
||||
ui->_win->set_color(NORMAL_COLOR, NORMAL_BACK_COLOR);
|
||||
ui->_win->set_opaque_text(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
const int ry = int(ui->_y - ui->_firsty);
|
||||
@ -923,14 +923,28 @@ bool TTree_window::callback_draw_node(TTree& node, void* jolly, word when)
|
||||
|
||||
TImage* bmp = node.image(is_selected);
|
||||
if (bmp)
|
||||
bmp->draw(win, p.h, p.v + (_row_height - bmp->height()) / 2);
|
||||
{
|
||||
const int x = p.h;
|
||||
const int y = p.v + (_row_height - bmp->height()) / 2;
|
||||
if (is_enabled)
|
||||
bmp->draw(win, x, y);
|
||||
else
|
||||
{
|
||||
TImage dis(*bmp);
|
||||
for (int j = dis.height()-1; j >= 0; j--)
|
||||
for (int i = dis.width() - (j&1 ? 2 : 1); i >= 0; i-=2)
|
||||
dis.set_pixel(i, j, NORMAL_BACK_COLOR);
|
||||
dis.draw(win, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
TNode_info& ni = (*ui->_node_info)[ry];
|
||||
node.curr_id(ni._id);
|
||||
ni._valid = TRUE;
|
||||
ni._startx = ui->_x;
|
||||
ni._endx = ui->_x + text_len + 2;
|
||||
ni._expandable = node.has_son();
|
||||
ni._valid = TRUE;
|
||||
ni._startx = ui->_x;
|
||||
ni._endx = ui->_x + text_len + 2;
|
||||
ni._enabled = is_enabled;
|
||||
ni._expandable = is_enabled && node.has_son();
|
||||
if (ni._expandable)
|
||||
{
|
||||
ni._plusx = ui->_x - TABX + 1;
|
||||
@ -1051,6 +1065,7 @@ void TTree_window::update()
|
||||
}
|
||||
|
||||
_node_info.reset();
|
||||
set_opaque_text(TRUE);
|
||||
|
||||
word flags = SCAN_PRE_ORDER | SCAN_IN_ORDER | SCAN_IGNORING_UNEXPANDED;
|
||||
if (_hide_leaves) flags |= SCAN_IGNORING_LEAVES;
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
virtual bool expand_all();
|
||||
virtual bool shrink_all();
|
||||
virtual TImage* image(bool selected) const;
|
||||
virtual bool enabled() const { return TRUE; }
|
||||
bool disabled() const { return !enabled(); }
|
||||
|
||||
virtual bool scan_depth_first(NODE_HANDLER nh, void* jolly, word flags = SCAN_PRE_ORDER);
|
||||
virtual bool scan_breadth_first(NODE_HANDLER nh, void* jolly, word flags = SCAN_PRE_ORDER);
|
||||
|
@ -367,6 +367,13 @@ TImage::TImage(short id) : _image(NULL)
|
||||
TImage::TImage(const TImage& im, short w, short h) : _image(NULL)
|
||||
{
|
||||
const XVT_IMAGE_FORMAT fmt = xvt_image_get_format(im._image);
|
||||
if (w < 0 || h < 0)
|
||||
{
|
||||
short iw, ih;
|
||||
xvt_image_get_dimensions(im._image, &iw, &ih);
|
||||
if (w < 0) w = iw;
|
||||
if (h < 0) h = ih;
|
||||
}
|
||||
set(xvt_image_create(fmt, w, h, NULL));
|
||||
|
||||
if (ok())
|
||||
@ -482,6 +489,16 @@ void TImage::set_clut(byte n, COLOR c)
|
||||
xvt_image_set_clut(_image, n, c);
|
||||
}
|
||||
|
||||
void TImage::set_pixel(int x, int y, COLOR col)
|
||||
{
|
||||
xvt_image_set_pixel(_image, x, y, col);
|
||||
}
|
||||
|
||||
COLOR TImage::get_pixel(int x, int y) const
|
||||
{
|
||||
return xvt_image_get_pixel(_image, x, y);
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
// @doc EXTERNAL
|
||||
|
||||
@ -520,7 +537,7 @@ void TImage::convert_transparent_color(COLOR transparent)
|
||||
{
|
||||
if (_image)
|
||||
{
|
||||
const COLOR trans = xvt_image_get_pixel(_image, 0, 0) & 0x00FFFFFF;
|
||||
const COLOR trans = get_pixel(0, 0) & 0x00FFFFFF;
|
||||
if (trans != (transparent & 0x00FFFFFF) &&
|
||||
xvt_image_get_format(_image) == XVT_IMAGE_CL8)
|
||||
{
|
||||
|
@ -89,6 +89,10 @@ public:
|
||||
void draw(WINDOW w, const RCT& dst) const;
|
||||
// @cmember Disegna l'immagine sulla finestra
|
||||
void draw(WINDOW w, const RCT& dst, const RCT& src) const;
|
||||
// @cmember Setta un pixel
|
||||
void set_pixel(int x, int y, COLOR c);
|
||||
// @cmember Legge un pixel
|
||||
COLOR get_pixel(int x, int y) const;
|
||||
|
||||
// @cmember Setta l'immagine e le sue dimensioni
|
||||
XVT_IMAGE set(XVT_IMAGE i);
|
||||
@ -127,7 +131,7 @@ public:
|
||||
// @cmember Costruttore. Viene passato l'identificatore dell'immagine sul file di risorsa
|
||||
TImage(short id);
|
||||
// @cmember Costruttore. Viene passata l'immagine e le sue diemsioni
|
||||
TImage(const TImage& i, short width, short height);
|
||||
TImage(const TImage& i, short width = -1, short height = -1);
|
||||
// @cmember Costruttore. Viene passata l'immagine e le sue diemsioni
|
||||
TImage(short width, short height, XVT_IMAGE_FORMAT fmt = XVT_IMAGE_CL8);
|
||||
// @cmember Distruttore
|
||||
|
Loading…
x
Reference in New Issue
Block a user