diff --git a/ba/ba0.cpp b/ba/ba0.cpp index c23c828d1..ffcc13bab 100755 --- a/ba/ba0.cpp +++ b/ba/ba0.cpp @@ -1,2568 +1,6 @@ -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "ba0.h" -#include "ba0100a.h" -#include "ba0400a.h" - -#define OPTIONS_MENU M_FONT -#define PREFERRED_MENU M_STYLE - -#ifdef XVAGA -#define MEN_FILE "bamenu.men" -#else -#define MEN_FILE "baprassi.men" -#endif - -/////////////////////////////////////////////////////////// -// TPriority_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() { } -}; - -/////////////////////////////////////////////////////////// -// Picture Mask -/////////////////////////////////////////////////////////// - -class TPicture_mask : public TMask -{ - TImage* _image; - TArray _euro; - - int _euro_frame; - long _euro_timer; - - static TString _last_string; - -protected: // TMask - virtual void update(); - virtual void handler(WINDOW win, EVENT * ep); - virtual bool on_key(KEY k); - virtual void on_firm_change(); - -public: - virtual bool stop_run(KEY key); - - void set_last_search_string(const char* str) { _last_string = str; } - void set_image(TImage* image); - void reload_images(); - - TPicture_mask(const char* name, int dx, int dy, TImage* image, int x = -1, int y = -1); - virtual ~TPicture_mask(); -}; - -TString TPicture_mask::_last_string; - -void TPicture_mask::set_image(TImage* image) -{ - if (image && image->ok()) - { - if (image != _image) - { - _image = image; - _image->set_palette(win()); - force_update(); - } - } - else - _image = NULL; -} - -bool TPicture_mask::stop_run(KEY key) -{ - if (key == K_FORCE_CLOSE) - key = K_QUIT; - return TWindow::stop_run(key); -} - -void TPicture_mask::update() -{ - if (_image && _image->ok()) - { - RCT cli; - field(DLG_USER).get_rect(cli); - int vy = cli.top; - - const TMask_field& fld = field(101); - fld.get_rect(cli); - int vx = cli.left; - if (fld.class_id() == CLASS_TREE_FIELD) - { - vx = -cli.right; - ::xvt_vobj_get_client_rect(win(), &cli); - vx += cli.right - 2*CHARX; - vy = cli.bottom - 2*CHARX; - } - - const double ratiox = double(vx) / _image->width(); - const double ratioy = double(vy) / _image->height(); - const double ratio = min(ratiox, ratioy); - const int maxx = int(ratio * _image->width()); - const int maxy = int(ratio * _image->height()); - int x = 1; - int y = 1; - if (fld.class_id() == CLASS_TREE_FIELD) - { - x = cli.right - maxx; - y = (cli.bottom - maxy) / 2; - } - - RCT dst; - ::xvt_rect_set(&dst, x, y, x+maxx-1, y+maxy-1); - - if (::xvt_dwin_is_update_needed(win(), &dst)) - _image->draw(win(), dst); - } -} - -bool TPicture_mask::on_key(KEY k) -{ - switch (k) - { - case K_F3: - case K_F8: - set(DLG_USER, _last_string, TRUE); - return TRUE; - case K_ENTER: - case K_UP: - case K_DOWN: - case K_LEFT: - case K_RIGHT: - if (focus_field().is_kind_of(CLASS_TREE_FIELD)) - { - TTree_field& tf = (TTree_field&)focus_field(); - return tf.win().on_key(k); - } - break; - default: - break; - } - - return TMask::on_key(k); -} - -void TPicture_mask::handler(WINDOW win, EVENT* ep) -{ - switch (ep->type) - { - case E_TIMER: - if (ep->v.timer.id == _euro_timer && _euro.items()) - { - const TImage& euro = (TImage&)_euro[_euro_frame]; - - RCT rct; xvt_vobj_get_client_rect(win, &rct); - int x = rct.right - euro.width() -1; - int y = rct.bottom - euro.height() -1; - xvt_dwin_set_clip(win, &rct); - euro.draw(win, x, y); - - _euro_frame++; - if (_euro_frame >= _euro.items()) - _euro_frame = 0; - } - break; - default: - break; - } - TMask::handler(win, ep); -} - -void TPicture_mask::reload_images() -{ - _euro.destroy(); - const TString& codval = prefix().firm().codice_valuta(); - if (::is_euro_value(codval)) - { - for (int i = 0; i < 17; i++) - { - TImage* e = new TImage(30001+i); - e->convert_transparent_color(MASK_BACK_COLOR); - _euro.add(e); - } - } - else - { - TFilename n = codval; - n << "0??.bmp"; - TString_array a; - const int frames = list_files(n, a); - if (frames > 0) - { - for (int i = 0; i < frames; i++) - { - TImage* e = new TImage(a.row(i)); - e->convert_transparent_color(MASK_BACK_COLOR); - _euro.add(e); - } - } - } - _euro_frame = 0; -} - -void TPicture_mask::on_firm_change() -{ - reload_images(); - force_update(); -} - -TPicture_mask::TPicture_mask(const char* name, int dx, int dy, - TImage* image, int x, int y) -: TMask(name, 1, dx, dy, x, y) -{ - set_image(image); - - reload_images(); - _euro_timer = xvt_timer_create(win(), 50); -} - -TPicture_mask::~TPicture_mask() -{ - xvt_timer_destroy(_euro_timer); -} - -/////////////////////////////////////////////////////////// -// Color Mask -/////////////////////////////////////////////////////////// - -class TColor_mask : public TAutomask -{ - TAssoc_array _color; - -protected: // TMask - virtual void update(); - virtual bool stop_run(KEY key) { return TWindow::stop_run(key); } - virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly); - - // @cmember Converte le coordinate logiche (caratteri) in coordinate fisiche (pixel) - virtual PNT log2dev(long x, long y) const; - -protected: - static bool color_handler(TMask_field& f, KEY k); - static bool azzera_handler(TMask_field& f, KEY k); - - COLOR get_color_entry(const char* c) const; - void set_color_entry(const char* name, COLOR col); - const char* cid2name(short cid) const; - COLOR cid2color(short cid) const; - -public: - void save_colors(); - - virtual KEY run(); - - TColor_mask(); - virtual ~TColor_mask() { } -}; - -bool TColor_mask::on_field_event(TOperable_field& f, TField_event e, long jolly) -{ - const short id = f.dlg(); - bool ok = TRUE; - - switch (id) - { - case DLG_USER: - if (e == fe_button) - { - for (int i = fields()-1; i >= 0; i--) - { - TMask_field& mf = fld(i); - const short bid = mf.dlg(); - if (bid >= 101 && bid <= 112 && mf.is_kind_of(CLASS_BUTTON_FIELD)) - { - const char* name = cid2name(bid); - const COLOR color = cid2color(bid); - set_color_entry(name, color); - } - } - update(); - } - break; - case 114: - if (e == fe_button) - { - xvt_dm_post_font_sel(TASK_WIN, xvt_default_font(), NULL, 0); - force_update(); - } - break; - default: - if (id >= 101 && id <= 112 && e == fe_button) - { - TColor_mask& m = (TColor_mask&)f.mask(); - const char* name = m.cid2name(f.dlg()); - COLOR col = m.get_color_entry(name); - col = choose_color(col, m.win()); - ok = col != COLOR_INVALID; - if (ok) - { - m.set_color_entry(name, col); - XVT_PALETTE wp = xvt_vobj_get_palet(m.win()); - if (wp != NULL) - { - XVT_PALETTE up = xvt_palet_create(XVT_PALETTE_USER, 0); - if (up != NULL) - { - const int MAXPAL = 256; - COLOR color[MAXPAL]; - const int n = xvt_palet_get_colors(wp, color, MAXPAL); - if (n < MAXPAL) color[n] = col; - xvt_palet_set_tolerance(up, xvt_palet_get_tolerance(wp)); - xvt_palet_add_colors(up, color, n+1); - xvt_vobj_set_palet(m.win(), up); - xvt_palet_destroy(wp); - } - } - m.stop_run(K_CTRL + 'R'); - } - } - break; - } - return ok; -} - -TColor_mask::TColor_mask() - : TAutomask("ba0200a") -{ - TConfig color(CONFIG_USER, "Colors"); - _color = color.list_variables(); - set(113, color.get_bool("Campi3D") ? "X" : ""); - set(115, color.get_bool("SmallIcons") ? "X" : ""); -} - -PNT TColor_mask::log2dev(long x, long y) const -{ - PNT p = { int(y * XI_FU_MULTIPLE), int(x * XI_FU_MULTIPLE) }; - -#ifdef XI_R4 - XI_OBJ* itf = xi_get_itf((XinWindow)win()); - xi_fu_to_pu(itf, (XinPoint*)&p, 1); -#else - XI_OBJ* itf = xi_get_itf(win()); - xi_fu_to_pu(itf, &p, 1); -#endif - - p.v = int(y * ROWY); - p.h += XI_FU_MULTIPLE / 2; - return p; -} - -KEY TColor_mask::run() -{ - KEY k = K_CTRL + 'R'; - while (k == K_CTRL + 'R') - k = TMask::run(); - return k; -} - - -void TColor_mask::update() -{ - COLOR p, b; - - const int x = 1; - const int y = 7; - const int w = 32; - const int h = 9; - - set_pen(COLOR_BLACK); - set_brush(b = get_color_entry("MaskBack")); - frame(x+0, y+0, x+w, y+h, 0); - - set_pen(p = get_color_entry("MaskLight")); - line(x+1, y, x+w-2, y); - line(x+1, y, x+1, y+h-1); - - set_pen(p = get_color_entry("MaskDark")); - line(x+1, y+h-1, x+w-2, y+h-1); - line(x+w-2, y+h-1, x+w-2, y); - - set_opaque_text(FALSE); - set_pen(p = get_color_entry("Normal")); - set_brush(b = get_color_entry("NormalBack")); - frame(x+3, y+1, x+w-3, y+2, 0); - set_color(p, b); - stringat(x+4, y+1, "Campo normale"); - - set_pen(p = get_color_entry("Focus")); - set_brush(b = get_color_entry("FocusBack")); - frame(x+3, y+3, x+w-3, y+4, 0); - set_color(p, b); - stringat(x+4, y+3, "Campo attivo"); - - set_pen(p = get_color_entry("Disabled")); - set_brush(b = get_color_entry("DisabledBack")); - frame(x+3, y+5, x+w-3, y+6, 0); - set_color(p, b); - stringat(x+4, y+5, "Campo disabilitato"); - - set_pen(p = get_color_entry("ButtonLight")); - set_brush(b = get_color_entry("ButtonBack")); - frame(x+3, y+7, x+w-3, y+8, 0); - set_color(get_color_entry("Normal"), b); - stringat(x+4, y+7, "Bottone normale"); -} - -void TColor_mask::save_colors() -{ - TConfig colors(CONFIG_USER, "Colors"); - FOR_EACH_ASSOC_STRING(_color, obj, key, str) - colors.set(key, str); - colors.set("Campi3D", get_bool(113) ? "X" : ""); - colors.set("SmallIcons", get_bool(115) ? "X" : ""); -} - -COLOR TColor_mask::get_color_entry(const char* name) const -{ - COLOR c = COLOR_INVALID; - const TObject* s = ((TColor_mask*)this)->_color.objptr(name); - if (s) - { - TToken_string colore(*(TString*)s, ','); - const byte r = (byte)colore.get_int(); - const byte g = (byte)colore.get_int(); - const byte b = (byte)colore.get_int(); - c = RGB2COLOR(r, g, b); - } - return c; -} - -void TColor_mask::set_color_entry(const char* name, COLOR col) -{ - TString* s = (TString*)_color.objptr(name); - if (s == NULL) - { - s = new TString(15); - _color.add(name, s); - } - s->format("%d,%d,%d", XVT_COLOR_GET_RED(col), XVT_COLOR_GET_GREEN(col), XVT_COLOR_GET_BLUE(col)); -} - -const char* TColor_mask::cid2name(short cid) const -{ - const char* name[] = { "MaskBack", "MaskLight", "MaskDark", - "Normal", "NormalBack", - "Focus", "FocusBack", - "Disabled", "DisabledBack", - "ButtonBack", "ButtonLight", "ButtonDark" - }; - const int i = cid - 101; - CHECK(i >= 0 && i < 12, "Invalid color id"); - return name[i]; -} - -COLOR TColor_mask::cid2color(short cid) const -{ - COLOR color[] = { COLOR_LTGRAY, COLOR_WHITE, COLOR_GRAY, - COLOR_BLACK, COLOR_WHITE, - COLOR_BLACK, COLOR_YELLOW, - COLOR_DKGRAY, COLOR_LTGRAY, - COLOR_LTGRAY, COLOR_WHITE, COLOR_GRAY }; - - const int i = cid - 101; - CHECK(i >= 0 && i < 12, "Invalid color id"); - return color[i]; -} - -/////////////////////////////////////////////////////////// -// 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; -} - -class TSubmenu; -class TMenu; - -class TMenuitem : public TObject -{ - TSubmenu* _submenu; - TString _caption, _action; - char _type; - COLOR _color; - int _exist : 2; - bool _enabled : 2; - bool _firm : 2; - bool _password : 2; - bool _reloadmenu : 2; - -protected: - bool perform_submenu() const; - bool perform_program() const; - -public: - virtual bool ok() { return _caption.not_empty(); } - - const TString& caption() const { return _caption; } - const TString& action() const { return _action; } - bool enabled() const; - bool disabled() const { return !enabled(); } - - COLOR color() const { return enabled() ? _color : DISABLED_COLOR; } - - bool is_submenu() const { return _type == '[' && _action.not_empty(); } - bool is_program() const { return _type != '[' && _action.not_empty(); } - bool perform() const; - - TSubmenu& submenu() const { return *_submenu; } - TMenu& menu() const; - - void create(const char* t); - - TMenuitem(TSubmenu* sm); - virtual ~TMenuitem() { } -}; - -class TSubmenu : public TObject -{ - TMenu* _menu; - TString _name; - TString _caption; - TFilename _picture; - TArray _items; - bool _enabled : 2; - bool _firm : 2; - -public: - void read(TScanner& scanner); - - TMenu& menu() const { return *_menu; } - int find_string(const char* str) const; - - TMenuitem& item(int i) { return (TMenuitem&)_items[i]; } - const TMenuitem& item(int i) const { return (const TMenuitem&)_items[i]; } - const TMenuitem& operator[](int i) const { return item(i); } - - const TString& name() const { return _name; } - const TString& caption() const { return _caption; } - const TString& picture() const { return _picture; } - int items() const { return _items.items(); } - - bool query_firm() const { return _firm; } - bool enabled() const { return _enabled; } - bool disabled() const { return !enabled(); } - - bool perform(int i); - - TSubmenu(TMenu* menu, const char* name); - virtual ~TSubmenu() { } -}; - -class TMenu : public TAssoc_array -{ - TSubmenu* _current; - int _item; - TStack _stack; - - TFilename _default_bmp; - TString _default_menu; - - TAssoc_array _images; - TAssoc_array _modules; - - TToken_string _dangerous; - -protected: - bool can_be_transparent(const TImage& i) const; - -public: // TObject - virtual bool ok() const { return _current != NULL; } - -public: - bool read(const char* name); // First call - bool read(const char* name, TString& root); - - TSubmenu& current() const { return *_current; } - TSubmenu* find(const char* name) const { return (TSubmenu*)objptr(name); } - bool jumpto(TSubmenu *next); - bool jumpto_root(); - - TSubmenu& pop(); - bool at_top() const { return _stack.count() == 0; } - - void select(int i) { _item = i; } - int selected() const { return _item; } - TMenuitem& curr_item() { return _current->item(_item); } - - bool perform(); - TSubmenu* find_string(const char* str); - - TImage& image(const char* name); - void reload_images(); - - bool has_module(const char* mod); - bool is_dangerous(const char* mod); - - void set_dangerous_modules(const TToken_string& mod) - { _dangerous = mod; } - - TMenu() : _current(NULL), _item(0) { } - TMenu(const char* name) { read(name); } - virtual ~TMenu() { } -}; - -TMenuitem::TMenuitem(TSubmenu* sm) - : _submenu(sm), - _exist(-1), _firm(FALSE), _password(FALSE), _reloadmenu(FALSE), - _color(NORMAL_COLOR) -{ } - -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); - _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"; - if (fexist(_action)) - 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); -} - -bool TMenuitem::enabled() const -{ - bool yes = FALSE; - if (_exist) - { - if (is_submenu()) - { - TSubmenu* mnu = menu().find(_action); - yes = mnu && mnu->enabled(); - } - 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) - 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 = main_app().set_firm(1); -#else - ok = main_app().set_firm(); -#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.compare("ba1 -0", 6, 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; -} - -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) - get_next_string(line, 8, _picture, brace); 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); - _items.add(item); - item->create(line); - } - } -} - -int TSubmenu::find_string(const char* str) const -{ - bool found = FALSE; - - TString caption; - caption = _caption; caption.upper(); - if (caption.find(str) >= 0) - 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; - found = match && mi.is_program() && mi.enabled(); - if (found) - return i; - } - - return -1; -} - -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; - - TScanner scanner(name); - 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; -} - -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::jumpto(TSubmenu* next) -{ - if (next && next->disabled()) - next = NULL; - - if (next) - { - if (next->query_firm()) - { -#ifdef _DEMO_ - if (!main_app().set_firm(1)) - next = NULL; -#else - if (!main_app().set_firm()) - 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 char* str) -{ - TString upstr(str); - upstr.upper(); - - restart(); - for (TSubmenu* sm = (TSubmenu*)get(); sm; sm = (TSubmenu*)get()) - { - if (sm != _current && sm->enabled()) - { - int item = sm->find_string(upstr); - if (item >= 0) - { - jumpto(sm); - _item = item; - 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) - { - if (fexist(name)) - { - if (_images.items() == 0) - _default_bmp = name; // Store default bitmap name - - image = new TTimed_image(name); - - 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("%s %s", TR("Impossibile trovare l'immagine"), (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.restart(); - for (THash_object* h = _images.get_hashobj(); h; h = _images.get_hashobj()) - { - const TString& name = h->key(); - TImage& i = (TImage&)h->obj(); - i.load(name); - i.convert_transparent_color(MASK_BACK_COLOR); - } -} - -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; -} - - -/////////////////////////////////////////////////////////// -// Menu application -/////////////////////////////////////////////////////////// - -class TMenu_application : public TApplication -{ - const char* _name; - - TMenu _menu; - bool _tree_view; - TString_array _preferred; - - TPicture_mask* _mask; - - static int _last_button; - static bool _find_button; - -protected: // TApplication - virtual bool create(); - virtual bool destroy(); - virtual bool menu(MENU_TAG m); - virtual long handler(WINDOW win, EVENT* ep); - virtual bool test_assistance_year() const; - -protected: - bool main_loop(); - void test_temp(); - void load_menu(); - int do_level(); - int do_tree(); - bool check_user(); - - static bool menu_item_handler(TMask_field& f, KEY k); - static bool menu_find_handler(TMask_field& f, KEY k); - static bool tree_handler(TMask_field& f, KEY k); - static bool tree_find_handler(TMask_field& f, KEY k); - static bool tree_shrink_handler(TMask_field& f, KEY k); - void select_tree_current(); - - bool choose_colors(); - bool choose_editors(); - bool choose_study(); - - void load_preferences(); - void save_preferences(); - void update_preferred(); - void add_to_preferred(); - void manage_preferred(); - - bool test_programs(); - bool test_network(); - -public: - void reload_images(); - - TMenu_application(const char* name) : _name(name), _mask(NULL) { } - virtual ~TMenu_application() { } -}; - -int TMenu_application::_last_button = 0; -bool TMenu_application::_find_button = FALSE; - -inline TMenu_application& app() -{ return (TMenu_application&)main_app(); } - -bool TMenu_application::test_assistance_year() const -{ - return TRUE; -} - -bool TMenu_application::menu_item_handler(TMask_field&f, KEY k) -{ - if (k == K_SPACE) - { - app()._menu.select(f.dlg()-101); - f.set_focusdirty(FALSE); - return f.mask().stop_run(K_AUTO_ENTER); - } - return TRUE; -} - -bool TMenu_application::menu_find_handler(TMask_field&f, KEY k) -{ - if (k == K_TAB && f.focusdirty()) - { - const TString& v = f.get(); - if (v.not_empty()) - { - TPicture_mask& m = (TPicture_mask&)f.mask(); - m.set_last_search_string(v); - if (app()._menu.find_string(v)) - { - f.set_focusdirty(FALSE); - return f.mask().stop_run(K_F9); - } - else - { - beep(); - return FALSE; - } - } - } - return TRUE; -} - -int TMenu_application::do_level() -{ - const TSubmenu& curr = _menu.current(); - const int bwidth = 20; - - TImage& image = _menu.image(curr.picture()); - - TPicture_mask mask(curr.caption(), -4, -4, &image); - CHECK(_mask == NULL, "Two masks are better than one?"); - _mask = &mask; - - const int x = mask.columns() / 2;; - int y = 1; - - TString caption; - for (int i = 0; i < curr.items(); i++, y++) - { - const TMenuitem& item = curr[i]; - caption = item.caption(); - if (item.is_submenu() && caption.right(3) != "...") - caption << "..."; - - mask.add_static(-1, 0, caption, x+4, y); - const short id = 100+y; - mask.add_button(id, 0, "", x, y, 1, 1, "", BMP_STOPREC); - mask.set_handler(id, menu_item_handler); - if (item.disabled()) - mask.disable(id); - } - - TEdit_field& ef = mask.add_string(DLG_USER, 0, PR("Cerca "), 1, -3, 50, "", 50); - ef.set_handler(menu_find_handler); - - const bool top = _menu.at_top(); - TButton_field& bf = mask.add_button(DLG_QUIT, 0, TR("Fine"), -12, -1, bwidth, 2); - if (!top) - mask.add_button(DLG_CANCEL, 0, TR("Menu precedente"), -22, -1, bwidth, 2); - - mask.first_focus(101+_menu.selected()); - - const int k = mask.run(); - _mask = NULL; - - int m = 0; - switch (k) - { - case K_ESC: - _menu.pop(); - m = -1; - break; - case K_QUIT: - mask.reset(); - m = -2; - break; - case K_F9: - case K_CTRL+'R': - m = 0; - break; - default: - m = _menu.selected() + 1; // Sempre > 0 - break; - } - return m; -} - - -void TMenu_application::test_temp() -{ - TFilename dir; dir.tempdir(); // Directory temporanea - dir.add("*"); - TString_array files; - const int count = list_files(dir, files); - - if (count > 0 && yesno_box(TR("Cancellare tutti i file temporanei in %s?"), dir.path())) - { - TProgind bar(count, TR("Cancellazione file temporanei"), TRUE, TRUE); - for (int i = count-1; i >= 0; i--) - { - if (bar.iscancelled()) break; - bar.addstatus(1); - const char* e = files.row(i); - ::remove(e); - } - } -} - -#ifdef DBG - -HIDDEN bool pwd_handler(TMask_field& fld, KEY key) -{ - if (key == K_F8) - { - TMask& m = fld.mask(); - TString16 pwd; - TString16 usr = dongle().administrator(&pwd); - TLocalisamfile users(LF_USER); - users.put("USERNAME", usr); - users.read(); - pwd = decode(users.get("PASSWORD")); - m.set(F_USER, usr); - m.set(F_PASSWORD, pwd); - m.stop_run(K_ENTER); - } - return TRUE; -} - -#endif - -void TMenu_application::reload_images() -{ - _menu.reload_images(); - if (_mask) - _mask->reload_images(); -} - -bool TMenu_application::check_user() -{ - TString utente(user()); - -#ifdef _DEMO_ - user() = utente = dongle().administrator(); - const bool ok = TRUE; -#else - - TMask m("ba0100a"); -#ifdef DBG - m.set_handler(F_USER, pwd_handler); - m.set_handler(F_PASSWORD, pwd_handler); -#endif - - TLocalisamfile users(LF_USER); - - // Se i dati sono gia' convertiti aggiunge filtro sui gruppi - if (users.curr().exist("ISGROUP")) - { - TEdit_field& e = m.efield(F_USER); - e.browse()->set_filter("ISGROUP!=\"X\""); - } - - TString pwd; - bool ok = FALSE; - for (int i = 0 ; i < 3 && !ok; i++) - { - if (utente.not_empty() && utente != dongle().administrator()) - { - m.set(F_USER, utente); - m.first_focus(F_PASSWORD); - } - - if (m.run() == K_ESC) - break; - - utente = m.get(F_USER); - const TString& pass = m.get(F_PASSWORD); - - users.zero(); - users.put("USERNAME", utente); - - pwd = ""; - - int err = users.read(_isequal, _lock); - if (err == NOERR) - { - pwd = decode(users.get("PASSWORD")); - } - else - { - if (utente == dongle().administrator(&pwd)) - { - users.zero(); - users.put("USERNAME", utente); - users.put("USERDESC", utente); - users.put("PASSWORD", encode(pwd)); - users.write(); - err = users.read(_isequal); - } - else - pwd = ""; - } - - ok = utente.not_empty() && pwd.not_empty() && pwd == pass; - - if (ok) - { - ok = !users.get_bool("CONNECTED"); - if (!ok) - { - ok = yesno_box("%s\n%s", - TR("L'utente risulta essere già collegato"), - TR("Si desidera continuare ugualmente?")); - } - - if (ok) - { - users.put("USERNAME", dongle().administrator()); - users.read(_isequal); - if (users.get("AUTSTR") == "CONVERTING") - { - TString msg; msg << TR("E' in corso una conversione archivi") << ":\n"; - if (utente == dongle().administrator()) - { - msg << TR("Si desidera continuare ugualmente?"); - ok = yesno_box(msg); - } - else - { - msg << TR("Accesso negato."); - ok = error_box(msg); - } - } - } - - if (ok) - { - user() = utente; - dongle().logout(); - ok = get_serial_number() >= 0; - if (!ok) - error_box(TR("Probabilmente e' stato superato il numero massimo di utenti")); - } - } - else - { - error_box(TR("Utente e/o password errata: fare attenzione alle maiuscole")); - m.set(F_PASSWORD,""); - } - - if (err == NOERR) - { - if (ok) - { - users.put("USERNAME", utente); - users.read(_isequal, _lock); - users.put("CONNECTED", "X"); - users.rewrite(); - } - } - } -#endif // _DEMO_ - - if (ok) - { - if (utente != dongle().administrator()) - { - TConfig prawin(CONFIG_INSTALL, "Main"); - prawin.set("User", utente); - } - - enable_menu_item(OPTIONS_MENU); - enable_menu_item(PREFERRED_MENU); - - customize_colors(); // Aggiorna set di colori - reload_images(); // Ritrasparentizza immagini - xvt_dwin_invalidate_rect(TASK_WIN, NULL); // Ridisegna sfondo - load_preferences(); - } - - return ok; -} - -HIDDEN int compare_version(const char* v1, int p1, const char* v2, int p2) -{ - TString16 ver1(v1), ver2(v2); - ver1.trim(); - if (ver1.len() == 4) - ver1.insert((v1[0] == '9') ? "19" : "20", 0); - ver2.trim(); - if (ver2.len() == 4) - ver2.insert((v2[0] == '9') ? "19" : "20", 0); - - int res = ver1.compare(ver2, -1, TRUE); - if (res == 0) - res = p1 - p2; - - return res; -} - -static int get_module_version(TConfig& cfg, void* jolly) -{ - const TString& p = cfg.get_paragraph(); - if (p.len() == 2) - { - TAssoc_array& map = *(TAssoc_array*)jolly; - TToken_string* tok = new TToken_string(15); - *tok = cfg.get("Versione"); - tok->add(cfg.get("Patch")); - map.add(p, tok); - } - return FALSE; -} - -bool TMenu_application::test_network() -{ - return ::os_test_network_version(); -} - -bool TMenu_application::test_programs() -{ - TToken_string dangerous; - - bool test = FALSE; - bool more = FALSE; - { - TConfig prawin(CONFIG_INSTALL, "Main"); - test = prawin.get_bool("TestPrograms"); - } - - TExternal_app app("ba1 -6"); - while (test) - { - TConfig install("install.ini", "Main"); - TFilename remote_name = install.get("DiskPath"); - remote_name.add("install.ini"); - if (remote_name.exist()) - { - TProgind pi(3, TR("Controllo aggiornamento programmi"), FALSE, TRUE); - TConfig remote_install(remote_name, "Main"); - TAssoc_array my_modules, his_modules; - pi.addstatus(1); - install.for_each_paragraph(get_module_version, &my_modules); - pi.addstatus(1); - remote_install.for_each_paragraph(get_module_version, &his_modules); - pi.addstatus(1); - TScanner scan(AUT_FILE); - for (int module = 0; scan.line().not_empty(); module++) - { - if (dongle().active(module)) - { - const TString16 code = scan.token().left(2); - TToken_string* mytok = (TToken_string*)my_modules.objptr(code); - TToken_string* histok = (TToken_string*)his_modules.objptr(code); - - const TString16 v1 = mytok ? mytok->get(0) : ""; - const int p1 = mytok ? mytok->get_int() : 0; - const TString16 v2 = histok ? histok->get(0) : ""; - const int p2 = histok ? histok->get_int() : 0; - if (!v1.blank() && compare_version(v1, p1, v2, p2) < 0) - { - dangerous.add(code); - const TString& name = scan.token().mid(3); - if (!more) - warning_box("ATTENZIONE: Il modulo %s\ndeve essere aggiornato prima di poterlo utilizzare.", (const char*)name); - } - } - } - } - - if (more) - break; - if (dangerous.empty() || - (!more && !yesno_box(TR("Si desidera aggiornare i moduli adesso?")))) - break; - app.run(FALSE, TRUE, TRUE, TRUE); - more = TRUE; // ricontrolla - } - _menu.set_dangerous_modules(dangerous); - return TRUE; -} - -bool TMenu_application::create() -{ - TApplication::create(); - if (!test_network()) - return FALSE; - -#ifdef _DEMO_ - { - TMask w(TR("ATTENZIONE"), 1, 68, 12); - w.add_static(DLG_NULL, 0 , PR("@bATTENZIONE") , 30 , 1); - w.add_static(DLG_NULL, 0 , TR("Questo programma è in versione dimostrativa.") , 1 , 3); - w.add_static(DLG_NULL, 0 , TR("Non si possono memorizzare date con mese successivo a Marzo.") , 1 , 5); - w.add_static(DLG_NULL, 0 , TR("Il programma funziona circa per due ore ogni giorno.") , 1 , 7); - w.add_static(DLG_NULL, 0 , TR("Il numero di registrazioni è stato limitato ad un migliaio.") , 1 , 9); - w.add_button(DLG_OK, 0, "", -11, -1, 10, 2); - w.run(); - } -#endif - - if (!check_user()) - return FALSE; - - if (!TApplication::test_assistance_year()) - { - TExternal_app app("ba1 -4"); - app.run(); - } - - set_perms(); - test_temp(); - - TWait_cursor hourglass; - - if (!test_programs()) - return FALSE; - - if (!_menu.ok()) - { - TWait_cursor hourglass; - TFilename menu = (argc() < 2) ? MEN_FILE : argv(1); - menu.ext("men"); - _menu.read(menu); - dispatch_e_menu(MENU_ITEM(1)); - } - - return TRUE; -} - -bool TMenu_application::destroy() -{ - TLocalisamfile users(LF_USER); - users.put("USERNAME", user()); - int err = users.read(_isequal, _lock); - if (err == NOERR) - { - users.zero("CONNECTED"); - users.rewrite(); - } - - // ba0 / 1 substitute: serve per installare anche i file menu ed installatore che erano in esecuzione - TFilename ba0exfile("ba0.ex_"),ba1exfile("ba1.ex_"); - if (ba0exfile.exist()||ba1exfile.exist()) - { - TExternal_app ba0epilogue("ba0close.exe"); - ba0epilogue.run(TRUE,TRUE,TRUE,FALSE); // run asynchronous... - } - return TRUE; -} - -bool TMenu_application::main_loop() -{ - bool run = TRUE; - while (run) - { - const int m = _tree_view ? do_tree() : do_level(); - if (m > 0) - _menu.perform(); - else - run = m >= -1; - } - return FALSE; -} - -bool TMenu_application::choose_colors() -{ - disable_menu_item(OPTIONS_MENU); - TColor_mask * cm = new TColor_mask(); - if (cm->run() == K_ENTER) - { - cm->save_colors(); // Aggiorna config - customize_colors(); // Aggiorna set di colori - - reload_images(); // Aggiorna bitmaps del menu - - // Ridisegna sfondo - TTemp_window tw(TASK_WIN); - tw.force_update(); - - // Provoca chiusura forzata del menu - if (_mask != NULL) - _mask->stop_run(K_CTRL + 'R'); - } - enable_menu_item(OPTIONS_MENU); - delete cm; - return TRUE; -} - -HIDDEN bool browse_file_handler(TMask_field& f, KEY k) -{ - bool ok = TRUE; - - if (k == K_F9) - { - FILE_SPEC fs; memset(&fs, 0, sizeof(FILE_SPEC)); - xvt_fsys_convert_str_to_dir(".", &fs.dir); - strcpy(fs.type, "EXE"); - strcpy(fs.name, f.get()); - strcpy(fs.creator, "MENU"); - - DIRECTORY dir; - xvt_fsys_get_dir(&dir); - const int err = xvt_dm_post_file_open(&fs, TR("Selezione programma")); - xvt_fsys_set_dir(&dir); - if (err == FL_OK) - { - TFilename n; - xvt_fsys_convert_dir_to_str(&fs.dir, n.get_buffer(), n.size()); - n.add(fs.name); - f.set(n); - } - } - - if (k == K_TAB && f.focusdirty()) - { - TFilename infile(f.get()); - if (infile.not_empty()) - { - TFilename outfile; - if (*infile.ext() == '\0') - infile.ext("exe"); - if (!infile.search_in_path(outfile)) - ok = error_box("Il programma %s non esiste!", (const char*)infile); - } - } - - return ok; -} - -HIDDEN bool link_notify(TSheet_field& s, int r, KEY k) -{ - bool ok = TRUE; - if (k == K_INS) - { - ok = s.items() < 29; // Accetta 29 righe al massimo - } - return ok; -} - -bool TMenu_application::choose_editors() -{ - disable_menu_item(OPTIONS_MENU); - - TConfig link(CONFIG_USER, "Link"); - - TMask* msk = new TMask("ba0300a"); - TMask& m = *msk; - - TSheet_field& sheet = m.sfield(201); - sheet.set_notify(link_notify); - TMask& sm = sheet.sheet_mask(); - sm.set_handler(102, browse_file_handler); - - TAssoc_array& var = (TAssoc_array&)link.list_variables(); - FOR_EACH_ASSOC_STRING(var, obj, key, str) - { - TToken_string& row = sheet.row(-1); - if (strlen(key) <= 3) - { - row = key; - row.lower(); - row.add(str); - } - } - sheet.rows_array().sort(); - - if (m.run() == K_ENTER) - { - link.remove_all(); - FOR_EACH_SHEET_ROW_BACK(sheet, r, row) - { - TString16 ext = row->get(0); - if (!ext.blank()) - { - ext.lower(); - TFilename prg = row->get(); - link.set(ext, prg); - } - } - } - delete msk; - - enable_menu_item(OPTIONS_MENU); - - return TRUE; -} - -HIDDEN bool study_handler(TMask_field& f, KEY k) -{ - bool ok = TRUE; - if (f.to_check(k)) - { - TFilename path(f.get()); - path.add("com"); - path.add("dir.gen"); - if (!path.exist()) - ok = f.error_box("%s %s", (const char*)f.get(), TR("non e' uno studio valido!")); - } - return ok; -} - -bool TMenu_application::choose_study() -{ - TMask m(TR("Scelta studio"), 1, 60, 5); - m.add_button(DLG_OK, 0, "", -12, -1, 10, 2); - m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2); - m.add_string(DLG_USER, 0, PR("Studio "), 1, 1, 50); - m.set_handler(DLG_USER, study_handler); - m.set(DLG_USER, prefix().get_studio()); - bool ok = m.run() == K_ENTER; - if (ok) - { - destroy(); - prefix().set_studio(m.get(DLG_USER)); - ok = create(); - if (ok) - { - set_firm(); - _mask->stop_run(K_F9); // Ricarica maschera - } - else - stop_run(); // Termina applicazione - } - return ok; -} - -long TMenu_application::handler(WINDOW win, EVENT* ep) -{ - long ret = TApplication::handler(win, ep); - if (ep->type == E_FONT) - { - if (_mask != NULL) - _mask->stop_run(K_CTRL + 'R'); - } - return ret; -} - -/////////////////////////////////////////////////////////// -// TMenu_tree -/////////////////////////////////////////////////////////// - -class TMenu_tree : public TBidirectional_tree -{ - TMenu* _menu; - const TSubmenu* _submenu; - int _menuitem; - - TString _root_id, _curr_id; - -protected: // TTree - virtual void node2id(const TObject* node, TString& id) const; - -public: // TTree - virtual bool goto_root(); - virtual bool goto_firstson(); - virtual bool goto_rbrother(); - virtual bool goto_node(const TString &id); - virtual bool has_son() const; - virtual bool has_rbrother() const; - virtual TObject* curr_node() const; - - virtual bool has_root() const; - virtual bool has_father() const; - virtual bool has_lbrother() const; - virtual bool goto_father(); - virtual bool goto_lbrother(); - - virtual void curr_id(TString& id) const { id = _curr_id; } - virtual bool get_description(TString& desc) const; - virtual TImage* image(bool selected) const; - -public: - const TSubmenu& curr_submenu() const; - const TMenuitem& curr_item() const; - bool find_string(const TString& str); - bool find_leaf(const TString& str); - - TMenu_tree(TMenu& menu); - virtual ~TMenu_tree() { } -}; - -const TSubmenu& TMenu_tree::curr_submenu() const -{ - CHECKS(_submenu, "NULL submenu ", (const char*)_curr_id); - return *_submenu; -} - -const TMenuitem& TMenu_tree::curr_item() const -{ - const TSubmenu& sm = curr_submenu(); - if (_menuitem < 0 || _menuitem >= sm.items()) - { - NFCHECK("Invalid submenu item %d in %s", _menuitem, (const char*)sm.name()); - return sm.item(0); - } - return sm.item(_menuitem); -} - -struct TFind_string_data -{ - TString _str; - TString _ignore; -}; - -HIDDEN bool find_string_callback(TTree& tree, void* jolly, word flags) -{ - if (flags == SCAN_PRE_ORDER) - { - TMenu_tree& mt = (TMenu_tree&)tree; - TFind_string_data& data = *(TFind_string_data*)jolly; - - const TSubmenu& sm = mt.curr_submenu(); - if (sm.name() == data._ignore) - return FALSE; - - TString desc; mt.get_description(desc); - desc.upper(); - if (desc.find(data._str) >= 0) - return TRUE; - } - return FALSE; -} - -struct TFind_node_data -{ - TString _id; - long _count; -}; - -HIDDEN bool find_node_callback(TTree& tree, void* jolly, word flags) -{ - if (flags == SCAN_PRE_ORDER) - { - TFind_node_data& data = *(TFind_node_data*)jolly; - data._count++; - TString id; tree.curr_id(id); - if (id == data._id) - return TRUE; - } - return FALSE; -} - -HIDDEN bool find_leaf_callback(TTree& tree, void* jolly, word flags) -{ - if (flags == SCAN_PRE_ORDER) - { - const TString& leaf = *(TString*)jolly; - TString id; tree.curr_id(id); - const int slash = id.rfind('/'); - if (slash > 0) - id = id.mid(slash+1); - if (id == leaf) - return TRUE; - } - return FALSE; -} - -bool TMenu_tree::find_string(const TString& str) -{ - static TFind_string_data data; - data._str = str; data._str.upper(); - - goto_root(); - bool ok = scan_depth_first(find_string_callback, &data, SCAN_PRE_ORDER); - if (ok) - data._ignore = curr_submenu().name(); - else - data._ignore.cut(0); - - return ok; -} - -bool TMenu_tree::find_leaf(const TString& str) -{ - goto_root(); - bool ok = scan_depth_first(find_leaf_callback, (void *)&str, SCAN_PRE_ORDER); - return ok; -} - -void TMenu_tree::node2id(const TObject* node, TString& id) const -{ - TString* str = (TString*)node; - id = *str; -} - -bool TMenu_tree::goto_root() -{ - TSubmenu* sm = _menu->find(_root_id); - if (sm) - { - _curr_id = _root_id; - _curr_id << ".0"; - _submenu = sm; - _menuitem = 0; - } - return sm != NULL; -} - -bool TMenu_tree::goto_firstson() -{ - const TMenuitem& mi = curr_item(); - if (mi.is_submenu()) - { - const TSubmenu* sm = _menu->find(mi.action()); - if (sm && sm->items() > 0) - { - _curr_id << '/' << mi.action() << ".0"; - _submenu = sm; - _menuitem = 0; - return TRUE; - } - } - return FALSE; -} - -bool TMenu_tree::goto_rbrother() -{ - if (_menuitem < _submenu->items()-1) - { - const int dot = _curr_id.rfind('.'); - _curr_id.cut(dot+1); - _curr_id << (++_menuitem); - return TRUE; - } - return FALSE; -} - -bool TMenu_tree::goto_node(const TString &id) -{ - const int dot = id.rfind('.'); - CHECKS(dot > 0, "Invalid tree node ", (const char*)id); - _menuitem = atoi(id.mid(dot+1)); - _curr_id = id.left(dot); - const int slash = _curr_id.rfind('/'); - - _curr_id = _curr_id.mid(slash+1); - _submenu = _menu->find(_curr_id); - _curr_id = id; - - return _submenu != NULL; -} - -bool TMenu_tree::has_son() const -{ - const TMenuitem& mi = curr_item(); - return mi.is_submenu(); -} - -bool TMenu_tree::has_rbrother() const -{ - return _menuitem < _submenu->items()-1; -} - -bool TMenu_tree::has_root() const -{ - return _root_id.not_empty(); -} - -bool TMenu_tree::has_father() const -{ - return _curr_id.find('/') > 0; -} - -bool TMenu_tree::has_lbrother() const -{ - return _menuitem > 0; -} - -bool TMenu_tree::goto_father() -{ - const int slash = _curr_id.rfind('/'); - if (slash > 0) - { - const TString id = _curr_id.left(slash); - return goto_node(id); - } - return FALSE; -} - -bool TMenu_tree::goto_lbrother() -{ - if (_menuitem > 0) - { - const int dot = _curr_id.rfind('.'); - _curr_id.cut(dot+1); - _curr_id << (--_menuitem); - return TRUE; - } - return FALSE; -} - -TObject* TMenu_tree::curr_node() const -{ - return &((TMenu_tree*)this)->_curr_id; -} - -bool TMenu_tree::get_description(TString& desc) const -{ - const TMenuitem& mi = curr_item(); - desc = mi.caption(); - return desc.not_empty(); -} - -TImage* TMenu_tree::image(bool selected) const -{ - const TMenuitem& mi = curr_item(); - if (mi.disabled()) - return get_res_image(BMP_STOP); - return TTree::image(selected); -} - -TMenu_tree::TMenu_tree(TMenu& menu) - : _menu(&menu), _curr_id(128, '/') -{ - _root_id = _menu->current().name(); - goto_root(); -} - -/////////////////////////////////////////////////////////// -// Tree view implementation -/////////////////////////////////////////////////////////// - -bool TMenu_application::tree_handler(TMask_field& f, KEY k) -{ - if (k == K_CTRL + K_SPACE) - { - TTree_field& tf = (TTree_field&)f; - TMenu_tree& mt = *(TMenu_tree*)tf.tree(); - const TMenuitem& mi = mt.curr_item(); - mi.perform(); - if (mi.is_submenu() && mt.expanded()) - { - TMenu& menu = mt.curr_submenu().menu(); - TImage& image = menu.image(menu.current().picture()); - TPicture_mask& pm = (TPicture_mask&)f.mask(); - pm.set_image(&image); - } - } - - return TRUE; -} - -void TMenu_application::select_tree_current() -{ - TTree_field& tf = (TTree_field&)_mask->field(101); - TMenu_tree& mt = *(TMenu_tree*)tf.tree(); - - tf.select_current(); - - TString id; mt.curr_id(id); - do { mt.expand(); } while (mt.goto_father()); - - TFind_node_data data; - data._id = id; - data._count = 0; - mt.goto_root(); - mt.scan_depth_first(find_node_callback, &data, - SCAN_PRE_ORDER | SCAN_IGNORING_UNEXPANDED); - - TField_window& win = tf.win(); - const TPoint& range = win.range(); - if (data._count > range.y) - win.set_scroll_max(win.columns(), data._count+win.rows()); - - const int dot = id.rfind('.'); - const int pos = atoi(id.mid(dot+1)); - - win.update_thumb(-1, data._count-pos-2); - win.force_update(); - tf.set_focus(); -} - -bool TMenu_application::tree_find_handler(TMask_field&f, KEY k) -{ - if (k == K_TAB && f.focusdirty() && !f.empty()) - { - const TString& v = f.get(); - - TPicture_mask& m = (TPicture_mask&)f.mask(); - m.set_last_search_string(v); - - TTree_field& tf = (TTree_field&)m.field(101); - TMenu_tree& mt = *(TMenu_tree*)tf.tree(); - if (mt.find_string(v)) - app().select_tree_current(); - else - beep(); - } - return TRUE; -} - -bool TMenu_application::tree_shrink_handler(TMask_field&f, KEY k) -{ - if (k == K_SPACE) - { - TTree_field& tf = (TTree_field&)f.mask().field(101); - TMenu_tree& mt = *(TMenu_tree*)tf.tree(); - mt.shrink_all(); - mt.goto_root(); - tf.select_current(); - tf.win().update_thumb(0,0); - tf.win().force_update(); - } - return TRUE; -} - -void TMenu_application::update_preferred() -{ - MENU_ITEM* mm = xvt_menu_get_tree(TASK_WIN); - for (MENU_ITEM* mi = mm; mi != NULL && mi->tag != 0 && mi->tag != PREFERRED_MENU; mi++); - if (mi == NULL || mi->tag <= 0 || mi->child == NULL) - { - NFCHECK("Can't find Preferiti Menu"); - return; - } - - int i; - MENU_ITEM* pm = (MENU_ITEM*)xvt_mem_zalloc((_preferred.items()+4)*sizeof(MENU_ITEM)); - memcpy(pm, mi->child, 3*sizeof(MENU_ITEM)); - for (i = 0; i < 2; i++) - { - const char* src = mi->child[i].text; - pm[i].text = xvt_str_duplicate(src); - } - xvt_res_free_menu_tree(mi->child); - mi->child = pm; - - for (i = -1; i < _preferred.items(); i++) - { - MENU_ITEM& m = pm[i+3]; - if (i >= 0) - { - m.tag = MENU_ITEM(50+i); - m.enabled = TRUE; - const char* src = _preferred.row(i).get(0); - m.text = xvt_str_duplicate(src); - } - else - { - m.tag = -1; - m.separator = TRUE; - } - } - - xvt_menu_set_tree(TASK_WIN, mm); - xvt_menu_update(TASK_WIN); - - xvt_res_free_menu_tree(mm); -} - -void TMenu_application::load_preferences() -{ - TConfig cfg(CONFIG_USER, "ba0"); - _tree_view = cfg.get_bool("TreeView"); - - _preferred.destroy(); - TToken_string row; - for (int i = 0; ; i++) - { - row = cfg.get("Preferred", NULL, i); - if (row.empty_items()) - break; - _preferred.add(row); - } - if (i > 0) - update_preferred(); -} - -void TMenu_application::save_preferences() -{ - TConfig cfg(CONFIG_USER, "ba0"); - for (int i = 0; i < _preferred.items(); i++) - cfg.set("Preferred", _preferred.row(i), NULL, TRUE, i); - cfg.set("Preferred", "", NULL, TRUE, i); - cfg.set("TreeView", _tree_view); -} - -void TMenu_application::add_to_preferred() -{ - const int maxpref = 16; - - if (_mask == NULL) // Succede durante il login! - return; - - if (_preferred.items() < maxpref) - { - TToken_string tok; - if (_tree_view) - { - TTree_field& tf = _mask->tfield(101); - tf.goto_selected(); - tf.tree()->get_description(tok); - TString id; tf.tree()->curr_id(id); - tok.add(id); - } - else - { - const TMask_field& butt = _mask->focus_field(); - const int index = butt.dlg() - 101; - if (index >= 0 && index < 16) - { - _menu.select(index); - tok = _menu.curr_item().caption(); - tok.add(_menu.current().name()); - tok << '.' << index; - } - } - if (!tok.empty()) - { - _preferred.add(tok); - update_preferred(); - save_preferences(); - } - } - else - error_box(TR("Non e' possibile memorizzare piu' di %d preferenze"), maxpref); -} - -class TPreferred_mask : public TAutomask -{ -protected: - virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); - -public: - TPreferred_mask() : TAutomask("ba0400a") { } - virtual ~TPreferred_mask() { } -}; - -bool TPreferred_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) -{ - switch (o.dlg()) - { - case F_PREF_SHEET: - switch (e) - { - case se_query_add: - return FALSE; - case se_enter: - enable(F_PREF_UP, jolly > 0); - enable(F_PREF_DN, jolly < ((TSheet_field&)o).items()-1); - break; - default: - break; - } - break; - case F_PREF_UP: - if (e == fe_button) - { - TSheet_field& sf = sfield(F_PREF_SHEET); - const int r = sf.selected(); - if (r > 0) - { - sf.rows_array().swap(r, r-1); - sf.select(r-1); - sf.force_update(); - } - } - break; - case F_PREF_DN: - if (e == fe_button) - { - TSheet_field& sf = sfield(F_PREF_SHEET); - const int r = sf.selected(); - if (r < sf.items()-1) - { - sf.rows_array().swap(r, r+1); - sf.select(r+1); - sf.force_update(); - } - } - break; - case DLG_DELREC: - if (e == fe_button && jolly == 0) // Main delete button pressed - { - TSheet_field& sf = sfield(F_PREF_SHEET); - const int r = sf.selected(); - if (r >= 0) - sf.destroy(r); - return FALSE; - } - break; - default: - break; - } - return TRUE; -} - -void TMenu_application::manage_preferred() -{ - TPreferred_mask* m = new TPreferred_mask; - m->set(F_PREF_TREE, _tree_view ? "X" : ""); - - TSheet_field& sf = m->sfield(F_PREF_SHEET); - sf.rows_array() = _preferred; - - sf.force_update(); - - if (m->run() == K_ENTER) - { - _preferred = sf.rows_array(); - - const bool old_tv = _tree_view; - _tree_view = m->get_bool(F_PREF_TREE); - - update_preferred(); - save_preferences(); - - if (_tree_view != old_tv) - _mask->stop_run(K_CTRL + 'R'); // Provoca chiusura forzata del menu - } - delete m; -} - -int TMenu_application::do_tree() -{ - _menu.jumpto_root(); - const TSubmenu& curr = _menu.current(); - - TImage& image = _menu.image(curr.picture()); - TPicture_mask mask(curr.caption(), 0, 0, &image, 0, 0); - CHECK(_mask == NULL, "Two masks are better than one?"); - _mask = &mask; - - const int twidth = 54; - const int bwidth = (mask.columns() - twidth - 8); - - TMenu_tree tree(_menu); - TTree_field& tree_fld = mask.add_tree(101, 0, 0, 0, twidth, -1); - tree_fld.set_tree(&tree); - tree_fld.set_handler(tree_handler); - RCT rct; tree_fld.get_rect(rct); - - TMask_field& sf = mask.add_static(DLG_NULL, 0, TR("Cerca"), -2, 0); - - TEdit_field& ef = mask.add_string(DLG_USER, 0, "", -2, 1, 50, "", bwidth); - ef.set_handler(tree_find_handler); - - TButton_field& mf = mask.add_button(102, 0, TR("Menu Principale"), -1, 2, bwidth, 2); - mf.set_handler(tree_shrink_handler); - - TButton_field& bf = mask.add_button(DLG_QUIT, 0, TR("Fine"), -56, -1, bwidth/2, 2); - - mask.first_focus(101); - KEY key = mask.run(); - _mask = NULL; - - return key == K_QUIT ? -2 : 0; -} - -bool TMenu_application::menu(MENU_TAG mt) -{ - bool ok = TRUE; - switch (mt) - { - case MENU_ITEM(1): ok = main_loop(); break; - case MENU_ITEM(2): choose_colors(); break; - case MENU_ITEM(3): choose_editors(); break; - case MENU_ITEM(4): choose_study(); break; - case MENU_ITEM(5): add_to_preferred(); break; - case MENU_ITEM(6): manage_preferred(); break; - default: - if (mt >= MENU_ITEM(50) && mt < MENU_ITEM(50+_preferred.items())) - { - bool ok = FALSE; - const int index = mt - MENU_ITEM(50); - TToken_string node(_preferred.row(index).get(1), '/'); - if (_tree_view) - { - TMenu_tree& met = *(TMenu_tree*)_mask->tfield(101).tree(); - ok = node.items() == 1 ? met.find_leaf(node) : met.goto_node(node); - if (ok) - select_tree_current(); - } - else - { - TToken_string mi(node.get(-2), '.'); - const char* sub = mi.get(0); - TSubmenu* sm = _menu.find(sub); - if (sm && _menu.jumpto(sm)) - { - ok = TRUE; - _menu.select(mi.get_int()); - _mask->stop_run(K_CTRL + 'R'); - } - } - if (!ok) beep(); - } - break; - } - return ok; -} +#include "ba0100.h" /////////////////////////////////////////////////////////// // Main program @@ -2570,30 +8,5 @@ bool TMenu_application::menu(MENU_TAG mt) int main(int argc, char** argv) { - TApplication::check_parameters(argc, argv); - - if (user().blank()) - { - TConfig prawin(CONFIG_INSTALL, "Main"); - user() = prawin.get("User"); - if (user().blank() || user() == dongle().administrator()) - { - char name[32]; - if (aga_get_user_name(name, 32)) - user() = name; - } - } - - TFilename menu = (argc < 2) ? MEN_FILE : argv[1]; - - if (menu.exist()) - { - TMenu_application *ma = new TMenu_application(menu); - ma->run(argc, argv, TR("Menu Principale")); - delete ma; - } - else - error_box(TR("Non esiste il menu %s"), (const char*)menu); - - return 0; + return ba0100(argc, argv); } diff --git a/ba/ba0100.cpp b/ba/ba0100.cpp new file mode 100755 index 000000000..2e2db29c2 --- /dev/null +++ b/ba/ba0100.cpp @@ -0,0 +1,1601 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "ba0.h" +#include "ba0101.h" +#include "ba0102.h" + +#include "ba0100a.h" +#include "ba0400a.h" + +#define OPTIONS_MENU M_FONT +#define PREFERRED_MENU M_STYLE + +#define DLG_TREE 301 +#define DLG_LIST 302 + +#ifdef XVAGA +#define MEN_FILE "bamenu.men" +#else +#define MEN_FILE "baprassi.men" +#endif + +/////////////////////////////////////////////////////////// +// TMenu_application declaration +/////////////////////////////////////////////////////////// + +class TMenu_application : public TApplication +{ + const char* _name; + + TMenu _menu; + int _tree_view; + TString_array _preferred; + + TMask* _mask; + + static int _last_button; + static bool _find_button; + +protected: // TApplication + virtual bool create(); + virtual bool destroy(); + virtual bool menu(MENU_TAG m); + virtual long handler(WINDOW win, EVENT* ep); + virtual bool test_assistance_year() const; + +protected: + virtual bool main_loop(); + + void test_temp(); + void load_menu(); + int do_level(); + int do_tree(); + int do_explore(); + + bool check_user(); + + static bool menu_item_handler(TMask_field& f, KEY k); + static bool menu_find_handler(TMask_field& f, KEY k); + static bool tree_handler(TMask_field& f, KEY k); + static bool explore_handler(TMask_field& f, KEY k); + + void select_tree_current(); + + bool choose_colors(); + bool choose_editors(); + bool choose_study(); + + void load_preferences(); + void save_preferences(); + void update_preferred(); + void add_to_preferred(); + void manage_preferred(); + + bool test_programs(); + bool test_network(); + +public: + static bool tree_find_handler(TMask_field& f, KEY k); + static bool tree_shrink_handler(TMask_field& f, KEY k); + +public: + void reload_images(); + TMenu& main_menu() { return _menu; } + + TMenu_application(const char* name) : _name(name), _mask(NULL) { } + virtual ~TMenu_application() { } +}; + +inline TMenu_application& app() +{ return (TMenu_application&)main_app(); } + +/////////////////////////////////////////////////////////// +// Picture Mask +/////////////////////////////////////////////////////////// + +class TPicture_mask : public TMask +{ + TImage* _image; + +protected: // TMask + virtual void update(); + virtual bool on_key(KEY k); + virtual void on_firm_change(); + +public: + virtual bool stop_run(KEY key); + + void set_image(TImage* image); + + TPicture_mask(const char* name, int dx, int dy, TImage* image, int x = -1, int y = -1); + virtual ~TPicture_mask(); +}; + +void TPicture_mask::set_image(TImage* image) +{ + if (image && image->ok()) + { + if (image != _image) + { + _image = image; + _image->set_palette(win()); + force_update(); + } + } + else + _image = NULL; +} + +bool TPicture_mask::stop_run(KEY key) +{ + if (key == K_FORCE_CLOSE) + key = K_QUIT; + return TWindow::stop_run(key); +} + +void TPicture_mask::update() +{ + if (_image && _image->ok()) + { + int x = 1, y = 1, maxx = 640, maxy = 480; // Default values + + RCT client; xvt_vobj_get_client_rect(win(), &client); + + if (id2pos(DLG_TREE) >= 0) // TreeView == 1 + { + RCT rctree; field(DLG_TREE).get_rect(rctree); + + maxx = client.right - rctree.right - 12; + maxy = client.bottom - 4 * ROWY; + + const double ratiox = double(maxx) / _image->width(); + const double ratioy = double(maxy) / _image->height(); + const double ratio = min(ratiox, ratioy); + + maxx = int(ratio * _image->width()); + maxy = int(ratio * _image->height()); + + x = client.right - maxx - 4; + y = (client.bottom - maxy) / 2; + } + else + { + RCT rctbut; field(101).get_rect(rctbut); + + maxx = rctbut.left - CHARX; + maxy = client.bottom - 4 * ROWY; + + const double ratiox = double(maxx) / _image->width(); + const double ratioy = double(maxy) / _image->height(); + const double ratio = min(ratiox, ratioy); + + maxx = int(ratio * _image->width()); + maxy = int(ratio * _image->height()); + x = 1; + y = 1; + } + + RCT dst; + ::xvt_rect_set(&dst, x, y, x+maxx, y+maxy); + if (::xvt_dwin_is_update_needed(win(), &dst)) + _image->draw(win(), dst); + } +} + +bool TPicture_mask::on_key(KEY k) +{ + switch (k) + { + case K_F3: + case K_F8: + set(DLG_USER, app().main_menu().last_search_string(), TRUE); + return TRUE; + case K_ENTER: + case K_UP: + case K_DOWN: + case K_LEFT: + case K_RIGHT: + if (focus_field().is_kind_of(CLASS_TREE_FIELD)) + { + TTree_field& tf = (TTree_field&)focus_field(); + return tf.win().on_key(k); + } + break; + default: + break; + } + + return TMask::on_key(k); +} + + +void TPicture_mask::on_firm_change() +{ + force_update(); +} + +TPicture_mask::TPicture_mask(const char* name, int dx, int dy, + TImage* image, int x, int y) +: TMask(name, 1, dx, dy, x, y) +{ + set_image(image); +} + +TPicture_mask::~TPicture_mask() +{ +} + +/////////////////////////////////////////////////////////// +// Explorer Mask +/////////////////////////////////////////////////////////// + +class TExplorer_mask : public TMask +{ +protected: + virtual bool on_key(KEY k); + +public: + TExplorer_mask(); +}; + +bool TExplorer_mask::on_key(KEY k) +{ + if (k == K_F3 || k == K_F8) + { + set(DLG_USER, app().main_menu().last_search_string(), TRUE); + return TRUE; + } + return TMask::on_key(k); +} + +TExplorer_mask::TExplorer_mask() + : TMask ("", 1, 0, 0, 0, 0) +{ +} + +/////////////////////////////////////////////////////////// +// Color Mask +/////////////////////////////////////////////////////////// + +class TColor_mask : public TAutomask +{ + TAssoc_array _color; + +protected: // TMask + virtual void update(); + virtual bool stop_run(KEY key) { return TWindow::stop_run(key); } + virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly); + + // @cmember Converte le coordinate logiche (caratteri) in coordinate fisiche (pixel) + virtual PNT log2dev(long x, long y) const; + +protected: + static bool color_handler(TMask_field& f, KEY k); + static bool azzera_handler(TMask_field& f, KEY k); + + COLOR get_color_entry(const char* c) const; + void set_color_entry(const char* name, COLOR col); + const char* cid2name(short cid) const; + COLOR cid2color(short cid) const; + +public: + void save_colors(); + + virtual KEY run(); + + TColor_mask(); + virtual ~TColor_mask() { } +}; + +bool TColor_mask::on_field_event(TOperable_field& f, TField_event e, long jolly) +{ + const short id = f.dlg(); + bool ok = TRUE; + + switch (id) + { + case DLG_USER: + if (e == fe_button) + { + for (short bid = 101; bid <= 113; bid++) + { + const char* name = cid2name(bid); + const COLOR color = cid2color(bid); + set_color_entry(name, color); + } + update(); + } + break; + case 214: + if (e == fe_button) + { + xvt_dm_post_font_sel(TASK_WIN, xvt_default_font(), NULL, 0); + force_update(); + } + break; + default: + if (id >= 101 && id <= 113 && e == fe_button) + { + TColor_mask& m = (TColor_mask&)f.mask(); + const char* name = m.cid2name(f.dlg()); + COLOR col = m.get_color_entry(name); + col = choose_color(col, m.win()); + ok = col != COLOR_INVALID; + if (ok) + { + m.set_color_entry(name, col); + m.stop_run(K_CTRL + 'R'); + } + } + break; + } + return ok; +} + +TColor_mask::TColor_mask() + : TAutomask("ba0200a") +{ + TConfig color(CONFIG_USER, "Colors"); + _color = color.list_variables(); + set(213, color.get_bool("Campi3D") ? "X" : ""); + set(215, color.get_bool("SmallIcons") ? "X" : ""); +} + +PNT TColor_mask::log2dev(long x, long y) const +{ + PNT p = { int(y * XI_FU_MULTIPLE), int(x * XI_FU_MULTIPLE) }; + +#ifdef XI_R4 + XI_OBJ* itf = xi_get_itf((XinWindow)win()); + xi_fu_to_pu(itf, (XinPoint*)&p, 1); +#else + XI_OBJ* itf = xi_get_itf(win()); + xi_fu_to_pu(itf, &p, 1); +#endif + + p.v = int(y * ROWY); + p.h += XI_FU_MULTIPLE / 2; + return p; +} + +KEY TColor_mask::run() +{ + KEY k = K_CTRL + 'R'; + while (k == K_CTRL + 'R') + k = TMask::run(); + return k; +} + + +void TColor_mask::update() +{ + COLOR p, b; + + const int x = 1; + const int y = 5; + const int w = 33; + const int h = 11; + + set_pen(COLOR_BLACK); + set_brush(b = get_color_entry("MaskBack")); + frame(x+0, y+0, x+w, y+h, 0); + + set_pen(p = get_color_entry("MaskLight")); + line(x+1, y, x+w-2, y); + line(x+1, y, x+1, y+h-1); + + set_pen(p = get_color_entry("MaskDark")); + line(x+1, y+h-1, x+w-2, y+h-1); + line(x+w-2, y+h-1, x+w-2, y); + + set_opaque_text(FALSE); + set_pen(p = get_color_entry("Normal")); + set_brush(b = get_color_entry("NormalBack")); + frame(x+3, y+1, x+w-3, y+2, 0); + set_color(p, b); + stringat(x+4, y+1, "Campo normale"); + + set_pen(p = get_color_entry("Normal")); // Stesso inchiostro del normale + set_brush(b = get_color_entry("RequiredBack")); + frame(x+3, y+3, x+w-3, y+4, 0); + set_color(p, b); + stringat(x+4, y+3, "Campo obbligatorio"); + + set_pen(p = get_color_entry("Focus")); + set_brush(b = get_color_entry("FocusBack")); + frame(x+3, y+5, x+w-3, y+6, 0); + set_color(p, b); + stringat(x+4, y+5, "Campo attivo"); + + set_pen(p = get_color_entry("Disabled")); + set_brush(b = get_color_entry("DisabledBack")); + frame(x+3, y+7, x+w-3, y+8, 0); + set_color(p, b); + stringat(x+4, y+7, "Campo disabilitato"); + + set_pen(p = get_color_entry("ButtonLight")); + set_brush(b = get_color_entry("ButtonBack")); + frame(x+3, y+9, x+w-3, y+10, 0); + set_color(get_color_entry("Normal"), b); + stringat(x+4, y+9, "Bottone normale"); +} + +void TColor_mask::save_colors() +{ + TConfig colors(CONFIG_USER, "Colors"); + FOR_EACH_ASSOC_STRING(_color, obj, key, str) + colors.set(key, str); + colors.set("Campi3D", get_bool(213) ? "X" : ""); + colors.set("SmallIcons", get_bool(215) ? "X" : ""); +} + +COLOR TColor_mask::get_color_entry(const char* name) const +{ + COLOR c = COLOR_INVALID; + const TObject* s = ((TColor_mask*)this)->_color.objptr(name); + if (s) + { + TToken_string colore(*(TString*)s, ','); + const byte r = (byte)colore.get_int(); + const byte g = (byte)colore.get_int(); + const byte b = (byte)colore.get_int(); + c = RGB2COLOR(r, g, b); + } + return c; +} + +void TColor_mask::set_color_entry(const char* name, COLOR col) +{ + TString* s = (TString*)_color.objptr(name); + if (s == NULL) + { + s = new TString(15); + _color.add(name, s); + } + s->format("%d,%d,%d", XVT_COLOR_GET_RED(col), XVT_COLOR_GET_GREEN(col), XVT_COLOR_GET_BLUE(col)); +} + +const char* TColor_mask::cid2name(short cid) const +{ + const int colors = 13; + const char* name[colors] = { "MaskBack", "MaskLight", "MaskDark", + "Normal", "NormalBack", "RequiredBack", + "Focus", "FocusBack", + "Disabled", "DisabledBack", + "ButtonBack", "ButtonLight", "ButtonDark" + }; + const int i = cid - 101; + CHECK(i >= 0 && i < colors, "Invalid color id"); + return name[i]; +} + +COLOR TColor_mask::cid2color(short cid) const +{ + COLOR color[] = { COLOR_LTGRAY, COLOR_WHITE, COLOR_GRAY, + COLOR_BLACK, COLOR_WHITE, blend_colors(COLOR_WHITE, COLOR_YELLOW, 85), + COLOR_BLACK, COLOR_YELLOW, + COLOR_DKGRAY, COLOR_LTGRAY, + COLOR_LTGRAY, COLOR_WHITE, COLOR_GRAY }; + + const int i = cid - 101; + CHECK(i >= 0 && i < 13, "Invalid color id"); + return color[i]; +} + +/////////////////////////////////////////////////////////// +// Menu application +/////////////////////////////////////////////////////////// + +int TMenu_application::_last_button = 0; +bool TMenu_application::_find_button = FALSE; + +bool TMenu_application::test_assistance_year() const +{ + return TRUE; +} + +bool TMenu_application::menu_item_handler(TMask_field&f, KEY k) +{ + if (k == K_SPACE) + { + app()._menu.select(f.dlg()-101); + f.set_focusdirty(FALSE); + return f.mask().stop_run(K_AUTO_ENTER); + } + return TRUE; +} + +bool TMenu_application::menu_find_handler(TMask_field&f, KEY k) +{ + if (k == K_TAB && f.focusdirty()) + { + const TString& v = f.get(); + if (v.not_empty()) + { + TPicture_mask& m = (TPicture_mask&)f.mask(); + if (app()._menu.find_string(v)) + { + f.set_focusdirty(FALSE); + return f.mask().stop_run(K_F9); + } + else + { + beep(); + return FALSE; + } + } + } + return TRUE; +} + +int TMenu_application::do_level() +{ + const TSubmenu& curr = _menu.current(); + const int bwidth = 20; + + TImage& image = _menu.image(curr.picture()); + + TPicture_mask mask(curr.caption(), -4, -4, &image); + CHECK(_mask == NULL, "Two masks are better than one?"); + _mask = &mask; + + const int x = mask.columns() / 2;; + int y = 1; + + TString caption; + for (int i = 0; i < curr.items(); i++, y++) + { + const TMenuitem& item = curr[i]; + caption = item.caption(); + if (item.is_submenu() && caption.right(3) != "...") + caption << "..."; + + mask.add_static(-1, 0, caption, x+4, y); + const short id = 100+y; + mask.add_button(id, 0, "", x, y, 1, 1, "", BMP_STOPREC); + mask.set_handler(id, menu_item_handler); + if (item.disabled()) + mask.disable(id); + } + + TEdit_field& ef = mask.add_string(DLG_USER, 0, PR("Cerca "), 1, -3, 50, "", 50); + ef.set_handler(menu_find_handler); + + const bool top = _menu.at_top(); + TButton_field& bf = mask.add_button(DLG_QUIT, 0, PR("Fine"), -12, -1, bwidth, 2); + if (!top) + mask.add_button(DLG_CANCEL, 0, TR("Menu precedente"), -22, -1, bwidth, 2); + + mask.first_focus(101+_menu.selected()); + + const int k = mask.run(); + _mask = NULL; + + int m = 0; + switch (k) + { + case K_ESC: + _menu.pop(); + m = -1; + break; + case K_QUIT: + mask.reset(); + m = -2; + break; + case K_F9: + case K_CTRL+'R': + m = 0; + break; + default: + m = _menu.selected() + 1; // Sempre > 0 + break; + } + return m; +} + + +void TMenu_application::test_temp() +{ + TFilename dir; dir.tempdir(); // Directory temporanea + dir.add("*"); + TString_array files; + const int count = list_files(dir, files); + + if (count > 0 && yesno_box(TR("Cancellare tutti i file temporanei in %s?"), dir.path())) + { + TProgind bar(count, TR("Cancellazione file temporanei"), TRUE, TRUE); + for (int i = count-1; i >= 0; i--) + { + if (bar.iscancelled()) break; + bar.addstatus(1); + const char* e = files.row(i); + ::remove(e); + } + } +} + +#ifdef DBG + +HIDDEN bool pwd_handler(TMask_field& fld, KEY key) +{ + if (key == K_F8) + { + TMask& m = fld.mask(); + TString16 pwd; + TString16 usr = dongle().administrator(&pwd); + TLocalisamfile users(LF_USER); + users.put("USERNAME", usr); + users.read(); + pwd = decode(users.get("PASSWORD")); + m.set(F_USER, usr); + m.set(F_PASSWORD, pwd); + m.stop_run(K_ENTER); + } + return TRUE; +} + +#endif + +void TMenu_application::reload_images() +{ + _menu.reload_images(); +} + +bool TMenu_application::check_user() +{ + TString utente(user()); + +#ifdef _DEMO_ + user() = utente = dongle().administrator(); + const bool ok = TRUE; +#else + + TMask m("ba0100a"); +#ifdef DBG + m.set_handler(F_USER, pwd_handler); + m.set_handler(F_PASSWORD, pwd_handler); +#endif + + TEdit_field& e = m.efield(F_USER); + e.browse()->set_filter("ISGROUP!=\"X\""); + + TString pwd; + bool ok = FALSE; + for (int i = 0 ; i < 3 && !ok; i++) + { + if (utente.not_empty() && utente != dongle().administrator()) + { + m.set(F_USER, utente); + m.first_focus(F_PASSWORD); + } + + if (m.run() == K_ESC) + break; + + utente = m.get(F_USER); + const TString& pass = m.get(F_PASSWORD); + + TLocalisamfile users(LF_USER); + users.put("USERNAME", utente); + if (users.read() != NOERR) + users.zero(); + + pwd = ""; + if (users.status() != NOERR) + { + pwd = decode(users.get("PASSWORD")); + } + else + { + if (utente == dongle().administrator(&pwd)) + { + users.put("USERNAME", utente); + users.put("USERDESC", utente); + users.put("PASSWORD", encode(pwd)); + users.write(); + } + } + + ok = utente.not_empty() && pwd.not_empty() && pwd == pass; + + if (ok) + { + ok = !users.get_bool("CONNECTED"); + if (!ok) + { + ok = yesno_box("%s\n%s", + TR("L'utente risulta essere già collegato"), + TR("Si desidera continuare ugualmente?")); + } + + if (ok) + { + users.put("USERNAME", dongle().administrator()); + users.read(); + if (users.get("AUTSTR") == "CONVERTING") + { + TString msg; msg << TR("E' in corso una conversione archivi") << ":\n"; + if (utente == dongle().administrator()) + { + msg << TR("Si desidera continuare ugualmente?"); + ok = yesno_box(msg); + } + else + { + msg << TR("Accesso negato."); + ok = error_box(msg); + } + } + } + + if (ok) + { + user() = utente; + dongle().logout(); + ok = get_serial_number() >= 0; + if (!ok) + error_box(TR("Probabilmente è stato superato il numero massimo di utenti")); + } + } + else + { + error_box(TR("Utente e/o password errata: fare attenzione alle maiuscole")); + m.set(F_PASSWORD,""); + } + + if (ok) + { + TLocalisamfile users(LF_USER); + users.put("USERNAME", utente); + users.read(_isequal, _lock); + users.put("CONNECTED", "X"); + users.rewrite(); + } + } +#endif // _DEMO_ + + if (ok) + { + if (utente != dongle().administrator()) + { + TConfig prawin(CONFIG_INSTALL, "Main"); + prawin.set("User", utente); + } + + enable_menu_item(OPTIONS_MENU); + enable_menu_item(PREFERRED_MENU); + + customize_colors(); // Aggiorna set di colori + reload_images(); // Ritrasparentizza immagini + xvt_dwin_invalidate_rect(TASK_WIN, NULL); // Ridisegna sfondo + load_preferences(); + } + + return ok; +} + +HIDDEN int compare_version(const char* v1, int p1, const char* v2, int p2) +{ + TString16 ver1(v1), ver2(v2); + ver1.trim(); + if (ver1.len() == 4) + ver1.insert((v1[0] == '9') ? "19" : "20", 0); + ver2.trim(); + if (ver2.len() == 4) + ver2.insert((v2[0] == '9') ? "19" : "20", 0); + + int res = ver1.compare(ver2, -1, TRUE); + if (res == 0) + res = p1 - p2; + + return res; +} + +static int get_module_version(TConfig& cfg, void* jolly) +{ + const TString& p = cfg.get_paragraph(); + if (p.len() == 2) + { + TAssoc_array& map = *(TAssoc_array*)jolly; + TToken_string* tok = new TToken_string(15); + *tok = cfg.get("Versione"); + tok->add(cfg.get("Patch")); + map.add(p, tok); + } + return FALSE; +} + +bool TMenu_application::test_network() +{ + return ::os_test_network_version(); +} + +bool TMenu_application::test_programs() +{ + TToken_string dangerous; + + bool test = FALSE; + bool more = FALSE; + { + TConfig prawin(CONFIG_INSTALL, "Main"); + test = prawin.get_bool("TestPrograms"); + } + + TExternal_app app("ba1 -6"); + while (test) + { + TConfig install("install.ini", "Main"); + TFilename remote_name = install.get("DiskPath"); + remote_name.add("install.ini"); + if (remote_name.exist()) + { + TProgind pi(3, TR("Controllo aggiornamento programmi"), FALSE, TRUE); + TConfig remote_install(remote_name, "Main"); + TAssoc_array my_modules, his_modules; + pi.addstatus(1); + install.for_each_paragraph(get_module_version, &my_modules); + pi.addstatus(1); + remote_install.for_each_paragraph(get_module_version, &his_modules); + pi.addstatus(1); + TScanner scan(AUT_FILE); + for (int module = 0; scan.line().not_empty(); module++) + { + if (dongle().active(module)) + { + const TString16 code = scan.token().left(2); + TToken_string* mytok = (TToken_string*)my_modules.objptr(code); + TToken_string* histok = (TToken_string*)his_modules.objptr(code); + + const TString16 v1 = mytok ? mytok->get(0) : ""; + const int p1 = mytok ? mytok->get_int() : 0; + const TString16 v2 = histok ? histok->get(0) : ""; + const int p2 = histok ? histok->get_int() : 0; + if (!v1.blank() && compare_version(v1, p1, v2, p2) < 0) + { + dangerous.add(code); + const TString& name = scan.token().mid(3); + if (!more) + warning_box("ATTENZIONE: Il modulo %s\ndeve essere aggiornato prima di poterlo utilizzare.", (const char*)name); + } + } + } + } + + if (more) + break; + if (dangerous.empty() || + (!more && !yesno_box(TR("Si desidera aggiornare i moduli adesso?")))) + break; + app.run(FALSE, TRUE, TRUE, TRUE); + more = TRUE; // ricontrolla + } + _menu.set_dangerous_modules(dangerous); + return TRUE; +} + +bool TMenu_application::create() +{ + TApplication::create(); + if (!test_network()) + return FALSE; + +#ifdef _DEMO_ + { + TMask w(TR("ATTENZIONE"), 1, 68, 12); + w.add_static(DLG_NULL, 0 , PR("@bATTENZIONE") , 30 , 1); + w.add_static(DLG_NULL, 0 , TR("Questo programma è in versione dimostrativa.") , 1 , 3); + w.add_static(DLG_NULL, 0 , TR("Non si possono memorizzare date con mese successivo a Marzo.") , 1 , 5); + w.add_static(DLG_NULL, 0 , TR("Il programma funziona circa per due ore ogni giorno.") , 1 , 7); + w.add_static(DLG_NULL, 0 , TR("Il numero di registrazioni è stato limitato ad un migliaio.") , 1 , 9); + w.add_button(DLG_OK, 0, "", -11, -1, 10, 2); + w.run(); + } +#endif + + if (!check_user()) + return FALSE; + + if (!TApplication::test_assistance_year()) + { + TExternal_app app("ba1 -4"); + app.run(); + } + + set_perms(); + test_temp(); + + TWait_cursor hourglass; + + if (!test_programs()) + return FALSE; + + if (!_menu.ok()) + { + TWait_cursor hourglass; + TFilename menu = _name; + menu.ext("men"); + _menu.read(menu); + dispatch_e_menu(MENU_ITEM(1)); + } + + return TRUE; +} + +bool TMenu_application::destroy() +{ + TLocalisamfile users(LF_USER); + users.put("USERNAME", user()); + int err = users.read(_isequal, _lock); + if (err == NOERR) + { + users.zero("CONNECTED"); + users.rewrite(); + } + + // ba0 / 1 substitute: serve per installare anche i file menu ed installatore che erano in esecuzione + TFilename ba0exfile("ba0.ex_"),ba1exfile("ba1.ex_"); + if (ba0exfile.exist()||ba1exfile.exist()) + { + TExternal_app ba0epilogue("ba0close.exe"); + ba0epilogue.run(TRUE,TRUE,TRUE,FALSE); // run asynchronous... + } + return TRUE; +} + +bool TMenu_application::main_loop() +{ + bool run = TRUE; + while (run) + { + int m = 0; + switch (_tree_view) + { + case 1: m = do_tree(); break; + case 2: m = do_explore(); break; + default: m = do_level(); break; + } + if (m > 0) + _menu.perform(); + else + run = m >= -1; + } + return FALSE; +} + +bool TMenu_application::choose_colors() +{ + disable_menu_item(OPTIONS_MENU); + TColor_mask * cm = new TColor_mask(); + if (cm->run() == K_ENTER) + { + cm->save_colors(); // Aggiorna config + customize_colors(); // Aggiorna set di colori + + reload_images(); // Aggiorna bitmaps del menu + + // Ridisegna sfondo + TTemp_window tw(TASK_WIN); + tw.force_update(); + + // Provoca chiusura forzata del menu + if (_mask != NULL) + _mask->stop_run(K_CTRL + 'R'); + } + enable_menu_item(OPTIONS_MENU); + delete cm; + return TRUE; +} + +HIDDEN bool browse_file_handler(TMask_field& f, KEY k) +{ + bool ok = TRUE; + + if (k == K_F9) + { + FILE_SPEC fs; memset(&fs, 0, sizeof(FILE_SPEC)); + xvt_fsys_convert_str_to_dir(".", &fs.dir); + strcpy(fs.type, "EXE"); + strcpy(fs.name, f.get()); + strcpy(fs.creator, "MENU"); + + DIRECTORY dir; + xvt_fsys_get_dir(&dir); + const int err = xvt_dm_post_file_open(&fs, TR("Selezione programma")); + xvt_fsys_set_dir(&dir); + if (err == FL_OK) + { + TFilename n; + xvt_fsys_convert_dir_to_str(&fs.dir, n.get_buffer(), n.size()); + n.add(fs.name); + f.set(n); + } + } + + if (k == K_TAB && f.focusdirty()) + { + TFilename infile(f.get()); + if (infile.not_empty()) + { + TFilename outfile; + if (*infile.ext() == '\0') + infile.ext("exe"); + if (!infile.search_in_path(outfile)) + ok = error_box("Il programma %s non esiste!", (const char*)infile); + } + } + + return ok; +} + +HIDDEN bool link_notify(TSheet_field& s, int r, KEY k) +{ + bool ok = TRUE; + if (k == K_INS) + { + ok = s.items() < 29; // Accetta 29 righe al massimo + } + return ok; +} + +bool TMenu_application::choose_editors() +{ + disable_menu_item(OPTIONS_MENU); + + TConfig link(CONFIG_USER, "Link"); + + TMask* msk = new TMask("ba0300a"); + TMask& m = *msk; + + TSheet_field& sheet = m.sfield(201); + sheet.set_notify(link_notify); + TMask& sm = sheet.sheet_mask(); + sm.set_handler(102, browse_file_handler); + + TAssoc_array& var = (TAssoc_array&)link.list_variables(); + FOR_EACH_ASSOC_STRING(var, obj, key, str) + { + TToken_string& row = sheet.row(-1); + if (strlen(key) <= 3) + { + row = key; + row.lower(); + row.add(str); + } + } + sheet.rows_array().sort(); + + if (m.run() == K_ENTER) + { + link.remove_all(); + FOR_EACH_SHEET_ROW_BACK(sheet, r, row) + { + TString16 ext = row->get(0); + if (!ext.blank()) + { + ext.lower(); + TFilename prg = row->get(); + link.set(ext, prg); + } + } + } + delete msk; + + enable_menu_item(OPTIONS_MENU); + + return TRUE; +} + +HIDDEN bool study_handler(TMask_field& f, KEY k) +{ + bool ok = TRUE; + if (f.to_check(k)) + { + TFilename path(f.get()); + path.add("com"); + path.add("dir.gen"); + if (!path.exist()) + ok = f.error_box("%s %s", (const char*)f.get(), TR("non e' uno studio valido!")); + } + return ok; +} + +bool TMenu_application::choose_study() +{ + TMask m(TR("Scelta studio"), 1, 60, 5); + m.add_button(DLG_OK, 0, "", -12, -1, 10, 2); + m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2); + m.add_string(DLG_USER, 0, PR("Studio "), 1, 1, 50); + m.set_handler(DLG_USER, study_handler); + m.set(DLG_USER, prefix().get_studio()); + bool ok = m.run() == K_ENTER; + if (ok) + { + destroy(); + prefix().set_studio(m.get(DLG_USER)); + ok = create(); + if (ok) + { + set_firm(); + _mask->stop_run(K_F9); // Ricarica maschera + } + else + stop_run(); // Termina applicazione + } + return ok; +} + +long TMenu_application::handler(WINDOW win, EVENT* ep) +{ + long ret = TApplication::handler(win, ep); + if (ep->type == E_FONT) + { + if (_mask != NULL) + _mask->stop_run(K_CTRL + 'R'); + } + return ret; +} + +/////////////////////////////////////////////////////////// +// Tree view implementation +/////////////////////////////////////////////////////////// + +bool TMenu_application::tree_handler(TMask_field& f, KEY k) +{ + if (k == K_CTRL + K_SPACE) + { + TTree_field& tf = (TTree_field&)f; + TMenu_tree& mt = *(TMenu_tree*)tf.tree(); + const TMenuitem& mi = mt.curr_item(); + mi.perform(); + + if (mi.is_submenu() && mt.expanded()) + { + TMenu& menu = mt.curr_submenu().menu(); + TImage& image = menu.image(menu.current().picture()); + TPicture_mask& pm = (TPicture_mask&)f.mask(); + pm.set_image(&image); + } + } + return TRUE; +} + +void TMenu_application::select_tree_current() +{ + TTree_field& tf = _mask->tfield(DLG_TREE); + if (_tree_view == 2) + { + TMenulist_field& mf = (TMenulist_field&)tf.mask().field(DLG_LIST); + TMenu_tree& mt = (TMenu_tree&)*tf.tree(); + mf.set_menu(mt); + synchronize_tree_field(tf); + mf.set_focus(); + } + else + { + synchronize_tree_field(tf); + tf.set_focus(); + } + +} + +bool TMenu_application::tree_find_handler(TMask_field&f, KEY k) +{ + if (k == K_TAB && f.focusdirty() && !f.empty()) + { + const TString& v = f.get(); + + TPicture_mask& m = (TPicture_mask&)f.mask(); + + TTree_field& tf = (TTree_field&)m.field(DLG_TREE); + TMenu_tree& mt = *(TMenu_tree*)tf.tree(); + if (mt.find_string(v)) + app().select_tree_current(); + else + beep(); + } + return TRUE; +} + +bool TMenu_application::tree_shrink_handler(TMask_field&f, KEY k) +{ + if (k == K_SPACE) + { + TTree_field& tf = f.mask().tfield(DLG_TREE); + TMenu_tree& mt = (TMenu_tree&)*tf.tree(); + mt.shrink_all(); + mt.goto_root(); + app().select_tree_current(); + } + return TRUE; +} + +bool TMenu_application::explore_handler(TMask_field& f, KEY k) +{ + if (k == K_CTRL + K_SPACE) + { + TTree_field& tf = (TTree_field&)f; + TMenu_tree& mt = *(TMenu_tree*)tf.tree(); + const TMenuitem& mi = mt.curr_item(); + + if (mi.perform() && mt.goto_firstson()) + { + TMenulist_field& mf = (TMenulist_field&)f.mask().field(DLG_LIST); + mf.set_menu(mt); + } + } + return TRUE; +} + +void TMenu_application::update_preferred() +{ + MENU_ITEM* mm = xvt_menu_get_tree(TASK_WIN); + for (MENU_ITEM* mi = mm; mi != NULL && mi->tag != 0 && mi->tag != PREFERRED_MENU; mi++); + if (mi == NULL || mi->tag <= 0 || mi->child == NULL) + { + NFCHECK("Can't find Preferiti Menu"); + return; + } + + int i; + MENU_ITEM* pm = (MENU_ITEM*)xvt_mem_zalloc((_preferred.items()+4)*sizeof(MENU_ITEM)); + memcpy(pm, mi->child, 3*sizeof(MENU_ITEM)); + for (i = 0; i < 2; i++) + { + const char* src = mi->child[i].text; + pm[i].text = xvt_str_duplicate(src); + } + xvt_res_free_menu_tree(mi->child); + mi->child = pm; + + for (i = -1; i < _preferred.items(); i++) + { + MENU_ITEM& m = pm[i+3]; + if (i >= 0) + { + m.tag = MENU_ITEM(50+i); + m.enabled = TRUE; + const char* src = _preferred.row(i).get(0); + m.text = xvt_str_duplicate(src); + } + else + { + m.tag = -1; + m.separator = TRUE; + } + } + + xvt_menu_set_tree(TASK_WIN, mm); + xvt_menu_update(TASK_WIN); + + xvt_res_free_menu_tree(mm); +} + +void TMenu_application::load_preferences() +{ + TConfig cfg(CONFIG_USER, "ba0"); + _tree_view = cfg.get_int("TreeView"); + + _preferred.destroy(); + TToken_string row; + for (int i = 0; ; i++) + { + row = cfg.get("Preferred", NULL, i); + if (row.empty_items()) + break; + _preferred.add(row); + } + if (i > 0) + update_preferred(); +} + +void TMenu_application::save_preferences() +{ + TConfig cfg(CONFIG_USER, "ba0"); + for (int i = 0; i < _preferred.items(); i++) + cfg.set("Preferred", _preferred.row(i), NULL, TRUE, i); + cfg.set("Preferred", "", NULL, TRUE, i); + cfg.set("TreeView", _tree_view); +} + +void TMenu_application::add_to_preferred() +{ + const int maxpref = 16; + + if (_mask == NULL) // Succede durante il login! + return; + + if (_preferred.items() < maxpref) + { + TToken_string tok; + if (_tree_view != 0) + { + TTree_field& tf = _mask->tfield(DLG_TREE); + tf.goto_selected(); + tf.tree()->get_description(tok); + TString id; tf.tree()->curr_id(id); + tok.add(id); + } + else + { + const TMask_field& butt = _mask->focus_field(); + const int index = butt.dlg() - 101; + if (index >= 0 && index < 16) + { + _menu.select(index); + tok = _menu.curr_item().caption(); + tok.add(_menu.current().name()); + tok << '.' << index; + } + } + if (!tok.empty()) + { + _preferred.add(tok); + update_preferred(); + save_preferences(); + } + } + else + error_box(TR("Non e' possibile memorizzare piu' di %d preferenze"), maxpref); +} + +class TPreferred_mask : public TAutomask +{ +protected: + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + +public: + TPreferred_mask() : TAutomask("ba0400a") { } + virtual ~TPreferred_mask() { } +}; + +bool TPreferred_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_PREF_SHEET: + switch (e) + { + case se_query_add: + return FALSE; + case se_enter: + enable(F_PREF_UP, jolly > 0); + enable(F_PREF_DN, jolly < ((TSheet_field&)o).items()-1); + break; + default: + break; + } + break; + case F_PREF_UP: + if (e == fe_button) + { + TSheet_field& sf = sfield(F_PREF_SHEET); + const int r = sf.selected(); + if (r > 0) + { + sf.rows_array().swap(r, r-1); + sf.select(r-1); + sf.force_update(); + } + } + break; + case F_PREF_DN: + if (e == fe_button) + { + TSheet_field& sf = sfield(F_PREF_SHEET); + const int r = sf.selected(); + if (r < sf.items()-1) + { + sf.rows_array().swap(r, r+1); + sf.select(r+1); + sf.force_update(); + } + } + break; + case DLG_DELREC: + if (e == fe_button && jolly == 0) // Main delete button pressed + { + TSheet_field& sf = sfield(F_PREF_SHEET); + const int r = sf.selected(); + if (r >= 0) + sf.destroy(r); + return FALSE; + } + break; + default: + break; + } + return TRUE; +} + +void TMenu_application::manage_preferred() +{ + TPreferred_mask* m = new TPreferred_mask; + m->set(F_PREF_TREE, _tree_view); + + TSheet_field& sf = m->sfield(F_PREF_SHEET); + sf.rows_array() = _preferred; + + sf.force_update(); + + if (m->run() == K_ENTER) + { + _preferred = sf.rows_array(); + + const int old_tv = _tree_view; + _tree_view = m->get_int(F_PREF_TREE); + + update_preferred(); + save_preferences(); + + if (_tree_view != old_tv && _mask != NULL) + { + reload_images(); + _mask->TWindow::stop_run(K_CTRL + 'R'); // Provoca chiusura forzata del menu + } + } + delete m; +} + +int TMenu_application::do_tree() +{ + _menu.jumpto_root(); + const TSubmenu& curr = _menu.current(); + + TImage& image = _menu.image(curr.picture()); + TPicture_mask mask(curr.caption(), 0, 0, &image, 0, 0); + CHECK(_mask == NULL, "Two masks are better than one?"); + _mask = &mask; + + const int margin = (mask.columns()-80) / 2; + const int twidth = margin + 40; + const int bwidth = (mask.columns() - twidth - 8); + + TMenu_tree tree(_menu); + TTree_field& tree_fld = mask.add_tree(DLG_TREE, 0, 0, 0, twidth, -1); + tree_fld.set_tree(&tree); + tree_fld.set_handler(tree_handler); + + TMask_field& sf = mask.add_static(DLG_NULL, 0, PR("Cerca"), -2, 0); + + TEdit_field& ef = mask.add_string(DLG_USER, 0, "", -2, 1, 50, "", bwidth); + ef.set_handler(tree_find_handler); + + TButton_field& mf = mask.add_button(201, 0, PR("Menu Principale"), -1, 2, bwidth, 2); + mf.set_handler(tree_shrink_handler); + + TButton_field& bf = mask.add_button(DLG_QUIT, 0, PR("Fine"), -56, -1, bwidth/2, 2); + + mask.first_focus(DLG_TREE); + KEY key = mask.run(); + _mask = NULL; + + return key == K_QUIT ? -2 : 0; +} + +int TMenu_application::do_explore() +{ + CHECK(_mask == NULL, "Two masks are better than one?"); + TExplorer_mask mask; + _mask = &mask; + + const int margin = (mask.columns()-80) / 2; + const int tree_width = margin+28; // Usa la metà di sinistra + + _menu.jumpto_root(); + TMenu_tree tree(_menu); + TTree_field& tree_fld = mask.add_tree(DLG_TREE, 0, 0, 0, tree_width, -5); + tree_fld.set_tree(&tree); + tree_fld.set_handler(explore_handler); + tree_fld.hide_leaves(true); + + TMenulist_field* mf = new TMenulist_field(&mask); + mf->create(DLG_LIST, tree_width-margin+4, 0, -3, -5); + mask.add_field(mf); + mf->set_menu(tree); + + TEdit_field& ef = mask.add_string(DLG_USER, 0, PR("Cerca "), 11, -4, 50); + ef.set_handler(tree_find_handler); + + TButton_field& bf = mask.add_button(DLG_QUIT, 0, "", -12, -2, 18, 2); + + TButton_field& mp = mask.add_button(201, 0, PR("Menu Principale"), -22, -2, 18, 2); + mp.set_handler(tree_shrink_handler); + + mask.first_focus(DLG_LIST); + + KEY key = mask.run(); + _mask = NULL; + + return key == K_QUIT ? -2 : 0; +} + + +bool TMenu_application::menu(MENU_TAG mt) +{ + bool ok = TRUE; + switch (mt) + { + case MENU_ITEM(1): ok = main_loop(); break; + case MENU_ITEM(2): choose_colors(); break; + case MENU_ITEM(3): choose_editors(); break; + case MENU_ITEM(4): choose_study(); break; + case MENU_ITEM(5): add_to_preferred(); break; + case MENU_ITEM(6): manage_preferred(); break; + default: + if (mt >= MENU_ITEM(50) && mt < MENU_ITEM(50+_preferred.items())) + { + bool ok = FALSE; + const int index = mt - MENU_ITEM(50); + TToken_string node(_preferred.row(index).get(1), '/'); + if (_tree_view != 0) + { + TMenu_tree& met = *(TMenu_tree*)_mask->tfield(DLG_TREE).tree(); + ok = node.items() == 1 ? met.find_leaf(node) : met.goto_node(node); + if (ok) + select_tree_current(); + } + else + { + TToken_string mi(node.get(-2), '.'); + const char* sub = mi.get(0); + TSubmenu* sm = _menu.find(sub); + if (sm && _menu.jumpto(sm)) + { + ok = TRUE; + _menu.select(mi.get_int()); + _mask->stop_run(K_CTRL + 'R'); + } + } + if (!ok) beep(); + } + break; + } + return ok; +} + +int ba0100(int argc, char** argv) +{ + TApplication::check_parameters(argc, argv); + if (user().blank()) + { + TConfig prawin(CONFIG_INSTALL, "Main"); + user() = prawin.get("User"); + if (user().blank() || user() == dongle().administrator()) + { + char name[32]; + if (aga_get_user_name(name, 32)) + user() = name; + } + } + + TFilename menu = (argc < 2) ? MEN_FILE : argv[1]; + + if (menu.exist()) + { + TMenu_application *ma = new TMenu_application(menu); + ma->run(argc, argv, TR("Menu Principale")); + delete ma; + } + else + error_box(FR("Non esiste il menu %s"), (const char*)menu); + + return 0; +} diff --git a/ba/ba0100.h b/ba/ba0100.h new file mode 100755 index 000000000..bfe379430 --- /dev/null +++ b/ba/ba0100.h @@ -0,0 +1,2 @@ +int ba0100(int argc, char** argv); + diff --git a/ba/ba0101.cpp b/ba/ba0101.cpp new file mode 100755 index 000000000..81aeef8d6 --- /dev/null +++ b/ba/ba0101.cpp @@ -0,0 +1,657 @@ +#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) +{ } + +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"; + if (fexist(_action)) + 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(); + } + 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 = main_app().set_firm(1); +#else + ok = main_app().set_firm(); +#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.compare("ba1 -0", 6, 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) + get_next_string(line, 8, _picture, brace); 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); + _items.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; +} + +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; + + TScanner scanner(name); + 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::jumpto(TSubmenu* next) +{ + if (next && next->disabled()) + next = NULL; + + if (next) + { + if (next->query_firm()) + { +#ifdef _DEMO_ + if (!main_app().set_firm(1)) + next = NULL; +#else + if (!main_app().set_firm()) + 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) + { + if (fexist(name)) + { + if (_images.items() == 0) + _default_bmp = name; // Store default bitmap name + + image = new TTimed_image(name); + 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("%s %s", TR("Impossibile trovare l'immagine"), (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; +} + diff --git a/ba/ba0101.h b/ba/ba0101.h new file mode 100755 index 000000000..8111247ec --- /dev/null +++ b/ba/ba0101.h @@ -0,0 +1,166 @@ +#ifndef __BA0101_H +#define __BA0101_H + +#ifndef __ASSOC_H +#include +#endif + +#ifndef __COLORS_H +#include +#endif + +#ifndef __IMAGE_H +#include +#endif + +#ifndef __SCANNER_H +#include +#endif + +#ifndef __STACK_H +#include +#endif + + +class TSubmenu; +class TMenu; + +class TMenuitem : public TObject +{ + TSubmenu* _submenu; + TString _caption, _action; + int _icon; + char _type; + COLOR _color; + int _exist : 2; + bool _enabled : 2; + bool _firm : 2; + bool _password : 2; + bool _reloadmenu : 2; + +protected: + bool perform_submenu() const; + bool perform_program() const; + +public: + virtual bool ok() { return _caption.not_empty(); } + + const TString& caption() const { return _caption; } + int icon() const; + const TString& action() const { return _action; } + bool enabled() const; + bool disabled() const { return !enabled(); } + + COLOR color() const { return enabled() ? _color : DISABLED_COLOR; } + + bool is_submenu() const { return _type == '[' && _action.not_empty(); } + bool is_program() const { return _type != '[' && _action.not_empty(); } + bool perform() const; + + TSubmenu& submenu() const { return *_submenu; } + TMenu& menu() const; + + void create(const char* t); + + TMenuitem(TSubmenu* sm); + virtual ~TMenuitem() { } +}; + +class TSubmenu : public TObject +{ + TMenu* _menu; + TString _name; + TString _caption; + TFilename _picture; + TArray _items; + bool _enabled : 2; + bool _firm : 2; + +public: + void read(TScanner& scanner); + + TMenu& menu() const { return *_menu; } + int find_string(const TString& str) const; + + TMenuitem& item(int i) { return (TMenuitem&)_items[i]; } + const TMenuitem& item(int i) const { return (const TMenuitem&)_items[i]; } + const TMenuitem& operator[](int i) const { return item(i); } + + const TString& name() const { return _name; } + const TString& caption() const { return _caption; } + const TString& picture() const { return _picture; } + int items() const { return _items.items(); } + + TImage& image() const; + + bool query_firm() const { return _firm; } + bool enabled() const { return _enabled; } + bool disabled() const { return !enabled(); } + + bool perform(int i); + + TSubmenu(TMenu* menu, const char* name); + virtual ~TSubmenu() { } +}; + +class TMenu : public TAssoc_array +{ + TSubmenu* _current; + int _item; + TStack _stack; + + TFilename _default_bmp; + TString _default_menu; + + TAssoc_array _images; + TAssoc_array _modules; + + TToken_string _dangerous; + + TString _last_search; + TAssoc_array _ignore_list; + +protected: + bool can_be_transparent(const TImage& i) const; + +public: // TObject + virtual bool ok() const { return _current != NULL; } + +public: + bool read(const char* name); // First call + bool read(const char* name, TString& root); + + TSubmenu& current() const { return *_current; } + TSubmenu* find(const char* name) const { return (TSubmenu*)objptr(name); } + bool jumpto(TSubmenu *next); + bool jumpto_root(); + + TSubmenu& pop(); + bool at_top() const { return _stack.count() == 0; } + + void select(int i) { _item = i; } + int selected() const { return _item; } + TMenuitem& curr_item() { return _current->item(_item); } + TSubmenu* find_parent(const TSubmenu& sub); + + bool perform(); + TSubmenu* find_string(const TString& str); + TString& last_search_string() { return _last_search; } + TAssoc_array& search_ignore_list() { return _ignore_list; } + + TImage& image(const char* name); + void reload_images(); + + bool has_module(const char* mod); + bool is_dangerous(const char* mod); + + void set_dangerous_modules(const TToken_string& mod) + { _dangerous = mod; } + + TMenu() : _current(NULL), _item(0) { } + TMenu(const char* name) { read(name); } + virtual ~TMenu() { } +}; + + +#endif diff --git a/ba/ba0102.cpp b/ba/ba0102.cpp new file mode 100755 index 000000000..825439ed1 --- /dev/null +++ b/ba/ba0102.cpp @@ -0,0 +1,763 @@ +#include + +#include +#include +#include + +#include "ba0102.h" + +/////////////////////////////////////////////////////////// +// TMenu_tree +/////////////////////////////////////////////////////////// + +const TSubmenu& TMenu_tree::curr_submenu() const +{ + CHECKS(_submenu, "NULL submenu ", (const char*)_curr_id); + return *_submenu; +} + +const TMenuitem& TMenu_tree::curr_item() const +{ + const TSubmenu& sm = curr_submenu(); + if (_menuitem < 0 || _menuitem >= sm.items()) + { + NFCHECK("Invalid submenu item %d in %s", _menuitem, (const char*)sm.name()); + return sm.item(0); + } + return sm.item(_menuitem); +} + +struct TFind_node_data +{ + TString _id; + size_t _count; +}; + +struct TFind_string_data +{ + TString _str; + TAssoc_array* _ignore_list; +}; + +HIDDEN bool find_string_callback(TTree& tree, void* jolly, word flags) +{ + if (flags == SCAN_PRE_ORDER) + { + TMenu_tree& mt = (TMenu_tree&)tree; + TFind_string_data& data = *(TFind_string_data*)jolly; + + const TSubmenu& sm = mt.curr_submenu(); + if (data._ignore_list->is_key(sm.name())) + return FALSE; + + TString desc; mt.get_description(desc); + desc.upper(); + if (desc.find(data._str) >= 0 || desc.match(data._str)) + return TRUE; + } + return FALSE; +} + +HIDDEN bool find_node_callback(TTree& tree, void* jolly, word flags) +{ + if (flags == SCAN_PRE_ORDER) + { + TFind_node_data& data = *(TFind_node_data*)jolly; + data._count++; + TString id; tree.curr_id(id); + if (id == data._id) + return TRUE; + } + return FALSE; +} + +HIDDEN bool find_leaf_callback(TTree& tree, void* jolly, word flags) +{ + if (flags == SCAN_PRE_ORDER) + { + const TString& leaf = *(TString*)jolly; + TString id; tree.curr_id(id); + const int slash = id.rfind('/'); + if (slash > 0) + id = id.mid(slash+1); + if (id == leaf) + return TRUE; + } + return FALSE; +} + +bool TMenu_tree::find_string(const TString& str) +{ + TFind_string_data data; + data._str = str; data._str.upper(); + data._ignore_list = &_menu->search_ignore_list(); + + if (data._str != _menu->last_search_string()) + { + _menu->last_search_string() = data._str; + _menu->search_ignore_list().destroy(); + } + + goto_root(); + bool ok = scan_depth_first(find_string_callback, &data, SCAN_PRE_ORDER); + if (ok) + _menu->search_ignore_list().add(curr_submenu().name()); + else + _menu->search_ignore_list().destroy(); + + return ok; +} + +bool TMenu_tree::find_leaf(const TString& str) +{ + goto_root(); + bool ok = scan_depth_first(find_leaf_callback, (void *)&str, SCAN_PRE_ORDER); + return ok; +} + +void TMenu_tree::node2id(const TObject* node, TString& id) const +{ + TString* str = (TString*)node; + id = *str; +} + +bool TMenu_tree::goto_root() +{ + TSubmenu* sm = _menu->find(_root_id); + if (sm) + { + _curr_id = _root_id; + _curr_id << ".0"; + _submenu = sm; + _menuitem = 0; + } + return sm != NULL; +} + +bool TMenu_tree::goto_firstson() +{ + const TMenuitem& mi = curr_item(); + if (mi.is_submenu()) + { + const TSubmenu* sm = _menu->find(mi.action()); + if (sm && sm->items() > 0) + { + _curr_id << '/' << mi.action() << ".0"; + _submenu = sm; + _menuitem = 0; + return TRUE; + } + } + return FALSE; +} + +bool TMenu_tree::goto_rbrother() +{ + if (_menuitem < _submenu->items()-1) + { + const int dot = _curr_id.rfind('.'); + _curr_id.cut(dot+1); + _curr_id << (++_menuitem); + return TRUE; + } + return FALSE; +} + +bool TMenu_tree::goto_node(const TString &id) +{ + const int dot = id.rfind('.'); + CHECKS(dot > 0, "Invalid tree node ", (const char*)id); + _menuitem = atoi(id.mid(dot+1)); + _curr_id = id.left(dot); + const int slash = _curr_id.rfind('/'); + + _curr_id = _curr_id.mid(slash+1); + _submenu = _menu->find(_curr_id); + _curr_id = id; + + return _submenu != NULL; +} + +bool TMenu_tree::has_son() const +{ + const TMenuitem& mi = curr_item(); + return mi.is_submenu(); +} + +bool TMenu_tree::has_rbrother() const +{ + return _menuitem < _submenu->items()-1; +} + +bool TMenu_tree::has_root() const +{ + return _root_id.not_empty(); +} + +bool TMenu_tree::has_father() const +{ + return _curr_id.find('/') > 0; +} + +bool TMenu_tree::has_lbrother() const +{ + return _menuitem > 0; +} + +bool TMenu_tree::goto_father() +{ + const int slash = _curr_id.rfind('/'); + if (slash > 0) + { + const TString id = _curr_id.left(slash); + return goto_node(id); + } + return FALSE; +} + +bool TMenu_tree::goto_lbrother() +{ + if (_menuitem > 0) + { + const int dot = _curr_id.rfind('.'); + _curr_id.cut(dot+1); + _curr_id << (--_menuitem); + return TRUE; + } + return FALSE; +} + +TObject* TMenu_tree::curr_node() const +{ + return &((TMenu_tree*)this)->_curr_id; +} + +bool TMenu_tree::get_description(TString& desc) const +{ + const TMenuitem& mi = curr_item(); + desc = mi.caption(); + return desc.not_empty(); +} + +TImage* TMenu_tree::image(bool selected) const +{ + const TMenuitem& mi = curr_item(); + if (mi.disabled()) + return get_res_image(BMP_STOP); + return TTree::image(selected); +} + +long TMenu_tree::find_node(const TString& id) +{ + TFind_node_data data; + data._id = id; + data._count = 0; + goto_root(); + scan_depth_first(find_node_callback, &data, + SCAN_PRE_ORDER | SCAN_IGNORING_UNEXPANDED); + return data._count; +} + +TMenu_tree::TMenu_tree(TMenu& menu) + : _menu(&menu), _curr_id(128, '/') +{ + _root_id = _menu->current().name(); + goto_root(); +} + +/////////////////////////////////////////////////////////// +// Utility +/////////////////////////////////////////////////////////// + +void synchronize_tree_field(TTree_field& tf) +{ + TMenu_tree& mt = *(TMenu_tree*)tf.tree(); + + tf.select_current(); + TString id; mt.curr_id(id); // Memorizza nodo corrente + + mt.shrink_all(); + mt.goto_node(id); + do + { + mt.expand(); + } + while (mt.goto_father()); + + mt.goto_node(id); + tf.set_tree(&mt); // Azzera origine + + TField_window& win = tf.win(); + win.force_update(); +} + +/////////////////////////////////////////////////////////// +// TMenulist_field +/////////////////////////////////////////////////////////// + +class TMenulist_images : public TCache +{ + WINDOW _win; + +protected: + TObject* key2obj(const char* key); + bool can_be_transparent(const TImage& i) const; + +public: + void set_owner(WINDOW win) { _win = win; } + TImage* image(const TString& filename); + TMenulist_images() : TCache(17), _win(NULL_WIN) { } +}; + +bool TMenulist_images::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; +} + +inline int fast_hypot(int x, int y) +{ +// return (int)sqrt(double(x*x + y*y)); // Pitagora + +/* + const int s = x*x + y*y; + int h = 0; + for (int i = 512; i > 0; i /= 2) + { + const int k = h+i; + if (k*k <= s) + h = k; + } + return h; +*/ + // loop unrolled + #define TEST(s, h, i) { const int k = h+i; if (k*k <= s) h = k; } + const int s = x*x + y*y; + int h = 0; + TEST(s, h, 512); TEST(s, h, 256); TEST(s, h, 128); + TEST(s, h, 64); TEST(s, h, 32); TEST(s, h, 16); + TEST(s, h, 8); TEST(s, h, 4); TEST(s, h, 2); TEST(s, h, 1); + return h; +} + +TObject* TMenulist_images::key2obj(const char* key) +{ + TImage* img = NULL; + + if (fexist(key)) + { + TWait_cursor hourglass; + TImage image(key); + if (can_be_transparent(image)) + image.convert_transparent_color(NORMAL_BACK_COLOR); + + const int w = image.width(); + const int h = image.height(); + const int radius = min(w, h)/2; + + const clock_t start_timer = clock(); + for (int y = h-1; y >= 0; y--) + { + for (int x = w-1; x >= 0; x--) + { + int perc = 0; + const int r = fast_hypot(x-w/2, y-h/2); + if (r < radius) + { + perc = 75 - (75 * r / radius); + } + COLOR col = image.get_pixel(x, y); + COLOR bri = blend_colors(col, NORMAL_BACK_COLOR, perc); + image.set_pixel(x, y, bri); + } + } + const clock_t stop_timer = clock()-start_timer; + + RCT rct; xvt_vobj_get_client_rect(_win, &rct); + const double ratiox = double(rct.right) / image.width(); + const double ratioy = double(rct.bottom) / image.height(); + const double ratio = max(ratiox, ratioy); + const int maxx = int(ratio * image.width())-2; + const int maxy = int(ratio * image.height())-2; + img = new TImage(image, maxx, maxy); + } + return img; +} + +TImage* TMenulist_images::image(const TString& filename) +{ + TObject* obj = objptr(filename); + return (TImage*)obj; +} + +class TMenulist_window : public TField_window +{ + enum { MENU_COLS = 3, MENU_ROWS = 5 }; + +private: + TMenu_tree* _tree; + TString _curr_node; + bool _can_go_back; + + TMenulist_images _images; + TString _image_name; + + int _selected; + TPointer_array _sorted; + +protected: + virtual void update(); + virtual void handler(WINDOW win, EVENT* ep); + virtual bool on_key(KEY k); + + void synchronize_buddy_tree() const; + void draw_item(int i); + void click_on(int index); + void select(int s, int direction); + +public: + void set_menu(TMenu_tree& mt); + + TMenulist_window(int x, int y, int dx, int dy, WINDOW parent, TMenulist_field* owner); + virtual ~TMenulist_window(); +}; + +void TMenulist_window::draw_item(int i) +{ + if (i < 0 && i >= _sorted.items()) + return; // Scarta elementi non validi + + RCT rct; xvt_vobj_get_client_rect(win(), &rct); + const int width = rct.right - rct.left; + const int height = rct.bottom - rct.top; + + xvt_set_font(win(), NULL, 0, 0); // Set default font + set_opaque_text(TRUE); + + const TMenuitem& item = (const TMenuitem&)_sorted[i]; + if (i == _selected && item.enabled()) + set_color(item.color(), FOCUS_BACK_COLOR); + else + { + COLOR bc = item.enabled() ? NORMAL_BACK_COLOR : DISABLED_BACK_COLOR; + set_color(item.color(), bc); + } + + const int row = i / MENU_COLS; + const int col = i % MENU_COLS; + const int left = col * width / MENU_COLS; + const int right = (col+1) * width / MENU_COLS; + const int top = row * height / MENU_ROWS; + const int bottom = (row+1) * height / MENU_ROWS; + + const int maxchars = (right-left)/CHARX - 1; + const int cx = (left+right)/2; + const int cy = (top+bottom)/2; + + const int ico = item.enabled() ? item.icon() : 0; + const int ix = cx-16; + const int iy = top+2; + if (item.is_submenu()) + { + xvt_dwin_draw_icon(win(), ix, iy, 10202); + if ( ico > 0) + xvt_dwin_draw_icon(win(), ix, iy+4, ico); + } + else + { + xvt_dwin_draw_icon(win(), ix, iy, ico > 0 ? ico : ICON_RSRC); + } + + TString str = item.caption(); + if (i == 0 && _can_go_back) + str.insert("(..)\n"); + + TParagraph_string para(str, maxchars); + int y = iy + 32 + CHARY-2; + FOR_EACH_TOKEN(para, line) + { + const int ll = xvt_dwin_get_text_width(win(), line, -1); + const int x = cx - ll/2; + xvt_dwin_draw_text(win(), x, y, line, -1); + y += CHARY-2; + } + if (item.disabled()) + xvt_dwin_draw_icon(win(), ix+4, iy+4, 10203); // Stop icon +/* if (item.disabled()) + { + set_pen(COLOR_RED, 3); + PNT p; + p.h = ix, p.v = iy; xvt_dwin_draw_set_pos(win(), p); + p.h = ix+32, p.v = iy+32; xvt_dwin_draw_line(win(), p); + p.h = ix+32, p.v = iy; xvt_dwin_draw_set_pos(win(), p); + p.h = ix, p.v = iy+32; xvt_dwin_draw_line(win(), p); + } +*/ +} + +void TMenulist_window::update() +{ + TImage* img = _images.image(_image_name); // Delay time before clearing + + TField_window::update(); + if (_tree == NULL) + return; // Nothing to draw + + if (img != NULL) + { + RCT rct; xvt_vobj_get_client_rect(win(), &rct); + const int x = (rct.right - img->width())/2; + const int y = (rct.bottom - img->height())/2; + img->draw(win(), x, y); + } + + for (int i = 0; i < _sorted.items(); i++) + draw_item(i); +} + +void TMenulist_window::click_on(int index) +{ + if (index >= 0 && index < _sorted.items()) + { + const TMenuitem& mi = (const TMenuitem&)_sorted[index]; + if (mi.enabled()) + { + if (mi.is_submenu()) + { + if (index == 0 && _can_go_back) // Sù di un livello + { + _tree->goto_node(_curr_node); + _tree->goto_father(); + set_menu(*_tree); + } + else // Giù di un livello + { + if (mi.perform()) // Eventuale richiesta ditta + { + _tree->goto_node(_curr_node); + const TSubmenu& mnu = _tree->curr_submenu(); + for (int i = 0; i < mnu.items(); i++) + { + const TMenuitem& ti = mnu[i]; + if (ti.action() == mi.action()) + { + _tree->goto_firstson(); + set_menu(*_tree); + synchronize_buddy_tree(); + break; + } + _tree->goto_rbrother(); + } + } + } + } + else + { + mi.perform(); + } + set_focus(); + } + } +} + +void TMenulist_window::handler(WINDOW win, EVENT* ep) +{ + switch (ep->type) + { + case E_MOUSE_DOWN: + { + int index = 0; + if (ep->v.mouse.button > 0) // Tasto destro = Torna sù + { + if (!_can_go_back) + return; + } + else + { + RCT rct; xvt_vobj_get_client_rect(win, &rct); + const int row = ep->v.mouse.where.v * MENU_ROWS / rct.bottom; + const int col = ep->v.mouse.where.h * MENU_COLS / rct.right; + index = row * MENU_COLS + col; + } + click_on(index); + } + break; + default: + break; + } + + TField_window::handler(win, ep); +} + +void TMenulist_window::select(int s, int direction) +{ + const int old_selection = _selected; + + if (s < 0) + s = 0; + if (s >= _sorted.items()) + s = _sorted.last(); + + _selected = s; + const TMenuitem& mi = (const TMenuitem&)_sorted[_selected]; + if (!mi.enabled()) + { + for (_selected += direction; ; _selected += direction) + { + if (_selected < 0) + _selected = _sorted.last(); + if (_selected >= _sorted.items()) + _selected = 0; + if (_selected == s) // Ho rifatto l'intero giro! + break; + + const TMenuitem& item = (const TMenuitem&)_sorted[_selected]; + if (item.enabled()) + break; // Ho trovato un elemento abilitato! + } + } + + draw_item(old_selection); + draw_item(_selected); +} + +bool TMenulist_window::on_key(KEY k) +{ + switch (k) + { + case K_ESC: + case K_BACKSPACE: + if (_tree != NULL && _can_go_back) // Sù di un livello + click_on(0); + break; + case K_ENTER: + case K_SPACE: + click_on(_selected); + break; + case K_HOME: + select(0, +1); + break; + case K_UP: + case K_PREV: + select(_selected - MENU_COLS, -1); + break; + case K_DOWN: + case K_NEXT: + select(_selected + MENU_COLS, +1); + break; + case K_LEFT: + select(_selected-1, -1); + break; + case K_RIGHT: + select(_selected+1, +1); + break; + case K_END: + select(_sorted.last(), -1); + break; + default: + break; + } + return TRUE; +} + +void TMenulist_window::synchronize_buddy_tree() const +{ + TMask& m = owner().mask(); + for (int i = 0; i < m.fields(); i++) + { + TMask_field& mf = m.fld(i); + if (mf.is_kind_of(CLASS_TREE_FIELD)) + { + TTree_field& tf = (TTree_field&)mf; + synchronize_tree_field(tf); + break; + } + } +} + +void TMenulist_window::set_menu(TMenu_tree& tree) +{ + _tree = &tree; + + tree.curr_id(_curr_node); + const int dot = _curr_node.rfind('.')+1; + + int sel = -1; + if (dot > 0) + { + sel = atoi(_curr_node.mid(dot)); + _curr_node.overwrite("0", dot); + } + + _sorted.destroy(); + _can_go_back = tree.goto_father(); + if (_can_go_back) + { + _sorted.add(tree.curr_item()); + tree.goto_node(_curr_node); + } + + int folders = _sorted.items(); + + // Lista riordinata dei menu items + const TSubmenu& mnu = tree.curr_submenu(); + for (int i = 0; i < mnu.items(); i++) + { + const TMenuitem& item = mnu[i]; + if (item.is_submenu()) + _sorted.insert(item, folders++); + else + _sorted.add(item); + } + + TString80 sel_act; + if (sel >= 0 && sel < mnu.items()) + sel_act= mnu[sel].action(); + + for (_selected = _sorted.last(); _selected > 0; _selected--) + { + const TMenuitem& sm = (const TMenuitem&)_sorted[_selected]; + if (sm.enabled() && sm.action() == sel_act) + break; + } + + _image_name = mnu.picture(); + + force_update(); +} + +TMenulist_window::TMenulist_window(int x, int y, int dx, int dy, WINDOW parent, TMenulist_field* owner) + : TField_window(x, y, dx, dy, parent, owner), _tree(NULL) +{ + set_scroll_max(0, 0); // Get rid of that useless scrollbars + _images.set_owner(win()); +} + +TMenulist_window::~TMenulist_window() +{ +} + +TField_window* TMenulist_field::create_window(int x, int y, int dx, int dy, WINDOW parent) +{ + return new TMenulist_window(x, y, dx, dy, parent, this); +} + +void TMenulist_field::create(short dlg, int x, int y, int dx, int dy) +{ + _dlg = dlg; + _win = create_window(x, y, dx, dy, mask().win()); +} + +void TMenulist_field::set_menu(TMenu_tree& mt) +{ + TMenulist_window& w = (TMenulist_window&)win(); + w.set_menu(mt); +} diff --git a/ba/ba0102.h b/ba/ba0102.h new file mode 100755 index 000000000..2fb335f98 --- /dev/null +++ b/ba/ba0102.h @@ -0,0 +1,74 @@ +#ifndef __BA0102_H +#define __BA0102_H + +#ifndef __MASKFLD_H +#include +#endif + +#ifndef __TREE_H +#include +#endif + +#ifndef __BA0101_H +#include "ba0101.h" +#endif + +class TMenu_tree : public TBidirectional_tree +{ + TMenu* _menu; + const TSubmenu* _submenu; + int _menuitem; + + TString _root_id, _curr_id; + +protected: // TTree + virtual void node2id(const TObject* node, TString& id) const; + +public: // TTree + virtual bool goto_root(); + virtual bool goto_firstson(); + virtual bool goto_rbrother(); + virtual bool goto_node(const TString &id); + virtual bool has_son() const; + virtual bool has_rbrother() const; + virtual TObject* curr_node() const; + + virtual bool has_root() const; + virtual bool has_father() const; + virtual bool has_lbrother() const; + virtual bool goto_father(); + virtual bool goto_lbrother(); + + virtual void curr_id(TString& id) const { id = _curr_id; } + virtual bool get_description(TString& desc) const; + virtual TImage* image(bool selected) const; + +public: + const TSubmenu& curr_submenu() const; + const TMenuitem& curr_item() const; + + bool find_leaf(const TString& str); + bool find_string(const TString& str); + long find_node(const TString& id); + + TMenu_tree(TMenu& menu); + virtual ~TMenu_tree() { } +}; + +class TMenulist_field : public TWindowed_field +{ +protected: // TWindowed_field + virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent); + +public: + void set_menu(TMenu_tree& mt); + void create(short dlg, int x, int y, int dx, int dy); + + TMenulist_field(TMask* m) : TWindowed_field(m) { } + virtual ~TMenulist_field() { } +}; + +// Utilities +void synchronize_tree_field(TTree_field& tf); + +#endif diff --git a/ba/ba0200a.uml b/ba/ba0200a.uml index 90533cdaa..d6b530527 100755 --- a/ba/ba0200a.uml +++ b/ba/ba0200a.uml @@ -1,124 +1,124 @@ -PAGE "Colori" -1 -1 50 19 +PAGE "Colori" -1 -1 54 19 -GROUPBOX DLG_NULL 48 3 +GROUPBOX DLG_NULL 16 5 BEGIN PROMPT 1 0 "@bMaschera" END -BUTTON 101 10 +BUTTON 101 12 BEGIN PROMPT 2 1 "Normale" END -BUTTON 102 10 +BUTTON 102 12 BEGIN - PROMPT 19 1 "Chiaro" + PROMPT 2 2 "Chiaro" END -BUTTON 103 10 +BUTTON 103 12 BEGIN - PROMPT 36 1 "Scuro" + PROMPT 2 3 "Scuro" END -GROUPBOX DLG_NULL 14 4 +GROUPBOX DLG_NULL 16 5 BEGIN - PROMPT 1 3 "@bNormale" + PROMPT 19 0 "@bBottoni" END -BUTTON 104 10 +BUTTON 111 12 BEGIN - PROMPT 2 4 "Testo" + PROMPT 20 1 "Sfondo" END -BUTTON 105 10 +BUTTON 112 12 BEGIN - PROMPT 2 5 "Sfondo" + PROMPT 20 2 "Chiaro" END -GROUPBOX DLG_NULL 14 4 +BUTTON 113 12 BEGIN - PROMPT 18 3 "@bAttivo" + PROMPT 20 3 "Scuro" END -BUTTON 106 10 +GROUPBOX DLG_NULL 16 5 BEGIN - PROMPT 19 4 "Testo" + PROMPT 37 0 "@bNormale" END -BUTTON 107 10 +BUTTON 104 12 BEGIN - PROMPT 19 5 "Sfondo" + PROMPT 38 1 "Testo" END -GROUPBOX DLG_NULL 14 4 +BUTTON 105 12 BEGIN - PROMPT 35 3 "@bDisabilitato" + PROMPT 38 2 "Sfondo" END -BUTTON 108 10 +BUTTON 106 12 BEGIN - PROMPT 36 4 "Testo" + PROMPT 38 3 "Obbligatorio" END -BUTTON 109 10 + +GROUPBOX DLG_NULL 16 4 BEGIN - PROMPT 36 5 "Sfondo" + PROMPT 37 5 "@bAttivo" END -GROUPBOX DLG_NULL 14 5 +BUTTON 107 12 BEGIN - PROMPT 35 7 "@bBottone" + PROMPT 38 6 "Testo" END -BUTTON 110 10 +BUTTON 108 12 BEGIN - PROMPT 36 8 "Sfondo" + PROMPT 38 7 "Sfondo" END -BUTTON 111 10 +GROUPBOX DLG_NULL 16 4 BEGIN - PROMPT 36 9 "Chiaro" + PROMPT 37 9 "@bDisabilitato" END -BUTTON 112 10 +BUTTON 109 12 BEGIN - PROMPT 36 10 "Scuro" + PROMPT 38 10 "Testo" END -BOOLEAN 113 +BUTTON 110 12 BEGIN - PROMPT 2 18 "Campi 3D" + PROMPT 38 11 "Sfondo" END -BOOLEAN 115 +BOOLEAN 213 BEGIN - PROMPT 2 17 "Icone alternative" + PROMPT 38 13 "Campi 3D" END -BUTTON 114 10 2 +BOOLEAN 215 BEGIN - PROMPT 20 -1 "Font" + PROMPT 38 14 "Icone piccole" END -GROUPBOX DLG_NULL 14 8 +BUTTON 214 12 2 BEGIN - PROMPT 35 12 "" + PROMPT -33 16 "Font" END -BUTTON DLG_CANCEL 10 2 +BUTTON DLG_CANCEL 12 2 BEGIN - PROMPT 36 13 "Annulla" + PROMPT -13 -1 "Annulla" END -BUTTON DLG_USER 10 2 +BUTTON DLG_USER 12 2 BEGIN - PROMPT 36 15 "A~zzera" + PROMPT -23 -1 "A~zzera" END -BUTTON DLG_OK 10 2 +BUTTON DLG_OK 12 2 BEGIN - PROMPT 36 17 "Conferma" - PICTURE BMP_OK + PROMPT -33 -1 "" END ENDPAGE diff --git a/ba/ba0400a.uml b/ba/ba0400a.uml index d02cbfda9..3ed4f4696 100755 --- a/ba/ba0400a.uml +++ b/ba/ba0400a.uml @@ -2,9 +2,12 @@ PAGE "Preferiti" -1 -1 70 16 -BOOLEAN F_PREF_TREE +LIST F_PREF_TREE 1 10 BEGIN - PROMPT 1 0 "Menu ad albero" + PROMPT 1 0 "Tipo di Menu" + ITEM " |Normale" + ITEM "1|Albero" + ITEM "2|Explorer" END SPREADSHEET F_PREF_SHEET 63 -3 diff --git a/ba/ba1600.cpp b/ba/ba1600.cpp index 1d1736780..ff1a5dd35 100755 --- a/ba/ba1600.cpp +++ b/ba/ba1600.cpp @@ -2239,7 +2239,8 @@ int ba1600(int argc, char* argv[]) TCreazione_dischi app; app.run(argc, argv, TR("Creazione dischetti")); } - } else + } + else error_box(FR("L'utente %s non e' abilitato all'esecuzione di questo programma"), (const char*)user()); return 0; } diff --git a/ba/ba1700.cpp b/ba/ba1700.cpp index df77ba367..fc67522ec 100755 --- a/ba/ba1700.cpp +++ b/ba/ba1700.cpp @@ -624,7 +624,7 @@ KEY TInstaller_mask::askdisk(TString & path, TFilename & cmdline, int d, int dis TMask retry_mask(TR("Inserimento dischi"),1,80,10); retry_mask.add_static((F_PATH==101 ? 102:101),0, - format(FR("Inserire il disco %d di %d del modulo'%s' nell' unità indicata"), d, dischi, modulo) + format(FR("Inserire il disco %d di %d del modulo'%s' nell'unità"), d, dischi, modulo) ,2,2); retry_mask.add_static(F_PATH+3,0,TR("oppure indicare un percorso diverso"),2,3); diff --git a/ba/ba2200.cpp b/ba/ba2200.cpp index 0bd702465..4af48ffff 100755 --- a/ba/ba2200.cpp +++ b/ba/ba2200.cpp @@ -109,14 +109,18 @@ bool TArchive_mask::on_field_event(TOperable_field& o, TField_event e, long joll bool TArchive_app::create() { bool ok = TRUE; - + TIsamfile utenti(LF_USER); utenti.open(_excllock); for (int err = utenti.first(); err == NOERR; err = utenti.next()) { const TString16 u = utenti.get("USERNAME"); if (u != user() && utenti.get_bool("CONNECTED")) +#ifdef DBG + ok = yesno_box("L'archiviazione non puo' essere effettuata\nse ci sono altri utenti collegati (%s)", (const char*)u); +#else ok = error_box(FR("L'archiviazione non puo' essere effettuata\nse ci sono altri utenti collegati (%s)"), (const char*)u); +#endif } utenti.close(); diff --git a/ba/ba2600.cpp b/ba/ba2600.cpp index 71df982dc..f286c7459 100755 --- a/ba/ba2600.cpp +++ b/ba/ba2600.cpp @@ -3214,7 +3214,8 @@ KEY TEditMask_window::main_loop() //Richiama bool TMaskEditor_application::create() { - return TApplication::create(); + dispatch_e_menu(MENU_ITEM(11)); + return true; } //Richiama @@ -3485,7 +3486,6 @@ bool TMaskEditor_application::menu(MENU_TAG m) return TRUE; } -//int main(int argc, char* argv[]) int ba2600(int argc, char* argv[]) { TMaskEditor_application a; diff --git a/ba/bamenu.men b/ba/bamenu.men index 34957397a..53669a5b2 100755 --- a/ba/bamenu.men +++ b/ba/bamenu.men @@ -3,12 +3,11 @@ Caption = "Menu Principale" Picture = Module = 0 Flags = "" -Item_01 = "Anagrafiche di base", [MENU_001] -Item_02 = "Amministrazione", -Item_03 = "Acquisti e vendite", -Item_04 = "Magazzino e Produzione", -Item_11 = "Comunicazione", [MENU_019] -Item_11 = "Manutenzione", [MENU_015] +Item_01 = "Anagrafiche di base", [MENU_001], "", 10214 +Item_02 = "Amministrazione", , "", 10212 +Item_03 = "Acquisti e vendite", , "", 10211 +Item_04 = "Magazzino e Produzione", , "", 10215 +Item_05 = "Manutenzione", [MENU_015], "", 10210 [MENU_001] Caption = "Gestione Anagrafiche" @@ -95,18 +94,9 @@ Item_03 = "Utenti", "ba1 -3", "" Item_04 = "Attivazione moduli", "ba1 -4", "" Item_05 = "Installazione moduli", "ba1 -6", "" Item_06 = "Creazione dischi di installazione", "ba1 -5", "" -Item_07 = "Backup", "ba2 -1", "" +Item_07 = "Backup", "ba2 -1", "", 10213 Item_08 = "Conversione all'Euro", [MENU_883] -[MENU_019] -Caption = "Comunicazione" -Picture = -Module = 0 -Item_01 = "EasyDoc", "c:\EasyDoc\EasyDoc.exe", "" -Item_02 = "Gestione Fax", "bafax -s", "" -Item_03 = "Archivio fax spediti e ricevuti", disabled -Item_04 = "Archivio contatti telefonici", disabled - [MENU_883] Caption = "Conversione all'Euro" Picture = diff --git a/ba/zip386.bat b/ba/zip386.bat deleted file mode 100755 index 84da73a91..000000000 --- a/ba/zip386.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -zip386.exe %1 -@ < %2 diff --git a/cg/cg2100.cpp b/cg/cg2100.cpp index 81c593540..5ef852643 100755 --- a/cg/cg2100.cpp +++ b/cg/cg2100.cpp @@ -113,6 +113,7 @@ TMask* TPrimanota_application::load_mask(int n) for (short id = 111; id <= 114; id++) { is.delete_column(id); + ism.hide(id); // Descrizioni commessa e fase } } @@ -1831,4 +1832,4 @@ int cg2100 (int argc, char** argv) a->run(argc, argv, "Prima nota"); delete a; return 0; -} +} \ No newline at end of file diff --git a/cg/cgmenu.men b/cg/cgmenu.men index e57ba6000..186a8b37f 100755 --- a/cg/cgmenu.men +++ b/cg/cgmenu.men @@ -89,17 +89,12 @@ Flags = "" Item_01 = "Prima nota", "cg2 -0", "F" Item_02 = "Gestione movimenti provvisori", "cg2 -1", "F" Item_03 = "Visualizzazione mastrini", "cg3 -5", "F" -Item_04 = "IVA", [CGMENU_010] -Item_05 = "Lista movimenti", "cg3 -0 M", "F" -Item_06 = "Lista fatture per clienti/fornitori", "cg3 -0 C", "F" -Item_07 = "Stampa Mastrini", "cg3 -1", "F" -Item_08 = "Stampa Riepiloghi", "cg3 -4", "F" -Item_09 = "Visualizzazione saldi", "cg5 -2", "F" -Item_10 = "Ricalcolo saldi", "cg4 -0", "F" -Item_11 = "Bilancio", "cg1 -4", "F" -Item_12 = "Bilancio IV direttiva CEE", "cg1 -5", "F" -Item_13 = "Giornale", "cg3 -3", "F" -Item_14 = "Saldaconto", +Item_04 = "Visualizzazione saldi", "cg5 -2", "F" +Item_05 = "Ricalcolo saldi", "cg4 -0", "F" +Item_06 = "IVA", [CGMENU_010] +Item_07 = "Stampe di contabilita`", [CGMENU_023] +Item_08 = "Stampe CDC/Commesse ", +Item_09 = "Saldaconto", [CGMENU_010] Caption = "IVA" @@ -231,6 +226,19 @@ Item_02 = "Gestione versamenti", "ba3 -0 %del", "" Item_03 = "Stampa versamenti", "cg1 -3", "F" Item_04 = "Gestione profili deleghe e distinte", "ba2 -0", "" +[CGMENU_023] +Caption = "Stampe di contabilita`" +Picture = +Module = 7 +Flags = "" +Item_01 = "Lista movimenti", "cg3 -0 M", "F" +Item_02 = "Lista fatture per clienti/fornitori", "cg3 -0 C", "F" +Item_03 = "Stampa Mastrini", "cg3 -1", "F" +Item_04 = "Stampa Riepiloghi", "cg3 -4", "F" +Item_05 = "Bilancio", "cg1 -4", "F" +Item_06 = "Bilancio IV direttiva CEE", "cg1 -5", "F" +Item_07 = "Giornale", "cg3 -3", "F" + [CGMENU_025] Caption = "Collegamento bilanci" Picture = diff --git a/include/codeb.c b/include/codeb.c index 4ca06d460..8e1cadf8b 100755 --- a/include/codeb.c +++ b/include/codeb.c @@ -58,18 +58,6 @@ bool handle_ok(int handle) static char* find_slash_backslash(const char* s) { -/* - const int l = strlen(str); - const char* xstr = str + l; - while (xstr-- && l--) - if (*xstr == '\\' || *xstr == '/' || l <= 0) - break; - if (l <= 0) - return NULL; - else - return xstr; -*/ - const char* slash = NULL; for ( ; *s; s++) { diff --git a/include/colors.cpp b/include/colors.cpp index 7da9e53c1..16fc71075 100755 --- a/include/colors.cpp +++ b/include/colors.cpp @@ -51,6 +51,7 @@ COLOR blend_colors(COLOR col1, COLOR col2, int perc) } + class TColor_row_mask : public TMask { public: @@ -329,4 +330,3 @@ TSelect_color_mask::~TSelect_color_mask() { delete _sheet_mask; } - diff --git a/include/image.cpp b/include/image.cpp index 6ba0ff141..6236b427a 100755 --- a/include/image.cpp +++ b/include/image.cpp @@ -81,6 +81,7 @@ TImage::TImage(const TImage& im, short w, short h) : _image(NULL) if (ok()) { +#ifndef XVAGA if (fmt == XVT_IMAGE_CL8) { const short colors = xvt_image_get_ncolors(im._image); @@ -88,6 +89,7 @@ TImage::TImage(const TImage& im, short w, short h) : _image(NULL) for (short c = 0; c < colors; c++) xvt_image_set_clut(_image, c, xvt_image_get_clut((XVT_IMAGE)im._image, c)); } +#endif xvt_image_transfer(_image, (XVT_IMAGE)im._image, &_src, (RCT*)&im._src); } } diff --git a/include/isam.cpp b/include/isam.cpp index 4ba65c6bf..2b41ac608 100755 --- a/include/isam.cpp +++ b/include/isam.cpp @@ -957,8 +957,9 @@ int TBaseisamfile::_read(TRectype& rec, word op, word lockop) _lasterr = cisread(fhnd, getkey(), rec, op + lockop, _recno); - _recno = DB_recno(fhnd); // qui - if(rec.has_memo()) + // _recno = DB_recno(fhnd); // Gia' fatto nella cisread + + if(rec.has_memo()) rec.init_memo(_recno, _isam_handle); if (_lasterr == NOERR) @@ -1275,10 +1276,8 @@ int TBaseisamfile::_open( else fatal_box(msg); } - if (prefix().get_recdes(_logicnum).NKeys <= 0) // qui - fatal_box("Il file %d (%s) e' senza indici", - num(), - (const char*)filename); + if (prefix().get_recdes(_logicnum).NKeys <= 0) + fatal_box("Il file %d (%s) e' senza indici", num(), (const char*)filename); _recno = RECORD_NON_FISICO; setkey(_curr_key); _lasterr = NOERR; @@ -2462,13 +2461,16 @@ int TSystemisamfile::load( char* s2 = (char*) s.get(); if (fd) { - s2++; - s2[strlen(s2) - 1] = '\0'; + s1.rtrim(1); + s1.ltrim(1); } if (curr().type((const TString&) fld[j]) == _memofld) - s1 = esc(s2); - else - s1 = s2; + { + TString s2 = s1; + + s1 = esc(s2); + } + put((const TString&) fld[j], s1); } } @@ -3362,9 +3364,6 @@ int TRectype::readat(TBaseisamfile& f, TRecnotype nrec, word lockop) // Certified 100% int TRectype::next(TBaseisamfile& f,word lockop) { -/* const int err = f._read(*this, _isnext, lockop); - *this = f.curr(); - return err; */ return read(f, _isnext, lockop); } diff --git a/include/maskfld.h b/include/maskfld.h index 15f66fe1c..deaf5c4ed 100755 --- a/include/maskfld.h +++ b/include/maskfld.h @@ -1562,6 +1562,7 @@ public: class TWindowed_field : public TOperable_field { +protected: short _dlg; TField_window* _win; @@ -1610,6 +1611,8 @@ public: bool goto_selected(); void set_header(const char* head); + void set_row_height(int rh); + TTree_field(TMask* m) : TWindowed_field(m) { } virtual ~TTree_field() { } @@ -1637,4 +1640,3 @@ public: #endif // __MASKFLD_H - diff --git a/include/msksheet.cpp b/include/msksheet.cpp index 1e084ccac..a4c633b73 100755 --- a/include/msksheet.cpp +++ b/include/msksheet.cpp @@ -1007,9 +1007,9 @@ bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev) static char tmp[16]; static clock_t digit_timer = 0; - BOOLEAN& refused = xiev->refused; + switch (xiev->type) { case XIE_GET_FIRST: @@ -1110,6 +1110,7 @@ bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev) if (xiev->v.cell_request.back_color == 0 && f->required()) xiev->v.cell_request.back_color = REQUIRED_BACK_COLOR; + } diff --git a/include/printer.cpp b/include/printer.cpp index d73e5f651..b4ef16555 100755 --- a/include/printer.cpp +++ b/include/printer.cpp @@ -1585,7 +1585,7 @@ bool TPrinter::set() // determine index of currently selected printer // ACTHUNG! Deep hacking of XVT internals! NON PORTABLE! - _prname = (const char *)(get_printrcd() + 4); + _prname = (const char *)(get_printrcd()) + 4; if (_prname.blank()) _prname = oldprn; diff --git a/include/tree.cpp b/include/tree.cpp index 3a141ca26..0ecbf6e45 100755 --- a/include/tree.cpp +++ b/include/tree.cpp @@ -804,13 +804,15 @@ class TTree_window : public TField_window TAuto_token_string _header; int _headlines; - static int _row_height; + /*static*/ int _row_height; static bool _tree_locked; protected: // TWindow virtual void update(); virtual bool on_key(KEY key); virtual void handler(WINDOW win, EVENT* ep); + + int row_height() const { return _row_height; } PNT log2dev(long x, long y) const; TPoint dev2log(const PNT& p) const; @@ -830,12 +832,13 @@ public: bool goto_selected(); void set_header(const char* head); + TTree_window(int x, int y, int dx, int dy, WINDOW parent, TTree_field* owner); virtual ~TTree_window() { } }; -int TTree_window::_row_height = CHARY+2; +/* int TTree_window::_row_height = CHARY+2; */ bool TTree_window::_tree_locked = FALSE; const int TABX = 3; @@ -929,19 +932,22 @@ bool TTree_window::callback_draw_node(TTree& node, void* jolly, word when) const WINDOW win = ui->_win->win(); ui->_win->set_pen(DISABLED_COLOR); + const int rh = ui->_win->row_height(); + PNT q; - q.h = p.h; q.v = p.v + _row_height/2; + q.h = p.h; q.v = p.v + rh/2; xvt_dwin_draw_set_pos(win, q); q.h -= TABX*CHARX - 3*CHARX/2; xvt_dwin_draw_line(win, q); - q.v = (by+1+ui->_headlines)*_row_height; + q.v = (by+1)*rh; + xvt_dwin_draw_line(win, q); TImage* bmp = node.image(is_selected); if (bmp) { const int x = p.h; - const int y = p.v + (_row_height - bmp->height()) / 2; + const int y = p.v + (rh - bmp->height()) / 2; if (is_enabled) bmp->draw(win, x, y); else @@ -1145,6 +1151,12 @@ bool TTree_window::goto_selected() return ok; } +void TTree_window::set_row_height(int rh) +{ + if (rh <= 0) + rh = CHARY+2; + _row_height = rh; +} int TTree_window::info2index(const TNode_info& info) const { @@ -1347,7 +1359,7 @@ TTree_window::TTree_window(int x, int y, int dx, int dy, : TField_window(x, y, dx, dy, parent, owner), _tree(NULL), _hide_leaves(FALSE), _headlines(0) { - _row_height = CHARY+2; + set_row_height(-1); // Compute default row height } /////////////////////////////////////////////////////////// @@ -1397,7 +1409,14 @@ void TTree_field::set_header(const char* head) tree_win().set_header(head); } +void TTree_field::set_row_height(int rh) +{ + tree_win().set_row_height(rh); +} + + + TField_window* TTree_field::create_window(int x, int y, int dx, int dy, WINDOW parent) { return new TTree_window(x, y, dx, dy, parent, this); -} +} \ No newline at end of file diff --git a/server/baseserv.h b/server/baseserv.h index 59ee81378..917ba6510 100755 --- a/server/baseserv.h +++ b/server/baseserv.h @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/server/dbserver.cpp b/server/dbserver.cpp index a8e4f762e..511b05006 100755 --- a/server/dbserver.cpp +++ b/server/dbserver.cpp @@ -1,6 +1,13 @@ +#include + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif //WX_PRECOMP + #include "BaseServ.h" -#include +#include +//#include #include /////////////////////////////////////////////////////////// diff --git a/server/server.rc b/server/server.rc index 58e1f88b4..4a7b00c37 100755 --- a/server/server.rc +++ b/server/server.rc @@ -1,3 +1,3 @@ mondrian ICON "soap.ico" -#include "wx/msw/wx.rc" +#include "../../wx240/include/wx/msw/wx.rc" diff --git a/ve/velib04b.cpp b/ve/velib04b.cpp index 085b64ccc..c4c2c71e1 100755 --- a/ve/velib04b.cpp +++ b/ve/velib04b.cpp @@ -1897,6 +1897,7 @@ error_type TContabilizzazione::compile_rows_mov(TDocumento& doc) else _righe_iva->add(r, conto, ALL_DECIMALS, perc); + } r.put(RDOC_CODIVA, codiva2); //Restore } diff --git a/ve/velib06.cpp b/ve/velib06.cpp index 83127acaf..9d54eb6ef 100755 --- a/ve/velib06.cpp +++ b/ve/velib06.cpp @@ -2360,6 +2360,7 @@ bool TDocumento_mask::controeuro_handler( TMask_field& f, KEY key ) bool TDocumento_mask::codval_handler( TMask_field& f, KEY key ) + { if (key == K_TAB && f.focusdirty()) { @@ -2388,4 +2389,3 @@ bool TDocumento_mask::codval_handler( TMask_field& f, KEY key ) } return TRUE; } - diff --git a/xvaga/xvaga.cpp b/xvaga/xvaga.cpp index 466fed570..fce05b046 100755 --- a/xvaga/xvaga.cpp +++ b/xvaga/xvaga.cpp @@ -2175,7 +2175,10 @@ SLIST xvt_fsys_list_files(char *type, char *pat, BOOLEAN dirs) wxString f = ::wxFindFirstFile(pat, flags); while (!f.IsEmpty()) { - xvt_slist_add_at_elt(list, NULL, f, 0L); + if (f.StartsWith(".\\")) + f = f.Mid(2); + xvt_slist_add_at_elt(list, NULL, f, 0L); + f = ::wxFindNextFile(); } @@ -3150,6 +3153,9 @@ long xvt_vobj_get_attr(WINDOW win, long data) case ATTR_TASK_WINDOW: ret = long(_task_win); break; + case ATTR_WIN_INSTANCE: + ret = 0; + break; case ATTR_WIN_PM_DRAWABLE_TWIN: ret = TRUE; break; @@ -3502,4 +3508,4 @@ WINDOW statbar_create(int cid, int left, int top, int right, int bottom, w.SetStatusWidths(2, widths); return (WINDOW)&w; -} +} \ No newline at end of file