36d6a7f5e7
Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 22.1 patch 246 git-svn-id: svn://10.65.10.50/trunk@12818 c028cbd2-c16b-5b4b-a496-9718f37d4682
766 lines
16 KiB
C++
Executable File
766 lines
16 KiB
C++
Executable File
#include <applicat.h>
|
|
#include <currency.h>
|
|
#include <dongle.h>
|
|
#include <execp.h>
|
|
#include <mask.h>
|
|
#include <printer.h>
|
|
#include <relation.h>
|
|
#include <utility.h>
|
|
|
|
#include "ba0100a.h"
|
|
#include "ba0101.h"
|
|
#include "ba0100.h"
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Utility
|
|
///////////////////////////////////////////////////////////
|
|
|
|
bool sys_dll_changed()
|
|
{
|
|
TString_array list;
|
|
int k = list_files("*.dl_", list);
|
|
if (k == 0)
|
|
k = list_files("*.ex_", list);
|
|
return k > 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Menu management
|
|
///////////////////////////////////////////////////////////
|
|
|
|
static int get_next_string(const char* s, int from, TString& str, char& brace)
|
|
{
|
|
if (from < 0)
|
|
return -1;
|
|
|
|
char closing = '\0';
|
|
int start = 0;
|
|
|
|
for (int i = from; s[i]; i++)
|
|
{
|
|
if (s[i] == closing)
|
|
{
|
|
char* fine = (char*)(s + i);
|
|
const char old = *fine;
|
|
*fine = '\0';
|
|
str = s + start;
|
|
*fine = old;
|
|
return i+1;
|
|
}
|
|
|
|
if (!closing)
|
|
{
|
|
switch(s[i])
|
|
{
|
|
case '\'':
|
|
case '"' : closing = s[i]; break;
|
|
case '<' : closing = '>' ; break;
|
|
case '[' : closing = ']' ; break;
|
|
default : break;
|
|
}
|
|
if (closing)
|
|
{
|
|
start = i+1;
|
|
brace = s[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int get_next_int(const char* s, int from, int& val)
|
|
{
|
|
if (from < 0)
|
|
return -1;
|
|
|
|
const char* start = NULL;
|
|
int i = 0;
|
|
for (i = from; s[i]; i++)
|
|
{
|
|
if (start == NULL)
|
|
{
|
|
if (isdigit(s[i]))
|
|
start = s+i;
|
|
}
|
|
else
|
|
{
|
|
if (s[i] == ',')
|
|
break;
|
|
}
|
|
}
|
|
if (start != NULL)
|
|
val = atoi(start);
|
|
|
|
return i;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TTimed_image
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TTimed_image : public TImage
|
|
{
|
|
clock_t _last_time;
|
|
|
|
public:
|
|
clock_t touch() { return _last_time = clock(); }
|
|
clock_t last_time() const { return _last_time; }
|
|
|
|
TTimed_image(const char* name) : TImage(name) { touch(); }
|
|
virtual ~TTimed_image() { }
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Menu Item
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TMenuitem::TMenuitem(TSubmenu* sm)
|
|
: _submenu(sm), _icon(0),_color(NORMAL_COLOR), _exist(-1),
|
|
_firm(FALSE), _password(FALSE), _reloadmenu(FALSE)
|
|
|
|
{ }
|
|
|
|
TMenuitem::TMenuitem(const TMenuitem& mi)
|
|
{
|
|
_submenu = mi._submenu;
|
|
_exist = mi._exist;
|
|
_firm = mi._firm;
|
|
_password = mi._password;
|
|
_reloadmenu = mi._reloadmenu;
|
|
_color = mi._color;
|
|
_icon = mi._icon;
|
|
_enabled = mi._enabled;
|
|
_caption = mi._caption;
|
|
_action = mi._action;
|
|
_type = mi._type;
|
|
}
|
|
|
|
|
|
TMenu& TMenuitem::menu() const
|
|
{ return _submenu->menu(); }
|
|
|
|
void TMenuitem::create(const char* t)
|
|
{
|
|
TString16 flags;
|
|
char brace;
|
|
int start = 0;
|
|
|
|
start = get_next_string(t, start, _caption, brace);
|
|
start = get_next_string(t, start, _action, _type);
|
|
start = get_next_string(t, start, flags, brace);
|
|
start = get_next_int(t, start, _icon);
|
|
_caption = dictionary_translate(_caption);
|
|
|
|
for (int i = flags.len()-1; i >= 0; i--)
|
|
{
|
|
switch(toupper(flags[i]))
|
|
{
|
|
case 'D': _exist = FALSE; break;
|
|
case 'F': _firm = TRUE; break;
|
|
case 'P': _password = TRUE; break;
|
|
case 'R': _reloadmenu = TRUE; break;
|
|
default : break;
|
|
}
|
|
}
|
|
|
|
if (_type == '<')
|
|
{
|
|
if (_action.find('.') < 0)
|
|
_action << ".men";
|
|
TFilename n = _action;
|
|
if (n.custom_path())
|
|
menu().read(_action, _action);
|
|
else
|
|
_action.cut(0);
|
|
_type = '[';
|
|
}
|
|
|
|
if (_action.empty())
|
|
{
|
|
_exist = FALSE;
|
|
_enabled = FALSE;
|
|
}
|
|
|
|
// Controlla lo stato di aggiornamento
|
|
if (_enabled && is_program())
|
|
_enabled = !menu().is_dangerous(_action);
|
|
}
|
|
|
|
int TMenuitem::icon() const
|
|
{
|
|
return _icon;
|
|
}
|
|
|
|
bool TMenuitem::enabled() const
|
|
{
|
|
bool yes = FALSE;
|
|
if (_exist)
|
|
{
|
|
if (is_submenu())
|
|
{
|
|
TSubmenu* mnu = menu().find(_action);
|
|
yes = mnu && mnu->enabled() && mnu->items() > 0;
|
|
}
|
|
else
|
|
{
|
|
if (_exist < 0)
|
|
{
|
|
if (menu().is_dangerous(_action))
|
|
{
|
|
yes = false;
|
|
}
|
|
else
|
|
{
|
|
const int endname = _action.find(' ');
|
|
const TFilename name(endname > 0 ? _action.left(endname) : _action);
|
|
TFilename n = name;
|
|
if (n.custom_path())
|
|
yes = true;
|
|
else
|
|
{
|
|
const char* ext[] = { "exe", "pif", "com", "bat", NULL };
|
|
int e;
|
|
|
|
for (e = 0; ext[e]; e++)
|
|
{
|
|
n = name; n.ext(ext[e]);
|
|
if (n.custom_path())
|
|
break;
|
|
}
|
|
yes = ext[e] != NULL;
|
|
}
|
|
}
|
|
((TMenuitem*)this)->_exist = yes;
|
|
}
|
|
if (_exist)
|
|
{
|
|
TExternal_app app(_action);
|
|
yes = app.can_run();
|
|
}
|
|
if (!yes)
|
|
((TMenuitem*)this)->_enabled = FALSE;
|
|
}
|
|
}
|
|
return yes;
|
|
}
|
|
|
|
bool TMenuitem::perform_submenu() const
|
|
{
|
|
TSubmenu* mnu = menu().find(_action);
|
|
bool ok = mnu != NULL && mnu->enabled();
|
|
if (ok)
|
|
ok = menu().jumpto(mnu);
|
|
return ok;
|
|
}
|
|
|
|
bool TMenuitem::perform_program() const
|
|
{
|
|
bool ok = TRUE;
|
|
|
|
if (_password)
|
|
{
|
|
TMask mask("ba0100a");
|
|
mask.disable(F_USER);
|
|
mask.set(F_USER, "SERVIZIO");
|
|
ok = FALSE;
|
|
if (mask.run() == K_ENTER)
|
|
{
|
|
const TDate oggi(TODAY);
|
|
TString16 pwd; pwd << dongle().administrator() << (oggi.month() + oggi.day());
|
|
ok = pwd == mask.get(F_PASSWORD);
|
|
}
|
|
if (!ok) error_box("Password di servizio errata!\nAccesso negato.");
|
|
}
|
|
|
|
if (_firm && main_app().get_firm() == 0)
|
|
#ifdef _DEMO_
|
|
ok = menu().set_firm(1);
|
|
#else
|
|
ok = menu().set_firm(0);
|
|
#endif
|
|
|
|
if (ok)
|
|
{
|
|
TCurrency::force_cache_update(); // Chiude cache valute
|
|
prefix().set(NULL); // Chiude prefix
|
|
TExternal_app a(_action);
|
|
a.run(FALSE,3);
|
|
|
|
const bool maintenance_app = _action.starts_with("ba1 -0", TRUE);
|
|
if (maintenance_app)
|
|
{
|
|
char line1[16],line2[16];
|
|
|
|
while (fexist("conv.his"))
|
|
{
|
|
FILE* fp = fopen("conv.his","r");
|
|
fgets(line1,15,fp);
|
|
fclose(fp);
|
|
// Ora aspetta...
|
|
time_t old_time ;
|
|
time( &old_time) ;
|
|
while ( time( (time_t *) 0 ) <= old_time ) do_events();
|
|
TExternal_app auto_conv("ba1 -0 -C");
|
|
auto_conv.run();
|
|
fp = fopen("conv.his","r");
|
|
if (fp != NULL)
|
|
{
|
|
fgets(line2,15,fp);
|
|
fclose(fp);
|
|
}
|
|
else strcpy(line2,"");
|
|
if (strcmp(line1,line2) == 0)
|
|
if (!yesno_box("La conversione non sembra procedere. Continuare?"))
|
|
break;
|
|
}
|
|
}
|
|
prefix().set("DEF"); // Aggiorna prefix
|
|
|
|
const bool install_app = _action.starts_with("ba1 -6", TRUE);
|
|
if (install_app && sys_dll_changed())
|
|
{
|
|
WINDOW w = cur_win();
|
|
if (w != NULL_WIN)
|
|
dispatch_e_char(w, K_QUIT);
|
|
|
|
}
|
|
|
|
printer_destroy(); // Forza rilettura parametri della stampante
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TMenuitem::perform() const
|
|
{
|
|
bool ok = enabled();
|
|
if (ok)
|
|
{
|
|
if (is_submenu())
|
|
ok = perform_submenu();
|
|
else
|
|
ok = perform_program();
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Submenu
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TSubmenu::TSubmenu(TMenu* menu, const char* name)
|
|
: _menu(menu), _name(name), _items(12), _enabled(TRUE), _firm(FALSE)
|
|
{
|
|
}
|
|
|
|
void TSubmenu::read(TScanner& scanner)
|
|
{
|
|
while (scanner.ok())
|
|
{
|
|
TString& line = scanner.line();
|
|
if (line.empty())
|
|
break;
|
|
if (line[0] == '[')
|
|
{
|
|
scanner.push();
|
|
break;
|
|
}
|
|
|
|
char brace;
|
|
if (line.compare("Caption", 7, TRUE) == 0)
|
|
{
|
|
get_next_string(line, 8, _caption, brace);
|
|
_caption = dictionary_translate(_caption);
|
|
} else
|
|
if (line.compare("Module", 6, TRUE) == 0)
|
|
{
|
|
const int equal = line.find('=');
|
|
if (equal > 0)
|
|
{
|
|
bool disable = TRUE;
|
|
TToken_string mod(line.mid(equal+1, -1), ',');
|
|
FOR_EACH_TOKEN(mod, cod)
|
|
{
|
|
const int code = atoi(cod);
|
|
if (code == 0 || main_app().has_module(code))
|
|
{
|
|
disable = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if (disable)
|
|
_enabled = FALSE;
|
|
}
|
|
} else
|
|
if (line.compare("Picture", 7, TRUE) == 0)
|
|
{
|
|
// Estrae solamente il nome del file immagine, elimina path ed estensione
|
|
TFilename name;
|
|
get_next_string(line, 8, name, brace);
|
|
xvt_fsys_parse_pathname(name, NULL, NULL, _picture.get_buffer(), NULL, NULL);
|
|
} else
|
|
if (line.compare("Flags", 5, TRUE) == 0)
|
|
{
|
|
TString16 flags;
|
|
get_next_string(line, 6, flags, brace);
|
|
if (flags.find('D') >= 0)
|
|
_enabled = FALSE;
|
|
if (flags.find('F') >= 0)
|
|
_firm = TRUE;
|
|
} else
|
|
if (line.compare("Item", 4, TRUE) == 0)
|
|
{
|
|
TMenuitem* item = new TMenuitem(this);
|
|
add(item);
|
|
item->create(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
int TSubmenu::find_string(const TString& str) const
|
|
{
|
|
bool found = FALSE;
|
|
|
|
TString caption;
|
|
caption = _caption; caption.upper();
|
|
if (caption.find(str) >= 0 || caption.match(str))
|
|
found = TRUE;
|
|
|
|
for (int i = 0; i < items(); i++)
|
|
{
|
|
const TMenuitem& mi = item(i);
|
|
caption = item(i).caption();
|
|
caption.upper();
|
|
const bool match = caption.find(str) >= 0 || caption.match(str);
|
|
found = match && mi.is_program() && mi.enabled();
|
|
if (found)
|
|
return i;
|
|
}
|
|
|
|
return found ? 0 : -1;
|
|
}
|
|
|
|
int TSubmenu::find(const TMenuitem& it) const
|
|
{
|
|
int i;
|
|
for (i = items()-1; i >= 0; i--)
|
|
{
|
|
const TMenuitem& mi = item(i);
|
|
if (mi.action() == it.action())
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
TImage& TSubmenu::image() const
|
|
{
|
|
return menu().image(picture());
|
|
}
|
|
|
|
bool TSubmenu::perform(int i)
|
|
{
|
|
bool ok = i >= 0 && i < items();
|
|
if (ok)
|
|
ok = item(i).perform();
|
|
return ok;
|
|
}
|
|
|
|
bool TMenu::read(const char* name, TString& root)
|
|
{
|
|
TString str(255);
|
|
bool first = TRUE;
|
|
|
|
TFilename menuname = name;
|
|
menuname.custom_path();
|
|
TScanner scanner(menuname);
|
|
while (scanner.ok())
|
|
{
|
|
const TString& line = first ? scanner.line() : scanner.pop();
|
|
if (line.empty())
|
|
break;
|
|
|
|
char brace = '[';
|
|
get_next_string(line, 0, str, brace);
|
|
|
|
if (first)
|
|
{
|
|
root = str;
|
|
first = FALSE;
|
|
}
|
|
|
|
if (objptr(str) == NULL)
|
|
{
|
|
TSubmenu* mnu = new TSubmenu(this, str);
|
|
mnu->read(scanner);
|
|
add(str, mnu);
|
|
}
|
|
else
|
|
break; // Menu gia' caricato!
|
|
}
|
|
|
|
return first == FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Menu
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
bool TMenu::read(const char* name)
|
|
{
|
|
TString root;
|
|
bool ok = read(name, root);
|
|
if (ok && _current == NULL)
|
|
{
|
|
_default_menu = root;
|
|
_current = find(root);
|
|
_item = 0;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TMenu::set_firm(long firm) const
|
|
{
|
|
if (firm <= 0)
|
|
{
|
|
TRelation rel(LF_NDITTE);
|
|
TCursor cur(&rel);
|
|
if (cur.items() == 1)
|
|
{
|
|
cur = 0L;
|
|
firm = rel.curr().get_long("CODDITTA");
|
|
if (!prefix().exist(firm))
|
|
firm = 0;
|
|
}
|
|
}
|
|
return main_app().set_firm(firm);
|
|
}
|
|
|
|
bool TMenu::jumpto(TSubmenu* next)
|
|
{
|
|
if (next && next->disabled())
|
|
next = NULL;
|
|
|
|
if (next)
|
|
{
|
|
if (next->query_firm())
|
|
{
|
|
#ifdef _DEMO_
|
|
if (!set_firm(1))
|
|
next = NULL;
|
|
#else
|
|
if (!set_firm(0))
|
|
next = NULL;
|
|
#endif
|
|
}
|
|
if (next)
|
|
{
|
|
if (_stack.count() >= 32)
|
|
_stack.destroy_base();
|
|
_stack.push(_current->name());
|
|
_current = next;
|
|
_item = 0;
|
|
}
|
|
}
|
|
|
|
return next != NULL;
|
|
}
|
|
|
|
bool TMenu::jumpto_root()
|
|
{
|
|
TSubmenu* sm = find(_default_menu);
|
|
return jumpto(sm);
|
|
}
|
|
|
|
TSubmenu& TMenu::pop()
|
|
{
|
|
TSubmenu* sm = _current;
|
|
if (!at_top())
|
|
{
|
|
TString& name = (TString&)_stack.pop();
|
|
sm = (TSubmenu*)objptr(name);
|
|
}
|
|
if (sm)
|
|
{
|
|
_current = sm;
|
|
_item = 0;
|
|
}
|
|
return *sm;
|
|
}
|
|
|
|
TSubmenu* TMenu::find_string(const TString& str)
|
|
{
|
|
TString upstr(str);
|
|
upstr.upper();
|
|
|
|
if (_last_search != upstr)
|
|
{
|
|
_last_search = upstr;
|
|
_ignore_list.destroy();
|
|
}
|
|
|
|
restart();
|
|
|
|
TSubmenu * sm;
|
|
|
|
for (sm = (TSubmenu*)get(); sm; sm = (TSubmenu*)get())
|
|
{
|
|
if (sm->enabled() && !_ignore_list.is_key(sm->name()))
|
|
{
|
|
const int item = sm->find_string(upstr);
|
|
if (item >= 0)
|
|
{
|
|
jumpto(sm);
|
|
_item = item;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sm != NULL)
|
|
_ignore_list.add(sm->name());
|
|
else
|
|
_ignore_list.destroy();
|
|
|
|
return sm;
|
|
}
|
|
|
|
TSubmenu* TMenu::find_parent(const TSubmenu& sub)
|
|
{
|
|
restart();
|
|
TSubmenu* sm;
|
|
for (sm = (TSubmenu*)get(); sm; sm = (TSubmenu*)get())
|
|
{
|
|
for (int i = sm->items()-1; i >= 0; i--)
|
|
{
|
|
const TMenuitem& mi = sm->item(i);
|
|
if (mi.is_submenu() && mi.action().find(sub.name()) >= 0)
|
|
break;
|
|
}
|
|
}
|
|
return sm;
|
|
}
|
|
|
|
bool TMenu::perform()
|
|
{
|
|
bool ok = _current != NULL;
|
|
if (ok)
|
|
ok = _current->perform(_item);
|
|
return ok;
|
|
}
|
|
|
|
//setta la trasparenza alle immagini con i 4 corner-pixel di colore uguale
|
|
bool TMenu::can_be_transparent(const TImage& i) const
|
|
{
|
|
const int w = i.width()-1;
|
|
const int h = i.height()-1;
|
|
const COLOR col = i.get_pixel(0,0);
|
|
if (i.get_pixel(w,0) != col)
|
|
return FALSE;
|
|
if (i.get_pixel(w,h) != col)
|
|
return FALSE;
|
|
if (i.get_pixel(0,h) != col)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
TImage& TMenu::image(const char* name)
|
|
{
|
|
TTimed_image* img = (TTimed_image*)_images.objptr(name);
|
|
if (img == NULL)
|
|
{
|
|
TFilename realname;
|
|
const char* ext[3] = { "jpg", "gif", "bmp" };
|
|
bool bFound = false;
|
|
for (int i = 0; i < 3 && !bFound; i++)
|
|
{
|
|
realname = name;
|
|
realname.ext(ext[i]);
|
|
bFound = realname.custom_path();
|
|
}
|
|
if (bFound)
|
|
{
|
|
if (_images.items() == 0)
|
|
_default_bmp = name; // Store default bitmap name
|
|
|
|
img = new TTimed_image(realname);
|
|
if (can_be_transparent(*img))
|
|
img->convert_transparent_color(MASK_BACK_COLOR);
|
|
_images.add(name, img);
|
|
}
|
|
else
|
|
{
|
|
img = (TTimed_image*)&image(_default_bmp);
|
|
if (img == NULL)
|
|
fatal_box(FR("Impossibile trovare l'immagine %s"), (const char*)_default_bmp);
|
|
}
|
|
|
|
if (_images.items() > 3)
|
|
{
|
|
TString worst_bmp;
|
|
clock_t worst_time = img->touch(); // Impedisco di cancellare la prossima
|
|
_images.restart();
|
|
for (THash_object* o = _images.get_hashobj(); o; o = _images.get_hashobj())
|
|
{
|
|
if (o->key() != _default_bmp)
|
|
{
|
|
TTimed_image& i = (TTimed_image&)o->obj();
|
|
if (i.last_time() < worst_time)
|
|
{
|
|
worst_time = i.last_time();
|
|
worst_bmp = o->key();
|
|
}
|
|
}
|
|
}
|
|
_images.remove(worst_bmp);
|
|
}
|
|
}
|
|
img->touch();
|
|
return *img;
|
|
}
|
|
|
|
void TMenu::reload_images()
|
|
{
|
|
_images.destroy();
|
|
}
|
|
|
|
bool TMenu::has_module(const char* mod)
|
|
{
|
|
TString16 key;
|
|
|
|
if (_modules.items() == 0)
|
|
{
|
|
TScanner scanner(AUT_FILE);
|
|
TString16 val;
|
|
for (int aut = 0; scanner.line() != ""; aut++)
|
|
{
|
|
key.strncpy(scanner.token(), 2);
|
|
key.lower();
|
|
val.format("%d", aut);
|
|
_modules.add(key, val);
|
|
}
|
|
}
|
|
|
|
key.strncpy(mod, 2);
|
|
key.lower();
|
|
|
|
int module = 0;
|
|
TString* cod = (TString*)_modules.objptr(key);
|
|
if (cod) module = atoi(*cod);
|
|
return main_app().has_module(module);
|
|
}
|
|
|
|
bool TMenu::is_dangerous(const char* mod)
|
|
{
|
|
TString code(mod);
|
|
code.cut(2);
|
|
return _dangerous.get_pos(code) >= 0;
|
|
}
|
|
|
|
TMenu::TMenu() : _current(NULL), _item(0)
|
|
{ }
|
|
|
|
TMenu::~TMenu()
|
|
{ }
|