campo-sirio/ba/ba0101.cpp
guy dddb1a668f Supporto base per tema METRO
git-svn-id: svn://10.65.10.50/branches/R_10_00@23185 c028cbd2-c16b-5b4b-a496-9718f37d4682
2016-04-15 08:12:39 +00:00

845 lines
18 KiB
C++
Executable File
Raw Blame History

#include <applicat.h>
#include <dongle.h>
#include <execp.h>
#include <mask.h>
#include <modaut.h>
#include <printer.h>
#include <relation.h>
#include <utility.h>
#include "ba0100a.h"
#include "ba0103.h"
#include "ba0100.h"
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
static bool _installing = false;
void set_installing_flag()
{ _installing = true; }
bool installing()
{ return _installing; }
///////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////
bool TMenuitem::_fullscreen_always;
TMenuitem::TMenuitem(TSubmenu* sm)
: _submenu(sm), _icon(0), _exist(-1), _enabled(-1),
_firm(false), _password(false), _reloadmenu(false), _fullscreen_43(false)
{ }
TMenuitem::TMenuitem(const TMenuitem& mi)
{
_submenu = mi._submenu;
_exist = mi._exist;
_firm = mi._firm;
_password = mi._password;
_reloadmenu = mi._reloadmenu;
_fullscreen_43 = mi._fullscreen_43;
_icon = mi._icon;
_enabled = mi._enabled;
_caption = mi._caption;
_action = mi._action;
_type = mi._type;
}
TMenu& TMenuitem::menu() const
{ return _submenu->menu(); }
bool 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;
case 'S': _fullscreen_43 = true; break;
default : break;
}
}
bool visible = true;
if (_type == '<')
{
const word mod = dongle().module_name2code(_action.left(2));
visible = dongle().shown(mod);
if (visible)
{
if (_action.find('.') < 0)
_action << ".men";
TFilename n = _action;
if (n.custom_path())
visible = menu().read(n, _action);
else
_action.cut(0);
_type = '[';
}
else
_action.cut(0);
}
if (!visible || _action.blank())
_exist = _enabled = false;
// Controlla lo stato di aggiornamento
//if (_enabled && is_program())
// _enabled = !menu().is_dangerous(_action) && !menu().is_vanished(_action);
return visible;
}
int TMenuitem::icon() const
{ return _icon; }
TSubmenu* TMenuitem::child_submenu() const
{
TSubmenu* sm = NULL;
if (is_submenu())
{
sm = menu().find(_action);
if (sm != NULL && sm->items() == 0)
sm = NULL;
}
return sm;
}
bool TMenuitem::enabled() const
{
if (_exist < 0)
{
bool yes = false;
if (is_submenu())
{
yes = child_submenu() != NULL;
}
else
{
// Controlla lo stato di aggiornamento
yes = !menu().is_dangerous(_action) && !menu().is_vanished(_action);
if (yes)
{
const int endname = _action.find(' ');
const TFilename name(endname > 0 ? _action.left(endname) : _action);
TFilename n = name;
if (!n.custom_path())
{
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;
}
bool yes = _exist != 0;
if (yes)
{
if (is_submenu())
{
const TSubmenu* mnu = child_submenu();
yes = mnu != NULL && mnu->enabled();
}
else
{
if (_enabled < 0)
{
const TExternal_app app(_action);
yes = app.can_run();
((TMenuitem*)this)->_enabled = yes;
}
yes = _enabled != 0;
}
}
return yes;
}
void TMenuitem::reset_permissions()
{
_enabled = -1;
}
bool TMenuitem::perform_submenu() const
{
TSubmenu* mnu = child_submenu();
bool ok = mnu != NULL && mnu->enabled();
if (ok)
ok = menu().jumpto(mnu);
return ok;
}
// Alcuni programmi devono essere eseguiti singolarmente: ba1, ba2, cg6
// oppure tutti quelli protetti da password di manutenzione come cg1 -1
bool TMenuitem::run_modal() const
{
bool yes = true;
if (submenu().menu().mask_mode() >= 3) // outlook mode
{
yes = _password || _action.match("ba[12] -*", true) || _action.starts_with("cg6", true);
}
return yes;
}
bool TMenuitem::run_fullscreen() const
{
bool yes = _fullscreen_always; // Always full screen
if (!yes && _fullscreen_43) // Full screen on 4/3 monitor
{
RCT rct; xvt_vobj_get_outer_rect(SCREEN_WIN, &rct);
const double ratio = double(rct.right) / double(rct.bottom);
yes = ratio < 1.4; // 4:3 = 1.333; 16:9 = 1.777; 16:10 = 1.600
}
return yes;
}
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);
TString80 pwd;
pwd << dongle().administrator() << (oggi.month() + oggi.day());
ok = pwd == mask.get(F_PASSWORD);
}
if (!ok)
return error_box("Password di servizio errata!\nAccesso negato.");
}
if (_firm && main_app().get_firm() <= 0)
ok = menu().set_firm(0);
if (ok)
{
TCurrency::force_cache_update(); // Chiude cache valute
TExternal_app a(_action);
if (!a.can_run())
{
((TMenuitem*)this)->_enabled = false; // Controllo sfuggito al caricamento del menu
return error_box(FR("L'utente %s non <20> abilitato all'uso del programma\n%s"),
(const char*)user(), (const char*)caption());
}
if (_action.starts_with("ba1 -6", true))
{
user() = dongle().administrator(); // Divento temporaneamente amministratore
a.run(true, 3); // e' una installazione -> applicazione in asincrono
set_installing_flag();
} else
if (_action.starts_with("ba7 -0", true))
{
xvt_sys_execute(_action, FALSE, FALSE);
return false; // Evita di creare un finestra ospite per il postino!
} else
if (_action.find("Teamviewer") >= 0)
{
xvt_sys_execute(_action, FALSE, TRUE);
return false; // Evita di creare un finestra ospite per la teleassistenza!
}
else
{
if (run_modal() || run_fullscreen())
{
prefix().set(NULL); // Chiude prefix
a.run(false, 1); // e' un programma sincrono
printer_destroy(); // Forza rilettura parametri della stampante
prefix().set("DEF"); // Riapre prefix
}
else
{
a.run(true, 1, false); // e' un programma asincrono
}
// incrementa conteggio utilizzo programmi
TToken_string cnt = ini_get_string(CONFIG_GUI, "Counters", _action);
cnt.add(cnt.get_int(0)+1, 0);
cnt.add(TDate(TODAY).date2ansi(), 1);
ini_set_string(CONFIG_GUI, "Counters", _action, cnt);
}
}
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),
_exist(true), _firm(false), _enabled(-1)
{ }
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.starts_with("Caption", true))
{
get_next_string(line, 8, _caption, brace);
_caption = dictionary_translate(_caption);
} else
if (line.starts_with("Module", true))
{
const int equal = line.find('=');
if (equal > 0)
{
TToken_string mod(line.after('='), ',');
mod.strip_spaces();
_modules = mod;
}
} else
if (line.starts_with("Picture", true))
{
// 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.starts_with("Flags", true))
{
TString16 flags;
get_next_string(line, 6, flags, brace);
if (flags.find('D') >= 0)
_exist = false;
if (flags.find('F') >= 0)
_firm = true;
} else
if (line.starts_with("Item", true))
{
TMenuitem* item = new TMenuitem(this);
if (item->create(line))
add(item);
else
delete item;
}
}
}
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::enabled() const
{
if (_enabled < 0)
{
bool yes = _exist != 0;
if (yes && _modules.full() && _modules != "0" && _modules != "ba")
{
yes = false;
bool is_good = false;
TToken_string& mod = (TToken_string&)_modules;
FOR_EACH_TOKEN(mod, cod)
{
is_good = _menu->has_module(cod);
if (is_good)
break;
}
if (is_good)
{
for (int i = items()-1; i >= 0 && !yes; i--)
{
const TMenuitem& mi = item(i);
yes = mi.enabled();
}
}
}
((TSubmenu*)this)->_enabled = yes;
}
return _enabled != 0;
}
void TSubmenu::reset_permissions()
{
if (_enabled >= 0)
{
_enabled = -1;
for (int i = items()-1; i >= 0; i--)
{
TMenuitem& mi = item(i);
mi.reset_permissions();
}
}
}
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 found = false;
TFilename menuname = name;
menuname.custom_path();
TScanner scanner(menuname);
while (scanner.ok())
{
const TString& line = found ? scanner.pop() : scanner.line();
if (line.empty())
break;
char brace = '[';
get_next_string(line, 0, str, brace);
if (!found)
{
root = str;
found = true;
}
if (objptr(str) == NULL)
{
TSubmenu* mnu = new TSubmenu(this, str);
mnu->read(scanner);
add(str, mnu);
}
else
break; // Menu gia' caricato!
}
return found;
}
///////////////////////////////////////////////////////////
// Menu
///////////////////////////////////////////////////////////
bool TMenu::read(const char* name)
{
Tdninst dninst;
dninst.find_killed(_vanished);
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
{
TApplication& a = main_app();
if (firm <= 0)
{
TPointer_array codes;
const int nditte = prefix().firms(codes);
if (codes.empty())
return error_box(TR("Non esistono ditte selezionabili"));
if (nditte == 1 || dongle().demo())
firm = codes.get_long(0);
else
{
if (!a.firm_change_enabled())
firm = a.get_firm();
}
}
return a.set_firm(firm);
}
bool TMenu::jumpto(TSubmenu* next)
{
if (next && next->disabled())
next = NULL;
if (next)
{
if (next->query_firm())
{
if (!set_firm(0))
next = NULL;
}
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.trim();
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 = NULL;
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;
}
TImage& TMenu::image(const char* name)
{
TTimed_image* img = (TTimed_image*)_images.objptr(name);
if (img == NULL)
{
TFilename realname;
const char* ext[] = { "png", "gif", "jpg", "bmp", NULL };
bool bFound = false;
for (int i = 0; ext[i] && !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();
// Reset permissions
restart();
for (TSubmenu* sm = (TSubmenu*)get(); sm; sm = (TSubmenu*)get())
sm->reset_permissions();
}
bool TMenu::has_module(const char* mod)
{
TDongle& donkey = dongle();
const word module = donkey.module_name2code(mod);
bool yes = module == BAAUT;
if (!yes && donkey.active(module))
yes = main_app().has_module(module) && !is_vanished(mod);
return yes;
}
bool TMenu::is_dangerous(const char* mod)
{
const char code[4] = { mod[0], mod[1], '\0', '\0' };
return _dangerous.get_pos(code) >= 0;
}
bool TMenu::is_vanished(const TString& app)
{
if (_vanished.empty() || app.starts_with("ba"))
return false;
if (_vanished.find('*') >= 0)
return true;
bool yes = _vanished.get_pos(app) >= 0;
if (!yes && app[0] != '7' && isdigit(app[0]))
{
TString4 mod; mod << app[0] << app[1];
const int cod = dongle().module_name2code(mod);
mod = dongle().module_code2name(cod);
yes = _vanished.get_pos(mod) >= 0;
}
return yes;
}
TMenu::TMenu() : _current(NULL), _item(0), _mask_mode(0)
{ }
TMenu::~TMenu()
{ }