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:
guy 1998-12-10 16:25:48 +00:00
parent 6e30f9c6dd
commit 1855e56994
40 changed files with 1477 additions and 307 deletions

View File

@ -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:

View File

@ -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();

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -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;}

View File

@ -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
///////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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;

View File

@ -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>

View File

@ -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;

View File

@ -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)

View File

@ -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() { }
};

View File

@ -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;

View File

@ -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

View File

@ -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());

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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
View 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
View 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

View File

@ -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)
{

View File

@ -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(); }

View File

@ -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;
}

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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
///////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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();
}

View File

@ -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);
};

View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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