#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include HIDDEN const char* const MASK_EXT = "msk"; /////////////////////////////////////////////////////////// // TMask methods /////////////////////////////////////////////////////////// void TMask::init_mask() { _msg_field = 0; _msg_key = 0; _pages = 0; // Azzera numero pagine e sheets if (_mask_num == 0) _sheet = NULL; // Non appartiene a nessuno sheet _enabled.set(MAX_PAGES); _enabled.set(); // Abilita tutte le pagine _should_check = true; _focus = _first_focus = 0; // Il primo ha il focus _page = -1; // Nessuna pagina corrente _handler = NULL; // Nessun handler utente _mode = NO_MODE; // Inizializza modo _error_severity = 0; _msg_field = 0; _msg_key = 0; _test_fld = -1; _last_test = -1; _toolwin = _toolbar = _notebook = _single = NULL_WIN; memset(_pagewin, 0, sizeof(_pagewin)); // Azzero lista pagine } WINDOW TMask::page_win(int p) const { if (p >= MAX_PAGES) return p == MAX_PAGES ? toolwin() : toolbar(); if (p >= 0 && p < _pages) return _pagewin[p]; return p <= 0 ? win() : NULL_WIN; } WINDOW TMask::curr_win() const { return page_win(_page > 0 && _page < _pages ? _page : 0); } TMask::TMask() : _mask_num(0) { init_mask(); } TMask::TMask(const char* title, int pages, int cols, int rows, int xpos, int ypos, WINDOW parent) : _mask_num(0) { init_mask(); if (pages > 1) { //WINDOW w = create_interface(parent, xpos, ypos, cols, rows, title, this); //set_win(w); // Crea la pagina principale che ospitera' il notebook const WIN_TYPE wt = (cols == 0) ? W_PLAIN : W_DOC; const long wsf = WSF_INVISIBLE | WSF_NO_MENUBAR; create(xpos, ypos, cols, rows, title, wsf, wt); create_book(false); // Crea il notebook che ospitera' le pagine for (int p = 1; p <= pages; p++) { WINDOW w = create_interface(notebook(), 0, 0, 0, 0, title, this); insert_page(w, -1); // Aggiunge nuova pagina in fondo } } else { WINDOW w = create_interface(parent, xpos, ypos, cols, rows, title, this); insert_page(w, 0); } } void TMask::set_locking(TBit_array& read_only, TToken_string& list, bool on) { if (list.find('*') >= 0) { if (on) { read_only.set(fields()); read_only.set(); } else read_only.reset(); } else { FOR_EACH_TOKEN(list, fld) { const TFixed_string id(fld); if (id[0] == '-' || id.ends_with("@")) // Gestione gruppi { const int grp = abs(atoi(fld)); FOR_EACH_MASK_FIELD((*this), pos, f) { if (f->in_group(grp)) read_only.set(pos, on); } } else { const int pos = field2pos(fld); if (pos >= 0) read_only.set(pos, on); } } } } // @mfunc Legge la maschera da file void TMask::read_mask( const char* name, // @parm Nome della maschera da leggere (senza estensione) int num, // @parm Numero della maschera da leggere all'interno del file int max) // @parm Numero massimo di pagine che deve avere la maschera { TWait_cursor hourglass; if (max <= 0) max = MAX_PAGES; _source_file = name; _source_file.ext(MASK_EXT); _source_file.lower(); _source_file.custom_path(); TScanner scanner(_source_file); if (num != 0) _mask_num = num; // Salta la maschera principale e quelle degli sheet precedenti a pie' pari for (int i = 0; i < num; i++) { while (scanner.ok()) if (scanner.line() == "ENDMASK") break; } init_mask(); while (scanner.ok() && scanner.popkey() != "EN") { if (scanner.key() == "PA") { read_page(scanner, false); if (_pages >= max) break; } else { if (scanner.key() == "TO") read_page(scanner, true); } } if (_pages <= 0) fatal_box("Impossibile leggere la maschera %s : %d", (const char*)_source_file, num); if (num == 0) { TFilename prof; make_profile_name(prof); if (prof.exist()) { // Costruisce la lista dei gruppi di appartenenza dell'utente const TString_array& uag = user_and_groups(); TConfig ini(prof); FOR_EACH_ARRAY_ROW_BACK(uag, c, rec) { TString utonto = rec->get(0); utonto << "_Locks"; if (ini.set_paragraph(utonto)) { TBit_array read_only; TAuto_token_string lfields(ini.get("Lock")); TAuto_token_string ufields(ini.get("Unlock")); if (ufields.find("*")>=0) { set_locking(read_only, lfields, true); } else { set_locking(read_only, lfields, true); set_locking(read_only, ufields, false); } FOR_EACH_MASK_FIELD((*this), j, f) { if (f->is_loadable()) { const bool ro = read_only[j]; if (f->read_only() != ro) f->set_read_only(ro); } } } } TAssoc_array & defs = ini.list_variables("defaults"); FOR_EACH_ASSOC_STRING(defs, obj, key, str) { short id = atoi(key); const int pos = id2pos(id); if (pos >= 0 && fld(pos).is_operable()) fld(pos).set_default(str); } } } else { // Faccio una prima passata in questa occasione: tuttavia il ciclo // verra' ripetuto nella load checks, nel caso ci siano campi aggiunti dinamicamente FOR_EACH_MASK_FIELD((*this), i, f) if (f->is_edit()) ((TEdit_field*)f)->test_drivers(); } } void TMask::add_field(TMask_field* f) { const long pos = _field.add(f)+1; const short id = f->dlg(); if (id > 0 && id < 512) { if (f->is_sheet()) { for (short cid = 101; cid <= 110; cid++) { if (_position.objptr(cid) && f->parent() == field(cid).parent()) { NFCHECK("Lo sheet %d mal sopporta la convivenza col campo %d", id, cid); break; } } } if (_position.objptr(id)) { if (id > DLG_QUIT) NFCHECK("Il campo %d e' duplicato!", id); } else _position.TArray::add((TObject*)pos, id); } } void TMask::set_tab_buttons(TToken_string& tabs) { int tab = 0; WINDOW nb = notebook(); if (nb == NULL_WIN) nb = create_book(false); FOR_EACH_TOKEN(tabs, title) { if (tab >= _pages) // Se devo creare piu' orecchie che pagine... insert_page(page_win(_pages-1), -1); // ... ripeto l'ultima pagina xvt_notebk_set_tab_title(nb, tab, title); tab++; } } void TMask::set_default_tab_buttons() { TToken_string tabs; TString16 pag; for (int i = 1; i <= _pages; i++) { pag.format(FR("Pag.%d"), i); tabs.add(pag); } set_tab_buttons(tabs); } TMask::TMask(const char* maskname, int num, int max) : _mask_num(num), _sheet(NULL) { if (maskname && *maskname) read_mask(maskname, num, max); } TMask::~TMask() { _field.destroy(); } word TMask::class_id() const { return CLASS_MASK; } bool TMask::is_kind_of(word c) const { if (c == CLASS_MASK) return true; return TWindow::is_kind_of(c); } void TMask::open() { if (!_open || _page != 0) _open = true; if (toolbar() != NULL_WIN) xvt_toolbar_realize(toolbar()); // Non si capisce perche' ce ne sia bisogno, ma tant'e' _focus = first_focus(0); set_focus_field(fld(_focus).dlg()); } int TMask::find_first_active(WINDOW p) const { const int max = fields(); for (int f = 0; f < max; f++) { TMask_field& c = fld(f); if (c.active() && c.parent() == p) return f; } return -1; } int TMask::first_focus(short id, bool dirty) { static int tempfirstfocus = -1; static bool tempdirty = false; int f = _first_focus; if (id == 0) { if (tempfirstfocus >= 0) { f = tempfirstfocus; if (tempdirty && fld(f).dirty() == false) fld(f).set_dirty(); tempfirstfocus = -1; } else { if (f < 0 || !fld(f).active()) { f = find_first_active(curr_win()); if (f < 0 && toolwin() != NULL_WIN) f = find_first_active(toolwin()); if (f < 0 && toolbar() != NULL_WIN) f = find_first_active(toolbar()); } } } else { if (id > 0) { f = _first_focus = id2pos(id); tempfirstfocus = -1; } else { f = tempfirstfocus = id2pos(-id); tempdirty = dirty; } } CHECKD(f >= 0 && f < fields(), "Invalid focus field ", f); return f; } TOperable_field& TMask::focus_field() const { if (is_open()) { const short focus = low_get_focus_id(curr_win()); if (focus > 0 ) ((TMask *)this)->notify_focus_field(focus); } TMask_field & f = fld(_focus); CHECK(f.is_kind_of(CLASS_OPERABLE_FIELD), "A non operable_field has the focus"); return (TOperable_field&)f; } void TMask::set_focus_field(short id) { notify_focus_field(id); if (is_open()) { const TMask_field& f = field(id); int p = _page > 0 ? _page : 0; if (f.parent() != curr_win()) // Controllo se devo cambiar pagina { p = find_parent_page(f); if (p < 0 || p >= _pages || !page_enabled(p)) p = 0; } show_page(p); } } void TMask::notify_focus_field(short id) { const int pos = id2pos(id); CHECKD(pos >= 0, "Can't set focus to field ", id); _focus = pos; } bool TMask::can_be_closed() const { if (is_running()) { bool ok = true; if ((edit_mode() || insert_mode()) && dirty() && id2pos(DLG_QUIT) < 0) ok = yesno_box(TR("Annullare i dati inseriti?")); if (ok) ((TMask*)this)->stop_run(K_FORCE_CLOSE); return false; } return true; // Should never happen! } void TMask::close() { _open = false; _page = -1; xvt_vobj_set_visible(win(), false); } short TMask::dirty() const { const int max = fields(); for (int i = 0; i < max; i++) { const TMask_field& f = fld(i); if (f.dirty() && f.active()) return f.dlg(); } return 0; } void TMask::load_checks() const { const int max = fields(); int i; for (i = 0; i < max; i++) { const TMask_field& f = fld(i); if (f.is_edit()) ((TEdit_field&)f).test_drivers(); } for (i = 0; i < max; i++) { TMask_field& f = fld(i); if (f.has_check()) f.check(STARTING_CHECK); } } // @doc EXTERNAL // @mfunc Abilita/disabilita una pagina e tutte le successive void TMask::enable_page( byte page, // @parm Pagina da abilitare/disabilitare bool on) // @parm Operazione da svolgere: // // @flag true | Abilita la pagina

(default) // @flag false | Disabilita la pagina

{ if (page > 0 && page < _pages) // Non posso spegnere la prima pagina { if (_enabled[page] != on) { CHECK(_notebook, "Can't find an useful notebook"); const short tabs = xvt_notebk_get_num_tabs(_notebook); if (on) { // Riaggiungo i tab buttons (normalmente tabs == page) for (short i = tabs; i < _pages; i++) { _enabled.set(i, true); xvt_notebk_add_page(_notebook, _pagewin[i], NULL, NULL, i); } } else { // Elimino i tab buttons (normalmente tabs == _pages) for (short i = tabs-1; i >= page; i--) { _enabled.set(i, false); xvt_notebk_rem_tab(_notebook, i); } _page = -1; } } } } // Controlla lo stato di abilitazione di una pagina // Certified 99% bool TMask::page_enabled(byte p) const { // First page and toolbars are always enabled const bool on = p == 0 || p >= MAX_PAGES || _enabled[p]; return on; } void TMask::start_run() { const long start = clock(); const int max = fields(); if (_should_check) { TWait_cursor hourglass; load_checks(); for (int i = 0; i < max; i++) { TMask_field& f = fld(i); if (f.dirty() <= 1) // Attenzione puo' valere anche 3 per i very dirty! { f.set_dirty(false); const bool op = f.is_operable() && (f.active() || f.ghost()) && !f.is_kind_of(CLASS_BUTTON_FIELD) && !f.is_kind_of(CLASS_BUTTON_TOOL); if (op) f.on_hit(); // Lancia messaggio di inizializzazione } } } _should_check = true; // Make sure that "nearly" all fields are clean! for (int i = 0; i < max; i++) { TMask_field& f = fld(i); if (f.dirty() == 1) // Attenzione puo' valere anche 3 per i very dirty! f.set_dirty(false); } _last_test = -1; } bool TMask::check_fields() { WINDOW curpage = NULL_WIN; // Page under test const bool sheet = is_sheetmask() && !is_open(); const int max = fields(); for (int i = 0; i < max; i++) { TMask_field& f = fld(i); const bool on = f.active() || (f.shown() && f.is_sheet()); if (on) // Don't test inactive fields { if (f.parent() != curpage) { const int pa = find_parent_page(f); if (!page_enabled(pa)) break; // Page disabled: end of test curpage = f.parent(); // Update current page } if (sheet) f.set_dirty(); // Force check in sheet masks if (f.on_key(K_ENTER) == false) { if (is_open()) set_focus_field(f.dlg()); return false; } } } return true; } void TMask::check_field( short fld_id ) { if (fld_id <= 0) { const int gr = -fld_id; for (int i = fields()-1; i >= 0; i--) { TMask_field& f = fld(i); if (gr == 0 || f.in_group(gr)) { f.on_hit(); f.check(); } } } else { field(fld_id).on_hit(); field(fld_id).check(); } } // @doc EXTERNAL // @mfunc Converte un identificatore di campo nella sua posizione // // @rdesc Ritorna la posizione del campo nella maschera (-1 se non lo trova) int TMask::id2pos( short id) const // @parm Identificatore del campo del quale trovare la posizione // @comm Cerca nella maschera il campo con identificatore

e ne ritorna il numero ordinale // (es. il campo 120 e' il quarto della maschera) { int pos = -1; if (id > 0) { if (id < 512) pos = int(long(_position.objptr(id))-1); else { for (pos = fields()-1; pos >= 0; pos--) if (fld(pos).dlg() == id) break; } } return pos; } TMask_field& TMask::field(short id) const { int pos = id2pos(id); if (pos < 0) { yesnofatal_box("Non esiste il campo %d sulla maschera %s", id, (const char*)_source_file); pos = 0; } return fld(pos); } int TMask::field2pos(const char* fieldname) const { const int id = atoi(fieldname); int i; for (i = fields()-1; i >= 0; i--) { TMask_field& f = fld(i); if (id == 0) { const TFieldref* fr = f.field(); if (fr != NULL && fr->name() == fieldname) break; } else { if (f.dlg() == id) break; } } return i; } TMask_field* TMask::find_by_id(short id) const { const int i = id2pos(id); return i >= 0 ? &fld(i) : NULL; } TMask_field* TMask::find_by_fieldname(const char* fieldname) const { const int i = field2pos(fieldname); return i >= 0 ? &fld(i) : NULL; } TEdit_field& TMask::efield(short id) const { TMask_field& f = field(id); CHECKD(f.is_edit(), "Impossibile trattare come editabile il campo ", id); return (TEdit_field&)f; } TList_field& TMask::lfield(short id) const { TMask_field& f = field(id); CHECKD(f.is_list(), "Impossibile trattare come listbox il campo ", id); return (TList_field&)f; } TSheet_field& TMask::sfield(short id) const { TMask_field& f = field(id); CHECKD(f.is_sheet(), "Impossibile trattare come spreadsheet il campo ", id); return (TSheet_field&)f; } TTree_field& TMask::tfield(short id) const { TMask_field& f = field(id); CHECKD(f.is_kind_of(CLASS_TREE_FIELD), "Impossibile trattare come albero il campo ", id); return (TTree_field&)f; } // @doc EXTERNAL int TMask::find_parent_page(const TMask_field& f) const { return win2page(f.parent()); } // @mfunc Forza la chiusura della maschera // // @rdesc Ritorna il risultato dell'operazione: // // @flag true | E' riuscita a chiudere la maschera // @flag false | Non e' riuscita a chiudere la maschera bool TMask::stop_run( KEY key) // @parm Tasto che deve provocare la chiusura // @comm Permette di chiudere la maschera come se l'utente avesse premuto il tasto

. // Nel caso la maschera non si chiuda (es. un check fallito), ritorna false. { if (key != K_AUTO_ENTER && key != K_FORCE_CLOSE) { const int last = fields(); int i; // Cerca se esiste un bottone avente come exit_key() il tasto key for (i = 0; i < last; i++) { const TMask_field& f = fld(i); if (f.is_operable() && !f.is_editable() && f.active()) { if (f.is_kind_of(CLASS_BUTTON_FIELD)) { const TButton_field& b = (const TButton_field&)f; if (b.exit_key() == key) break; } else if (f.is_kind_of(CLASS_BUTTON_TOOL)) { const TButton_tool& b = (const TButton_tool&)f; if (b.exit_key() == key || b.virtual_key() == key) break; } } } if (i >= last) return false; } if (key == K_CTRL_ENTER || key == K_AUTO_ENTER) key = K_ENTER; else { if (key == K_FORCE_CLOSE) key = (id2pos(DLG_QUIT)<0 && id2pos(DLG_CANCEL)>=0) ? K_ESC : K_QUIT; } if (key != K_ESC && key != K_QUIT && key != K_DEL && key != K_F9) { bool ok = check_current_field(); if (ok) ok = check_fields(); if (ok) { if (id2pos(DLG_PROFILE) >= 0 && field(DLG_PROFILE).hidden()) save_profile(); } else return false; } return TWindow::stop_run(key); } void TMask::on_button(short) { /* Non devo fare niente !!! non essendo una TWindow */ } long TMask::handler(WINDOW w, EVENT* ep) { static TSheet_field* _last_sheet = NULL; if (ep->type == E_MOUSE_DOWN && ep->v.mouse.button == 1) { _last_sheet = NULL; w = curr_win(); for (int f = fields()-1; f >= 0; f--) { TMask_field& cur_fld = fld(f); if (cur_fld.shown() && cur_fld.parent() == w) { RCT rct; cur_fld.get_rect(rct); if (xvt_rect_has_point(&rct, ep->v.mouse.where)) { if (cur_fld.is_kind_of(CLASS_SHEET_FIELD)) _last_sheet = (TSheet_field*)&cur_fld; else cur_fld.on_key(K_F11); break; } } } if (_last_sheet) { MENU_ITEM* menu = xvt_res_get_menu(BROWSE_BAR); if (menu != NULL) { const PNT& p = ep->v.mouse.where; xvt_menu_popup(menu->child, w, p, XVT_POPUP_CENTER, 0); // verificare xvt_res_free_menu_tree(menu); } } return 0L; } if (ep->type == E_COMMAND) { const int tag = ep->v.cmd.tag; if (_last_sheet != NULL) { switch (tag - BROWSE_BAR) { case 1: _last_sheet->save_columns_order(); break; case 2: _last_sheet->reset_columns_order(); break; case 3: _last_sheet->on_key(K_F11); break; case 4: _last_sheet->esporta(); break; default: break; } return 0L; } if (tag == M_HELP_ONCONTEXT) { on_key(K_F1); return 0L; } } if (ep->type == E_VSCROLL) { for (int i = 0; i < fields(); i++) { const TMask_field& ff = fld(i); if (ff._ctl != NULL) { XI_OBJ* obj = ff._ctl->xi_object(); if (obj->type == 11) { const int dir = ep->v.scroll.what == SC_LINE_UP ? -3 : +3; xi_scroll(obj, dir); break; } } } } if (ep->type == E_CONTROL) { if (is_running()) // Scarto a priori gli eventi di inizializzazione { switch (ep->v.ctl.ci.type) { case WC_NOTEBK: if (ep->v.ctl.ci.win == _notebook) { const bool changing = ep->v.ctl.ci.v.notebk.page == NULL_WIN; const int new_page = ep->v.ctl.ci.v.notebk.page_new; if (changing) // Tentativo di cambio pagina { if (new_page != _page && new_page < _pages) { if (_focus >= 0 && find_parent_page(fld(_focus)) != new_page) { if (!check_current_field()) return 1; } } } else { // Cambio pagina avvenuto show_page(new_page); // Forza il focus al primo campo } } break; case WC_ICON: // In realta' trattasi di bottone di toolbar if (ep->v.ctl.ci.win == toolbar()) // Test di sicurezza semi-inutile { TMask_field& tool = field(ep->v.ctl.id); if (tool.active()) tool.on_key(K_SPACE); // Gestisco l'evento di pressione del bottone } break; case WC_HSCROLL: case WC_VSCROLL: if (id2pos(ep->v.ctl.id) < 0) // potrebbero non avere un controllo associato break; // fall down case WC_HSLIDER: case WC_VSLIDER: case WC_PROPGRID: { TMask_field& f = field(ep->v.ctl.id); f.set_focusdirty(); f.on_key(K_SPACE); } break; default: break; } } return 0L; } if (ep->type == E_UPDATE && w == page_win(0)) { if (source_file().find("custom") > 0) { RCT rct; xvt_vobj_get_client_rect(w, &rct); rct.left += 2; rct.right -= 2; rct.bottom -= 2; DRAW_CTOOLS dct; xvt_dwin_get_draw_ctools(w, &dct); dct.fore_color = MASK_BACK_COLOR; dct.back_color = PROMPT_COLOR; dct.opaque_text = TRUE; xvt_dwin_set_draw_ctools(w, &dct); //xvt_dwin_set_font(w, DEF_FONT); xvt_dwin_set_clip(w, NULL); const char* text = "Custom"; const int tw = xvt_dwin_get_text_width(w, text, -1); xvt_dwin_draw_text(w, rct.left, rct.bottom, text, -1); xvt_dwin_draw_text(w, rct.right-tw, rct.bottom, text, -1); } } return TWindow::handler(w, ep); } // @doc EXTERNAL // @mfunc Assegna una azione al tasto non standard // // @rdesc Ritrna se e' stto effetuato una azione: // // @flag true | Era prevista una azione collegata al tasto ed e' stata eseguita // @flag false | Non era prevista nessuna azione collegata al tasto bool TMask::on_key( KEY key) // @parm Tasto premuto sulla maschera // @comm Controlla se il tasto e' tra quelli standard previsti dalla maschera corrente, in caso // contrario ne assegna una azione { if (_handler) { const bool cont = _handler(*this, key); if (!cont) return false; } switch(key) { case K_AUTO_ENTER: case K_CTRL_ENTER: case K_QUIT: case K_ESC: stop_run(key); break; case K_PREV: if (fld(_focus).on_key(K_TAB)) next_page(-1); break; case K_NEXT: if (fld(_focus).on_key(K_TAB)) next_page(+1); break; case K_F1: { const char* key = source_file().name_only(); EVENT e; memset(&e, 0, sizeof(e)); e.type = E_HELP; e.v.help.tag = M_HELP_ONCONTEXT; e.v.help.obj = win(); e.v.help.tid = (long)key; TFilename n = "campo"; TString4 module; module.strncpy(key, 2); module.lower(); if (module != "ba") n.insert(module); FILE_SPEC fs; xvt_fsys_convert_str_to_fspec(n, &fs); XVT_HELP_INFO hi = xvt_help_open_helpfile(&fs, 0); xvt_help_process_event(hi, win(), &e); } break; case K_F12: send_key(K_F12, focus_field().dlg()); break; case K_CTRL+'+': if (is_running()) { // Cerco nella pagina corrente il primo spreadsheet a partire dal campo col focus if (_focus < 0) _focus = 0; const WINDOW myparent = fld(_focus).parent(); for (int fire = _focus; fire < fields(); fire++) { TMask_field& f = fld(fire); if (f.parent() != myparent) break; if (f.is_sheet()) { send_key(key, f.dlg()); break; } } } break; /* case K_CTRL+'-': if (is_running() && focus_field().is_sheet()) send_key(key, focus_field().dlg()); break; */ default: if (key > K_CTRL) { key -= K_CTRL; if (key >= K_F1 && key <= K_F12) { const int page = key - K_F1; if (page < _pages && fld(_focus).on_key(K_TAB)) show_page(page); } else { for (int i = fields()-1; i >= 0; i--) { TMask_field& f = fld(i); if (f.is_operable() && !f.is_editable() && f.active()) { KEY vk = 0; if (f.is_kind_of(CLASS_BUTTON_FIELD)) { TButton_field& b = (TButton_field&)f; vk = b.virtual_key(); } else if (f.is_kind_of(CLASS_BUTTON_TOOL)) { TButton_tool& t = (TButton_tool&)f; vk = t.virtual_key(); } if (vk > 0 && vk == key) { f.on_key(K_SPACE); break; } } } } } } return true; } bool TMask::on_dirty(TMask_field&) { return true; } int TMask::win2page(WINDOW w) const { if (w == toolwin()) return MAX_PAGES; if (w == toolbar()) return MAX_PAGES+1; int p; for (p = _pages-1; p >= 0; p--) if (w == page_win(p)) break; return p; } TMask_field* TMask::parse_field(TScanner& scanner) { const TString& k = scanner.key(); if (k == "BO") return new TBoolean_field(this); if (k == "BR") return new TBrowsefile_field(this); if (k == "BU") return new TButton_field(this); if (k == "CL") return new TGolem_client_field(this); if (k == "CU") return new TCurrency_field(this); if (k == "DA") return new TDate_field(this); if (k == "GO") return new TGolem_field(this); if (k == "GR") return new TGroup_field(this); if (k == "LI") return new TList_field(this); if (k == "ME") return new TMemo_field(this); if (k == "NU") return new TReal_field(this); if (k == "PR") return new TProp_field(this); if (k == "RA") return new TRadio_field(this); if (k == "SL") return new TSlider_field(this); if (k == "SP") return new TSheet_field(this); if (k == "ST") return new TEdit_field(this); if (k == "TE") return new TText_field(this); if (k == "TL") return new TTreelist_field(this); if (k == "TR") return new TTree_field(this); if (k == "ZO") return new TZoom_field(this); return NULL; } TMask_field* TMask::parse_tool(TScanner& scanner) { const TString& k = scanner.key(); if (k == "BU") return new TButton_tool(this); return NULL; } int TMask::sheets() const { int count = 0; for (int f = fields()-1; f >= 0; f--) { if (fld(f).is_sheet()) count++; } return count; } // @doc EXTERNAL // @mfunc Legge la pagina dal file // // @rdesc Ritorna l'handle della finestra creata void TMask::read_page( TScanner& scanner, // @parm File dal quale leggere la pagina bool is_toolbar) // @parm Indica se e' la toolbar // @comm Il parametro

e' utilizzato per indicare se la pagina deve essere visualizzata // a tutto schermo (true) oppure no { const TString title = dictionary_translate(scanner.string()); RCT r; if (!is_toolbar && notebook() != NULL_WIN) // Pagina oltre la prima { scanner.line(); // Scarto rettangolo inutile xvt_rect_set(&r, 0, 0, 0, 0); } else { scanner.rectangle(r.left, r.top, r.right, r.bottom); if (is_toolbar) { if (r.top > 15) // Rendi negative le coordinate delle toolbar per ... r.top -= MAX_MASK_ROWS; // ... ottimizzare l'uso dello schermo ad alta risoluzione } } if (_notebook == NULL_WIN && _single == NULL) // Controlla se la maschera ha piu' di una pagina ... { // ... nel caso serva un notebook per le prossime const streampos pos = scanner.tellg(); // Memorizza posizione dello scanner while (true) { const TString& l = scanner.line(); if (l.empty() || l == "ENDMASK") // Fine maschera break; if (l.starts_with("PA") || l.starts_with("TO")) // Ho trovato un'altra pagina! { if (is_toolbar) create_book(false); // Crea notebook else { //WINDOW w = create_interface(NULL_WIN, r.left, r.top, r.right, r.bottom, title, this); //insert_page(w, 0); // Crea pagina principale const WIN_TYPE wt = (r.right == 0) ? W_PLAIN : W_DOC; const long wsf = WSF_INVISIBLE | WSF_NO_MENUBAR; create(r.left, r.top, r.right, r.bottom, title, wsf, wt); const bool single = l.starts_with("TO"); // Crea sotto-pagina singola o multipla? create_book(single); } break; } } scanner.seekg(pos); // Ripristina posizione dello scanner } WINDOW w = NULL_WIN; if (is_toolbar) { if (r.top == 0) w = create_bar(1); else { CHECKD(r.top < 0, "Bad bottom bar height ", r.top); w = create_bar(r.top); } } else { if (notebook() != NULL_WIN) w = create_page(title, -1); else { if (_single != NULL_WIN) w = _single; else { CHECK(win() == NULL_WIN, "bad page sequence"); w = create_interface(NULL_WIN, r.left, r.top, r.right, r.bottom, title, this); insert_page(w, 0); } } } while (scanner.popkey() != "EN") { TMask_field* f = NULL; if (is_toolbar && r.top == 0) f = parse_tool(scanner); else f = parse_field(scanner); if (f == NULL) { #ifdef DBG const int pf = fields(); TString e; e << "Campo non riconosciuto alla posizione " << pf; if (pf > 0) e << "\nL'ultimo riconosciuto e' " << fld(pf-1).dlg() << ": " << fld(pf-1).prompt(); error_box(e); #endif while (scanner.popkey() != "EN"); } else { f->construct(scanner, w); add_field(f); } } if (is_toolbar && r.top ==0 && _toolbar != NULL_WIN) xvt_toolbar_realize(_toolbar); } bool TMask::check_current_field() const { bool ok = true; if (_focus >= 0) { TMask_field& ff = fld(_focus); if (ff.focusdirty()) ok = ff.on_key(K_TAB); } return ok; } WINDOW TMask::create_book(bool single) { WINDOW parent = win(); if (parent == NULL_WIN) { //parent = create_interface(NULL_WIN, 0, 0, 0, 0, "", this); //set_win(parent); parent = create(0, 0, 0, 0, "", WSF_INVISIBLE|WSF_NO_MENUBAR, W_PLAIN); } if (single) { CHECK(_single == NULL_WIN, "One single page pane, please!"); CHECK(_notebook == NULL_WIN, "Single and notebook?"); _single = create_interface(parent, 0, 0, 0, 0, "", this); xvt_pane_add(parent, _single, "_MainSingle_", 0, 0); _pagewin[0] = _single; _pages = 1; } else { CHECK(_notebook == NULL_WIN, "One single notebook, please!"); CHECK(_single == NULL_WIN, "Notebook and Single?"); XVT_COLOR_COMPONENT xcc[4]; memset(xcc, 0, sizeof(xcc)); xcc[0].type = XVT_COLOR_BACKGROUND; xcc[0].color = MASK_BACK_COLOR; xcc[1].type = XVT_COLOR_FOREGROUND; xcc[1].color = NORMAL_COLOR; WIN_DEF wd; memset(&wd, 0, sizeof(wd)); wd.wtype = WC_NOTEBK; wd.ctlcolors = xcc; wd.v.ctl.flags = CTL_FLAG_TAB_DEFAULT | CTL_FLAG_TAB_TOP; xvt_vobj_get_client_rect(parent, &wd.rct); _notebook = xvt_ctl_create_def(&wd, parent, long(this)); xvt_pane_add(parent, _notebook, "_MainNoteBook_", 0, 0); if (_single != NULL) // Bello ... se solo andasse! { xvt_pane_detach(_single); insert_page(_single, 0); _single = NULL_WIN; } } return single ? _single : _notebook; } void TMask::insert_bar(WINDOW page) { WINDOW parent = win(); CHECK(page != NULL_WIN, "Invalid toolbar"); CHECK(parent != NULL_WIN, "Invalid main window for toolbar"); if (_notebook == NULL_WIN && _single == NULL_WIN) create_book(true); // In assenza di notebook crea un pane a pagina singola RCT rct_win; xvt_vobj_get_outer_rect(parent, &rct_win); RCT rct_bar; xvt_vobj_get_outer_rect(page, &rct_bar); if (rct_bar.top > (rct_win.bottom-rct_win.top)/2) // BottomBar { CHECK(_toolwin == NULL_WIN, "One single bottom bar, please!"); _toolwin = page; xvt_pane_add(parent, _toolwin, "_BottomBar_", 4, 0); // Ammazza la caption e ne blocca le dimensioni xvt_pane_change_flags(page, 0, 1 <<10); // No caption xvt_pane_change_flags(page, 0, 1 << 8); // No resize } else // TopBar { CHECK(_toolbar == NULL_WIN, "One single top bar, please!"); RCT t; xvt_vobj_get_client_rect(TASK_WIN, &t); RCT r; xvt_vobj_get_client_rect(win(), &r); if (r.bottom < t.bottom-2*ROWY) // Ridimensiono maschera piccola (non massimizzata) { const short bar_height = max(rct_bar.bottom - rct_bar.top, TOOL_SIZE + TOOL_TEXT * 12 + 12); RCT rct_new; xvt_vobj_get_client_rect(parent, &rct_new); rct_new.bottom += bar_height; xvt_rect_offset(&rct_new, rct_win.left, rct_win.top-bar_height/2); xvt_vobj_move(parent, &rct_new); } _toolbar = page; xvt_pane_add(parent, _toolbar, "_TopBar_", 62, 0); } } WINDOW TMask::create_bar(int height) { WINDOW w = NULL_WIN; if (height < 0) w = create_interface(win(), 0, height, 0, 0, "", this); // Bottom bar else { const long flags = TOOL_TEXT ? CTL_FLAG_PASSWORD : 0; w = xvt_toolbar_create(-1, 0, 0, -1, TOOL_SIZE, flags, win()); // Top bar XVT_COLOR_COMPONENT cc[4]; memset(cc, 0, sizeof(cc)); cc[0].type = XVT_COLOR_BLEND; cc[0].color = MASK_BACK_COLOR; cc[1].type = XVT_COLOR_FOREGROUND; cc[1].color = PROMPT_COLOR; xvt_ctl_set_colors(w, cc, XVT_COLOR_ACTION_SET); XVT_IMAGE txt = get_background_texture(); if (txt != NULL) xvt_ctl_set_texture(w, txt); } insert_bar(w); // Inserisce toolbar e crea notebook, se necessario return w; } void TMask::insert_page(WINDOW page, int dove) { CHECKD(dove >= -1 && dove <= _pages, "Invalid page position:", dove); // Per le pagine dopo la prima devo creare il notebook if (_pages == 1 && _notebook == NULL_WIN) create_book(false); memset(_pagewin, 0, sizeof(_pagewin)); // Azzero lista pagine if (_notebook != NULL_WIN) // property sheet { xvt_notebk_add_page(_notebook, page, NULL, NULL, dove); _pages = xvt_notebk_get_num_tabs(_notebook); // Ricostruisco lista pagine for (short p = 0; p < _pages; p++) _pagewin[p] = xvt_notebk_get_page(_notebook, p); } else // single page { CHECK(win() == NULL_WIN, "One single main page, please!"); set_win(page); _pagewin[0] = page; // Assegno la prima ed unica pagina _pages = 1; } } WINDOW TMask::create_page(const char* title, int dove) { CHECKD(dove < 0 || dove < MAX_PAGES, "invalid page position ", dove); WINDOW w = create_interface(notebook(), 0, 0, 0, 0, title, this); insert_page(w, dove); return w; } void TMask::set_focus() { TWindow::set_focus(); WINDOW w = curr_win(); if (w != win()) // Succede se ci sono notebook o toolbar { xvt_scr_set_focus_vobj(w); xvt_vobj_raise(w); } } // @doc EXTERNAL // @mfunc Mostra la prossima/precedente pagina void TMask::next_page( int p) // @parm Pagina alla quale saltare // @comm Il valore

puo' assumere i seguenti valori: // // @flag -1 | Mostra la pagina precedente // @flag 0 | Mostra la pagina corrente // @flag +1 | Mostra la pagina successiva // @flag 1000+n | Mostra la pagina n-esima { const int prev = _page; // Previous page if (p != 0) { const int k = (p < 1000) ? _page+p : p-1000; if (k < 0 || k >= _pages || !page_enabled(k)) { beep(); return; } _page = k; } else { if (_page < 0 || _page >= _pages) _page = 0; } if (_page != prev) { xvt_vobj_set_visible(win(), true); if (notebook() != NULL) xvt_notebk_set_front_page(notebook(), _page); } if (_focus < 0 || fld(_focus).parent() != curr_win() || !fld(_focus).active()) { _focus = find_first_active(curr_win()); if (_focus < 0 && toolwin() != NULL_WIN) _focus = find_first_active(toolwin()); if (_focus < 0 && toolbar() != NULL_WIN) _focus = find_first_active(toolbar()); } set_focus(); if (_focus >= 0) { TMask_field& ff = fld(_focus); if (ff.active()) ff.highlight(); } } void TMask::show_page(int p) { CHECKD(p >= 0 && p < _pages, "Pagina errata ", p); next_page(1000 + p); } void TMask::reset(short fld_id) { if (fld_id <= 0) { const int gr = -fld_id; FOR_EACH_MASK_FIELD(*this, i, c) if (gr == 0 || c->in_group(gr)) { c->reset(); c->set_dirty(false); } } else field(fld_id).reset(); } const TString& TMask::get(short fld_id) const { const TString& s = field(fld_id).get(); return s; } const TString& TMask::get(const char * fld_id) const { const TString * s = &EMPTY_STRING; for (int i = 0 ; i < fields(); i++) { TMask_field& f = fld(i); const TFieldref * campo = f.field(); if (campo != NULL && campo->name() == fld_id) { s= &f.get(); if (f.active()) break; } } return *s; } long TMask::get_long(short fld_id) const { const TString& s = get(fld_id); return atol(s); } bool TMask::get_bool(short fld_id) const { const TString& s = get(fld_id); return s.full() && s != "0"; } real TMask::get_real(short fld_id) const { const TString& s = get(fld_id); return real(s); } TDate TMask::get_date(short fld_id) const { const TString& s = get(fld_id); return TDate(s); } TCurrency& TMask::get_currency(short fld_id, TCurrency& c) const { const TMask_field& cf = field(fld_id); if (cf.class_id() == CLASS_CURRENCY_FIELD) { ((TCurrency_field&)cf).get_currency(c); } else { const real n(cf.get()); c.force_value(""); c.set_num(n); } return c; } // @doc EXTERNAL // @mfunc Setta il campo con un valore void TMask::set( short fld_id, // @parm Identificatore del campo da settare const char* s, // @parm Stringa da assegnare al campo byte hit) // @parm Indica se occorre rifare i controlli una volta settato il campo // con il nuovo valore (default false) // @parm long | n | Numero da asegnare al campo // @syntax set(short fld_id, const char *s, bool hit); // @syntax set(short fld_id, long n, bool hit); { TMask_field& f = field(fld_id); f.set(s); if ((f.active() || f.ghost())) { f.set_dirty(); if (hit & 0x2) f.check(); if (hit & 0x1) f.on_hit(); } } void TMask::set( const char * fld_id, // @parm FIELD del campo da settare const char* str, // @parm Stringa da assegnare al campo byte hit) // @parm Indica se occorre rifare i controlli una volta settato il campo // con il nuovo valore (default false) // @parm long | n | Numero da asegnare al campo // @syntax set(short fld_id, const char *s, bool hit); // @syntax set(short fld_id, long n, bool hit); { for (int i = 0 ; i < fields(); i++) { TMask_field& f = fld(i); const TFieldref * campo = f.field(); if (campo != NULL && campo->name() == fld_id) set(f.dlg(), str, hit); } } void TMask::set(short fld_id, long n, byte hit) { TString16 s; s << n; set(fld_id, s, hit); } void TMask::set(short fld_id, const real& n, byte hit) { CHECK(id2pos(fld_id) < 0 || field(fld_id).is_edit(), "Can't set a real value in a non edit field"); set(fld_id, n.string(), hit); } void TMask::set(short fld_id, const TDate& d, byte hit) { CHECK(id2pos(fld_id) < 0 || field(fld_id).is_kind_of(CLASS_DATE_FIELD), "Can't set a date in a non-date field"); set(fld_id, d.string(), hit); } void TMask::set(short fld_id, const TCurrency& n, byte hit) { CHECK(field(fld_id).is_kind_of(CLASS_CURRENCY_FIELD), "Can't set a currency in a non-currency field"); // CHECK(id2pos(fld_id) < 0 || field(fld_id).is_edit(), "Can't set a currency in a non edit field"); set(fld_id, n.get_num().string(), hit); } // @doc EXTERNAL // @mfunc Permette di attivare/disattivare tutta la maschera void TMask::activate( bool on) // @parm Indica l'operazione da svolgere sul campo: // // @flag true | Attiva la pagina(default) // @flag false | Disattiva la pagina { TWindow::activate(on); // Maschera vecchia e decrepita senza toolbar: nascondo i bottoni if (toolwin() != NULL_WIN && toolbar() == NULL_WIN) xvt_vobj_set_visible(toolwin(), on); } // @doc EXTERNAL // @mfunc Abilita/disabilita un campo void TMask::enable( short fld_id, // @parm Identificatore del campo da abilitare (0 tutti i campi, <0 id gruppo) bool on) // @parm Indica l'operazione da svolgere sul campo: // // @flag true | Abilita il campo (default) // @flag false | Disabilita il campo { if (fld_id <= 0) { const int gr = -fld_id; for (int i = fields()-1; i >= 0; i--) { TMask_field& f = fld(i); if (gr == 0 || f.in_group(gr)) f.enable(on); } } else field(fld_id).enable(on); } void TMask::enable_default(short fld_id) { if (fld_id <= 0) { const int gr = -fld_id; for (int i = fields()-1; i >= 0; i--) { TMask_field& f = fld(i); if (gr == 0 || f.in_group(gr)) f.enable_default(); } } else field(fld_id).enable_default(); } word TMask::num_keys() const { word max = 0; for (int i = fields()-1; i >= 0; i--) { const TMask_field& f = fld(i); if (f.is_editable()) { word k = ((const TEditable_field&)f).last_key(); if (k > max) max = k; } } return max; } // @doc EXTERNAL // @mfunc Abilita/disabilita i campi di una chiave sulla maschera void TMask::enable_key( word key, // @parm Chiave di cui abilitare il campo bool on) // @parm Indica l'operazione da svolgere sul tasto: // // @flag true | Abilita il campo (default) // @flag false | Disabilita il campo { for (int i = fields()-1; i >= 0; i--) { TMask_field& f = fld(i); if (f.in_key(key)) { if (on) { f.enable_default(); if (!f.shown()) f.show_default(); } else f.disable(); } } } // @doc EXTERNAL // @mfunc Ritorna il l'identificatore di un campo della chiave

// // @rdesc Ritorna l'identificatore del campo cercato TEditable_field* TMask::get_key_field( word key, // @parm Chiave di cui controllare l'esistenza bool first) const // @parm Indica se la ricerca dev partire dell'inizio. Assume i valori: // // @flag true | Comincia la ricerca dal primo campo della maschera // @flag false | Comincia la ricerca dal campo attuale nella maschera { static int last = 0; if (first) last = 0; const int max = fields(); for (int i = last; i < max; i++) { TMask_field& f = fld(i); if (f.in_key(key)) { last = i+1; return (TEditable_field*)&f; } } return NULL; } bool TMask::key_valid(word key) const { const int maxflds = fields(); bool full = false; for (int f = 0; f < maxflds; f++) { TMask_field& c = fld(f); if (c.is_editable() && c.shown() && c.in_key(key)) { if (c.empty()) { if (c.required()) return false; } else full = true; } } return full; } // @doc EXTERNAL // @mfunc Permette di mostrare/nascondere un campo void TMask::show( short fld_id, // @parm Campo da mostrare/nascondere (default -1) bool on) // @parm Indica l'operazione da svolgere sul campo: // // @flag true | Mostra il campo(default) // @flag false | Nasconde il campo // @comm Se

e' -1 allora permette di operare su tutti i campi della maschera { if (fld_id <= 0) { const int gr = -fld_id; for (int i = fields()-1; i >= 0; i--) { TMask_field& f = fld(i); if (gr == 0 || f.in_group(gr)) f.show(on); } } else field(fld_id).show(on); } // @doc EXTERNAL // @mfunc Rimette lo stato di default del campo void TMask::show_default( short fld_id) // @parm Identificatore del campo da risettare (default -1) // @comm Se

Assume il valore -1 vuole dire che vengono risettati tutti i campi della amschera { if (fld_id <= 0) { for (int i = fields()-1; i >= 0; i--) fld(i).show_default(); } else field(fld_id).show_default(); } void TMask::autoload(const TRelation& r) { FOR_EACH_MASK_FIELD((*this), i, f) if (f->is_loadable()) ((TLoadable_field*)f)->autoload(r); } void TMask::autosave(TRelation& r) const { FOR_EACH_MASK_FIELD((*this), i, f) if (f->is_loadable()) { bool save = f->shown(); if (!save && f->is_editable()) { // tenta di effettuare il save dei campi Edit hidden: // salva il nuovo valore solo se il precedente era blank if (f->field() != NULL) { const char* str = f->field()->read(r); save = *str == '\0'; } } if (save) ((TLoadable_field*)f)->autosave(r); } } void TMask::on_firm_change() { TString16 firm; firm << prefix().get_codditta(); for (int i = fields()-1; i >= 0; i--) { TMask_field& f = fld(i); if (f._flags.firm) { f.set(firm); f.check(STARTING_CHECK); f.on_hit(); } } } void TMask::on_idle() { if (_focus >= 0 && _focus < fields()) { if (fld(_focus).is_operable()) { TOperable_field& s = (TOperable_field&)fld(_focus); s.on_idle(); if (_msg_field > 0) { TMask_field& f = field(_msg_field); _msg_field = 0; if (_msg_key > 0) f.on_key(_msg_key); } } if (_error_severity > 0) { const int es = _error_severity; // Memorizzo per azzerare subito _error_severity = 0; set_focus(); if (ADVANCED_GRAPHICS && ANIMATED_BOXES) { switch(es) { case 2: xvt_dm_popup_warning(_error_message); break; case 3: xvt_dm_popup_error (_error_message); break; default: xvt_dm_popup_message(_error_message); break; } } else { switch(es) { case 2: xvt_dm_post_warning(_error_message); break; case 3: xvt_dm_post_error (_error_message); break; default: xvt_dm_post_message(_error_message); break; } } } if (_test_fld >= 0) { const TOperable_field & f = focus_field(); if (_last_test != f.dlg()) { TEditable_field & e = (TEditable_field &)field(_test_fld); if (!f.in_key(0) || !e.has_a_common_key(f)) { e.test_key_complete(false); _test_fld = -1; } _last_test = f.dlg(); } } } } // @doc EXTERNAL // @mfunc Permette di mandare un tasto ad un campo void TMask::send_key( KEY key, // @parm Codice del tasto da spedire short to, // @parm Identificatore del campo che deve ricevere TMask_field* from) // @parm Campo che spedisce il tasto { if (to == 0) { WINDOW w = from ? from->parent() : win(); dispatch_e_char(w, key); return; } if (to > 0) { if (to == DLG_PAGE) { CHECK(from, "You should specify a sender!"); const int p = find_parent_page(*from)+1; CHECKD(p > 0 && p < _pages, "You should specify a good page, not ", p); key -= K_CTRL+K_SHIFT; enable_page(p, key == 's' || key == 'e'); } else { const int pos = id2pos(to); if (pos >= 0) { if (_msg_field > 0) on_idle(); _msg_field = to; _msg_key = key; } #ifdef DBG else NFCHECK("Can't send key %u to field %d", key, to); #endif } } else { const int gr = -to; for (int i = fields()-1; i >= 0; i--) { TMask_field& campo = fld(i); if (campo.in_group(gr)) campo.on_key(key); } } } // @doc EXTERNAL // @mfunc Permette di mandare un handler ad controllo o ad una maschera void TMask::set_handler( short fld_id, // @parm Identificatere del campo che deve ricevere l'handler CONTROL_HANDLER handler) // @parm Handler da spedire al campo // @parm MASK_HANDLER | handler | Handler da spedire alla maschera // @syntax set_handler(short fld_id, CONTROL_HANDLER handler); // @syntax set_handler(MASK_HANDLER handler); // // @comm Nel primo caso viene mandato un al campo indicato // da

, mentre nel secondo viene mandato un // alla maschera corrente { TMask_field& f = field(fld_id); CHECKD(f.is_operable(), "Can't set an handler to non-operable field ", fld_id); ((TOperable_field&)f).set_handler(handler); } void TMask::set_handler(MASK_HANDLER handler) { _handler = handler; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo testo alla maschera // // @rdesc Ritorna l'handle del campo creato TMask_field& TMask::add_static ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) const char* flags) // @parm Flag di controllo del campo (deafult "") // @xref // { TText_field* f = new TText_field(this); f->construct(id, prompt, x, y, 0, page_win(page), flags); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo stringa alla maschera // // @rdesc Ritorna l'handle del campo creato TEdit_field& TMask::add_string ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dim, // @parm Lunghezza del campo sulla maschera const char* flags, // @parm Flag di controllo del campo (defailt "") int width) // @parm Lunghezza totale del campo stringa (default 0) // @xref // { TEdit_field* f = new TEdit_field(this); f->construct(id, prompt, x, y, dim, page_win(page), flags, width); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo bottone alla maschera // // @rdesc Ritorna l'handle del campo creato TButton_field& TMask::add_button ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dx, // @parm Larghezza del campo (in caratteri, default 9) int dy, // @parm Altezza del campo (in caratteri, default 1) const char* flags, // @parm Flag di controllo del campo (default "") short bmpup, // @parm Icona normale short bmpdn) // @parm Icona premuta // @xref // { TButton_field* f = new TButton_field(this); f->construct(id, prompt, x, y, dy, page_win(page), flags, dx, bmpup, bmpdn); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo boolean alla maschera // // @rdesc Ritorna il descrittore del campo aggiunto TBoolean_field& TMask::add_boolean ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) const char* flags) // @parm Flag di controllo del campo (default "") // @xref // { TBoolean_field* f = new TBoolean_field(this); f->construct(id, prompt, x, y, strlen(prompt), page_win(page), flags); add_field(f); return *f; } TCheckbutton_field& TMask::add_checkbutton ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dx, // @parm Larghezza del campo (in caratteri, default 9) int dy, // @parm Altezza del campo (in caratteri, default 1) const char* flags, // @parm Flag di controllo del campo (default "") short bmpup, // @parm Icona normale short bmpdn) // @parm Icona premuta // @xref // { TCheckbutton_field* f = new TCheckbutton_field(this); f->construct(id, prompt, x, y, dy, page_win(page), flags, dx); if (bmpup > 0) ((TCheckbutton_control*)f->_ctl)->set_icon(bmpup, bmpdn); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo numerico alla maschera // // @rdesc Ritorna l'handle del campo creato TReal_field& TMask::add_number ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dim, // @parm Lunghezza del campo sulla maschera const char* flags, // @parm Flag di controllo del campo (default "") int ndec) // @parm Numero di decimali (default 0) // @xref // { TReal_field* f = new TReal_field(this); f->construct(id, prompt, x, y, dim, page_win(page), flags, ndec); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo importo alla maschera // // @rdesc Ritorna l'handle del campo creato TCurrency_field& TMask::add_currency ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dim, // @parm Lunghezza del campo sulla maschera const char* flags, // @parm Flag di controllo del campo (default "") short driver) // @parm Campo con codice valuta // @xref // { TCurrency_field* f = new TCurrency_field(this); f->construct(id, prompt, x, y, dim, page_win(page), flags, 0); if (driver != 0) f->add_driver(driver); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo data alla maschera // // @rdesc Ritorna l'handle del campo creato TDate_field& TMask::add_date ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) const char* flags) // @parm Flag di controllo del campo (default "") // @xref // { TDate_field* f = new TDate_field(this); f->construct(id, prompt, x, y, 10, page_win(page), flags); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo lista alla maschera // // @rdesc Ritorna l'handle del campo creato TList_field& TMask::add_list ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dim, // @parm Lunghezza del campo sulla maschera const char* flags, // @parm Flag di controllo del campo (default "") const char* codes, // @parm tokenstring con i codici (NULL def.) const char* items) // @parm tokenstring con gli items (NULL def.) // @xref // { TList_field* f = new TList_field(this); f->construct(id, prompt, x, y, dim, page_win(page), flags); f->replace_items(codes,items); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo radio button alla maschera // // @rdesc Ritorna l'handle del campo creato TRadio_field& TMask::add_radio( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dx, // @parm Larghezza del campo (in caratteri) const char* codes, // @parm Array di codici delle voci const char* items, // @parm Array di prompt delle voci const char* flags) // @parm Flag di controllo del campo (default "") // @xref // { TRadio_field* f = new TRadio_field(this); f->replace_items(codes, items); f->construct(id, prompt, x, y, dx, page_win(page), flags, dx); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo zoom alla maschera // // @rdesc Ritorna l'handle del campo creato TZoom_field& TMask::add_zoom ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dim, // @parm Lunghezza del campo sulla maschera const char* flags, // @parm Flag di controllo del campo (defailt "") int width) // @parm Lunghezza totale del campo stringa (default 0) // @xref // { TZoom_field* f = new TZoom_field(this); f->construct(id, prompt, x, y, dim, page_win(page), flags, width); add_field(f); return *f; } // @doc EXTERNAL // @mfunc Aggiunge runtime un campo memo alla maschera // // @rdesc Ritorna l'handle del campo creato TMemo_field& TMask::add_memo( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dx, // @parm Larghezza del campo (in caratteri, deafilt 78) int dy, // @parm Altezza del campo (in caratteri, default 4) const char* flags) // @parm Flag di controllo del campo (default "") // @xref // { TMemo_field* f = new TMemo_field(this); f->construct(id, prompt, x, y, dy, page_win(page), flags, dx); add_field(f); return *f; } TTree_field& TMask::add_tree ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dx, // @parm Larghezza del campo sulla maschera int dy, // @parm Altezza del campo sulla maschera const char* flags)// @parm Flag di controllo del campo (default "") { TTree_field* f = new TTree_field(this); f->construct(id, "", x, y, dy, page_win(page), flags, dx); add_field(f); return *f; } TGroup_field& TMask::add_groupbox ( short id, // @parm Numero identificatore del campo da aggiungere int page, // @parm Pagina nel quale aggiungere il campo const char* prompt, // @parm Prompt del campo int x, // @parm Coordinata x (in caratteri) int y, // @parm Coordinata y (in caratteri) int dx, // @parm Larghezza del campo sulla maschera int dy, // @parm Altezza del campo sulla maschera const char* flags)// @parm Flag di controllo del campo (default "") { TGroup_field* f = new TGroup_field(this); f->construct(id, prompt, x, y, dy, page_win(page), flags, dx); add_field(f); return *f; } TButton_tool& TMask::add_button_tool(short id, const char* prompt, short bmpup) { if (toolbar() == NULL_WIN) // Se non c'e' ancora la toolbar, me l'invento adesso create_bar(1); CHECKD(id <= 0 || bmpup > 0, "Toolbar button needs a wonderful icon ", id); TButton_tool* t = new TButton_tool(this); t->construct(id, prompt, 0, 0, 0, toolbar(), "", 0, bmpup, 0); add_field(t); return *t; } // @doc EXTERNAL // @mfunc Salva i valori dei campi della maschera sul file di salvataggio // // @rdesc Ritorna il risultato dell'operazione: // // @flag true | Se l'operazione e' avvenuta corretamente // @flag false | Se non si riesce a creare il file di salvataggio bool TMask::save( bool append) const // @parm Indica se creare il file o appendere (true) le informazioni // ad uno gia' esistente (false, default). { FILE* f = fopen(_workfile, append ? "a" : "w"); if (f == NULL) return yesnofatal_box("Non posso aprire %s ", (const char*) _workfile); const int max = fields(); for (int i = 0; i < max; i++) { TMask_field& c = fld(i); if (c.is_editable()) fprintf(f, "%d|%s\n", c.dlg(), (const char*)c.get()); } fprintf(f, "[EOM]\n"); fclose(f); return true; } // @doc EXTERNAL // @mfunc Legge i valori dei campi della maschera da file di salvataggioo // // @rdesc Ritorna il risultato dell'operazione: // // @flag true | Se l'operazione e' avvenuta corretamente // @flag false | Se non si riesce a leggere il file di salvataggio bool TMask::load( bool reset) // @parm Indica la posizione di lettura del file: // // @flag true | Comincia la lettura dell'inizio // @flag false | Comincia la lettura dalla posizione corrente dell'offset { FILE* f = fopen(_workfile, "r"); if (f == NULL) return false; if (reset) _lastpos = 0; fseek(f, _lastpos, SEEK_SET); TToken_string t(256); char* buffer = t.get_buffer(); while (fgets(buffer, t.size(), f) != NULL && t != "[EOM]") { if (t.not_empty()) { t.rtrim(); const int pos = id2pos(t.get_int(0)); if (pos >= 0) fld(pos).set(t.get()); } } _lastpos = ftell(f); fclose(f); return true; } // @doc EXTERNAL // @mfunc Copia i valori dei campi dalla maschera

// void TMask::copy_values( const TMask& m) // @parm Maschera sorgente { reset(); const int nfields = fields(); for (int i = 0; i < nfields; i++) { TMask_field& dest_field = fld( i ); if (dest_field.is_editable() ) { const int pos = m.id2pos(dest_field.dlg()); if (pos >= 0) { const TMask_field& source_field = m.fld(pos); dest_field.set( source_field.get( ) ); } } } } bool TMask::make_profile_name(TFilename& f) const { f = source_file().name(); f.ext("ini"); if (!f.custom_path()) // Prova a cercare la configurazione in custom ... { // ... altrimenti riprova in config f =::firm2dir(-1); // Directory dati f.add("config"); // Directory config f.add(source_file().name()); // Nome Maschera f.ext("ini"); // Estensione } return f.exist(); } int TMask::save_profile(int num, const char* desc) const { TFilename prof; make_profile_name(prof); TConfig ini(prof, "Main"); if (num == 0) num = ini.get_int(user()); if (num <= 0) { TString_array p; TBit_array b(256); b.set(255); b.set(); b.reset(0L); ini.list_paragraphs(p); FOR_EACH_ARRAY_ROW_BACK(p, r, row) { num = atoi(*row); if (num > 0) b.reset(num); } num = int(b.first_one()); } TString16 para; para << num; ini.set(user(), para); TString description = desc; if (ini.set_paragraph(para)) { if (description.blank()) description = ini.get("Description"); ini.remove_all(); } else { if (description.blank()) description << "Profilo standard per " << user(); } ini.set("Description", description); TString16 name; for (int i = 0; i < fields(); i++) { TMask_field& f = fld(i); if (f.is_loadable() && f.get_default().empty()) { name.format("F_%d", f.dlg()); if (f.is_sheet()) { TSheet_field& s = (TSheet_field&)f; FOR_EACH_SHEET_ROW(s, r, row) ini.set(name, *row, NULL, true, r); } else { if (!f.is_firm()) ini.set(name, f.get()); } } } return num; } int TMask::load_profile(int num, bool reset) { TFilename prof; if (make_profile_name(prof)) { TConfig ini(prof, "Main"); if (num <= 0) num = ini.get_int(user()); else ini.set(user(), num); TString16 name; name << num; TAssoc_array& var = ini.list_variables(name); if (var.items() > 0) { for (int pos = fields()-1; pos >= 0; pos--) { TMask_field& f = fld(pos); if (f.is_loadable() && f.get_default().empty()) { name.format("F_%d", f.dlg()); if (reset || var.objptr(name) != NULL) { if (f.is_sheet()) { TSheet_field& sf = (TSheet_field&)f; sf.destroy(); for (int r = 0; ini.exist(name,r); r++) sf.row(r) = ini.get(name, NULL, r); sf.force_update(); } else { if (!f.is_firm()) f.set(ini.get(name)); } } } } } } return num; } bool TMask::kill_profile(int num) { TFilename prof; make_profile_name(prof); TConfig ini(prof, "Main"); if (num <= 0) num = ini.get_int(user()); TString8 name; name << num; const bool ok = ini.set_paragraph(name); if (ok) ini.remove_all(); return ok; } void TMask::load_defaults() { for (int pos = 0; pos < fields(); pos++) { TMask_field& f = fld(pos); if (f.is_loadable()) { const TString & def = f.get_default(); if (def.full()) f.set(def); } } } const char* TMask::get_caption(TString& str) const { char* title = str.get_buffer(128); xvt_vobj_get_title(win(), title, str.size()); return title; } void TMask::set_caption(const char* c) { TToken_string captions(c); if (_notebook != NULL_WIN) { for (int p = 0; p < _pages; p++) { const char* title = captions.get(); if (title == NULL) title = captions.get(0); xvt_notebk_set_tab_title(_notebook, p, title); } } else xvt_vobj_set_title(win(), captions.get(0)); } void TMask::post_error_message(const char* msg, int sev) { CHECK(sev > 0 && msg, "Bad error message posted"); if (_error_severity > 0) // C'e' gia' un messaggio d'errore in coda on_idle(); _error_message = msg; _error_severity = sev; } // @doc INTERNAL // @mfunc costruttore di copia TTimed_box::TTimed_box(const char * header,const char * message,int seconds,short button_id,int x,int y) : TMask(header,1,x,y) { // costruisce una maschera run time TMemo_field& m = add_memo(DLG_USER, 0, "", 1, 0,-1,-3); m.set(message); // setta il timer per l'evento _timer_delay=seconds * 1000 + 1; _timer_id=XVT_TIMER_ERROR; _button_id=button_id; } void TTimed_box::start_run() { if (_timer_id!=XVT_TIMER_ERROR) xvt_timer_destroy(_timer_id); _timer_id=xvt_timer_create(win(),_timer_delay); TMask::start_run(); } long TTimed_box::handler(WINDOW win, EVENT* ep) { if (ep->type == E_TIMER && ep->v.timer.id==_timer_id) send_key(K_SPACE, _button_id); return TMask::handler(win, ep); } TTimed_box::~TTimed_box() { if (_timer_id != XVT_TIMER_ERROR) xvt_timer_destroy(_timer_id); } TTimed_breakbox::TTimed_breakbox(const char * message,int seconds,int x,int y) : TTimed_box(TR("Richiesta di interruzione"),message,seconds,DLG_OK,x,y) { add_button(DLG_CANCEL, 0, TR("Interrompi"), -22, -1, 12, 2,"",0); add_button(DLG_OK, 0, TR("Riprova"), -12, -1, 12, 2,"",0); } TTimed_breakbox::~TTimed_breakbox() {} // @doc INTERNAL // @mfunc costruttore di copia TYesnoallnone_box::TYesnoallnone_box(const char * message, int default_key) : TMask(TR("Richiesta"),1,40,8) { // costruisce una maschera run time add_memo(FIRST_FIELD, 0, "", 1, 0,-1,-3); set(FIRST_FIELD, message); disable(FIRST_FIELD); add_button(DLG_OK, 0, TR("Tutti"), -14, -1, 8, 2,"",0); add_button(FIRST_FIELD+1, 0, TR("Si"), -24, -1, 8, 2,"",0).set_exit_key(K_YES); add_button(FIRST_FIELD+2, 0, TR("No"), -34, -1, 8, 2,"",0).set_exit_key(K_NO); add_button(DLG_CANCEL, 0, TR("Nessuno"), -44, -1, 8, 2,"",0); switch (default_key) { case K_ENTER: first_focus(DLG_OK); break; case K_ESC: first_focus(DLG_CANCEL); break; case K_NO: first_focus(FIRST_FIELD+2); break; default: first_focus(FIRST_FIELD+1); } } TYesnoallnone_box::~TYesnoallnone_box() {}