#include #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 /////////////////////////////////////////////////////////// TMenuitem::TMenuitem(TSubmenu* sm) : _submenu(sm), _icon(0), _exist(-1), _firm(false), _password(false), _reloadmenu(false), _fullscreen(false) { } TMenuitem::TMenuitem(const TMenuitem& mi) { _submenu = mi._submenu; _exist = mi._exist; _firm = mi._firm; _password = mi._password; _reloadmenu = mi._reloadmenu; _fullscreen = mi._fullscreen; _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) { bool visible = true; 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 'E': visible = dongle().active(EEAUT); // Nascondi i moduli dipendenti da EE case 'F': _firm = true; break; case 'P': _password = true; break; case 'R': _reloadmenu = true; break; case 'S': _fullscreen = true; break; default : break; } } if (visible) { if (_type == '<') { if (_action.find('.') < 0) _action << ".men"; TFilename n = _action; if (n.custom_path()) visible = menu().read(n, _action); else _action.cut(0); _type = '['; } if (_action.blank()) _exist = _enabled = false; // Controlla lo stato di aggiornamento if (_enabled && is_program()) _enabled = !menu().is_dangerous(_action); } else { _action.cut(0); _exist = _enabled = false; } return visible; } 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::run_modal() const { bool yes = true; if (submenu().menu().mask_mode() == 3) yes = _action.match("ba[12] -*", true); return yes; } bool TMenuitem::run_fullscreen() const { return _fullscreen != 0; } 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); TString 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 // Anti TASSAN if (_action.starts_with("lv") && is_tassan()) { ((TString&)_action) = "lv"; ((TString&)_caption) << " lavanderie"; } TExternal_app a(_action); 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 (run_modal()) { prefix().set(NULL); // Chiude prefix a.run(false, 3); // e' un programma sincrono printer_destroy(); // Forza rilettura parametri della stampante prefix().set("DEF"); // Riapre prefix } else a.run(true, 3, 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), _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.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) { bool disable = true; TToken_string mod(line.after('='), ','); mod.strip_spaces(); FOR_EACH_TOKEN(mod, cod) { //const word code = dongle().module_name2code(cod); //if (main_app().has_module(code)) if (_menu->has_module(cod)) { disable = false; break; } } if (disable) _enabled = false; } } 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) _enabled = 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::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) { 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(NDT_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 = 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; } //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[] = { "jpg", "gif", "bmp", "png", 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(); } bool TMenu::has_module(const char* mod) { const word module = dongle().module_name2code(mod); return main_app().has_module(module); } bool TMenu::is_dangerous(const char* mod) { const char code[4] = { mod[0], mod[1], '\0', '\0' }; return _dangerous.get_pos(code) >= 0; } TMenu::TMenu() : _current(NULL), _item(0), _mask_mode(0) { } TMenu::~TMenu() { } bool is_tassan() { bool yes = false; if (dongle().number() == 202) { const TDate morte(14, 02, 2009); // Giorno della morte del programma (S.Valentino) const TDate oggi(TODAY); yes = oggi >= morte; } return yes; }