#include #include #include #include #include #include #include #include #include #include "ba0100a.h" #include "ba0101.h" /////////////////////////////////////////////////////////// // 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; for (int 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), _exist(-1), _firm(FALSE), _password(FALSE), _reloadmenu(FALSE), _color(NORMAL_COLOR), _icon(0) { } 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; n.custom_path(); if (n.exist()) 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(' '); TFilename name(endname > 0 ? _action.left(endname) : _action); const char* ext[] = { "exe", "pif", "com", "bat", NULL }; for (int e = 0; ext[e]; e++) { name.ext(ext[e]); if (name.exist()) 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) == 0; 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 } 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), _enabled(TRUE), _firm(FALSE), _items(12) { } 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(); for (TSubmenu* 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(); for (TSubmenu* 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; } 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* image = (TTimed_image*)_images.objptr(name); if (image == NULL) { TFilename realname; const char* ext[3] = { "jpg", "gif", "bmp" }; for (int i = 0; i < 3; i++) { realname = name; realname << '.' << ext[i]; realname.custom_path(); if (realname.exist()) break; } if (realname.exist()) { if (_images.items() == 0) _default_bmp = name; // Store default bitmap name image = new TTimed_image(realname); if (can_be_transparent(*image)) image->convert_transparent_color(MASK_BACK_COLOR); _images.add(name, image); } else { image = (TTimed_image*)_images.objptr(_default_bmp); if (image == NULL) fatal_box(FR("Impossibile trovare l'immagine %s"), (const char*)_default_bmp); } if (_images.items() > 3) { TString worst_bmp; clock_t worst_time = image->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); } } image->touch(); return *image; } 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() { }