#include #include #include #include #include #include #include #include #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 è abilitato all'uso del programma\n%s"), (const char*)user(), (const char*)caption()); } const bool install_app = _action.starts_with("ba1 -6", true); if (install_app) { user() = dongle().administrator(); // Divento temporaneamente amministratore a.run(true, 3); // e' una installazione -> applicazione in asincrono set_installing_flag(); } else if (_action.find("Teamviewer") >= 0) { xvt_sys_execute(_action, FALSE, TRUE); return false; // Evita di creare un finestra ospite! } 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 } } } 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 { 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); } return main_app().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.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() { }