From 00a6c5fb6104241541b67ba16519d59ee078eed4 Mon Sep 17 00:00:00 2001 From: guy Date: Mon, 30 Jan 1995 13:46:06 +0000 Subject: [PATCH] Aggiornato help ipertestuale e abilitata voce stampa del menu in ba3 git-svn-id: svn://10.65.10.50/trunk@935 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/mask.cpp | 2760 +++++++++++++++++++++---------------------- include/maskfld.cpp | 5 +- include/tabapp.cpp | 5 +- 3 files changed, 1386 insertions(+), 1384 deletions(-) diff --git a/include/mask.cpp b/include/mask.cpp index 12582feec..dfff81151 100755 --- a/include/mask.cpp +++ b/include/mask.cpp @@ -1,1380 +1,1380 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define NULL_PAGE 256 - -HIDDEN const char* const MASK_EXT = "msk"; - -/////////////////////////////////////////////////////////// -// TMask methods -/////////////////////////////////////////////////////////// - -HIDDEN bool moving_focus = FALSE; - - -bool TMask::test_focus_change(WINDOW next) -{ - bool ok = TRUE; - - TMask_field& prev = fld(_focus); - if (prev.win() != next) - { - ok = prev.test_focus_change(); - if (!ok) // Test if previous field agrees ... - { - set_focus(); - prev.set_focusdirty(FALSE); - } - } - return ok; -} - -void TMask::control_handler(EVENT* ep) -{ - const WINDOW win = ep->v.ctl.ci.win; - const WIN_TYPE type = ep->v.ctl.ci.type; - - TMask_field* f = (TMask_field*)get_app_data(win); - CHECK(f != NULL, "Invalid field pointer in control"); - - if (type == WC_CHECKBOX) - { - if (test_focus_change(win)) - { - xvt_check_box(win, !xvt_get_checked_state(win)); - set_focus_win(win, FALSE); - f->on_key(K_SPACE); - } - return; - } - - if (type == WC_RADIOBUTTON) - { - if (moving_focus == FALSE) - { - if (test_focus_change(win)) - { - ((TRadio_field*)f)->check_radiobutton(win); - set_focus_win(win, FALSE); - f->on_key(K_SPACE); - } - } else moving_focus = FALSE; - return; - } - - if (type == WC_PUSHBUTTON) - { - if (test_focus_change(win)) - { - set_focus_win(win, FALSE); - f->on_hit(); - } - return; - } - - if (type == WC_LISTBUTTON) - { - if (test_focus_change(win)) - { - set_focus_win(win, FALSE); - f->on_key(K_SPACE); - } - return; - } - - if (ep->v.ctl.ci.v.edit.focus_change) - { - if (ep->v.ctl.ci.v.edit.active) - { - if (test_focus_change(win)) - { - set_focus_win(win, FALSE); - f->set_focusdirty(FALSE); - } - } - } - else - { // Contents of control were changed - f->on_key(K_SPACE); - } -} - -void TMask::handler(WINDOW win, EVENT* ep) -{ - switch (ep->type) - { - case E_UPDATE: -#if XVT_OS == XVT_OS_WIN - if (win != toolwin()) - { - clear_window(win, MASK_BACK_COLOR); - RCT r; get_client_rect(win, &r); r.right--; r.bottom--; - xvt_draw_rect(win, r, MASK_LIGHT_COLOR, MASK_DARK_COLOR, 1); - } - else clear_window(win, MASK_DARK_COLOR); -#else - clear_window(win, MASK_BACK_COLOR); -#endif - update(); - return; - case E_COMMAND: - if (ep->v.cmd.tag == M_FILE_NEW) - on_firm_change(); - break; - case E_CONTROL: - switch(ep->v.ctl.id) - { - case DLG_OK: - if (test_focus_change(ep->v.ctl.ci.win)) - stop_run(K_AUTO_ENTER); - break; - case DLG_CANCEL : - if (test_focus_change(ep->v.ctl.ci.win)) - stop_run(K_ESC); - break; - case DLG_QUIT : - if (test_focus_change(ep->v.ctl.ci.win)) - stop_run(K_FORCE_CLOSE); - break; - case DLG_F9: - { - WINDOW w = ep->v.ctl.ci.win; - TMask_field* f = (TMask_field*)get_app_data(w); - w = f->win(); - if (test_focus_change(w)) - f->on_key(K_F9); // Attiva ricerca sul campo associato al bottone - } - break; - default: - control_handler(ep); - break; - } - break; - default: - break; - } - TWindow::handler(win, ep); -} - -void TMask::init_mask() -{ - _sheets = _pages = 0; // Azzera numero pagine e sheets - - _enabled.set(MAX_PAGES); - _enabled.set(); // Abilita tutte le pagine - - _focus = _first_focus = 0; // Nessuno ha il focus - _page = -1; // Nessuna pagina corrente - _handler = NULL; // Nessun handler utente - _mode = NO_MODE; // Inizializza modo - _exchange = 1.0; // Il cambio per la valuta e' la lira - - memset(_pagewin, 0, sizeof(_pagewin)); - memset(_pagepag, 0, sizeof(_pagepag)); - memset(_pagetag, 0, sizeof(_pagetag)); -} - - -TMask::TMask(const char* title, int pages, int cols, int rows, int xpos, - int ypos) -{ - init_mask(); - for (_pages = 0; _pages < pages; _pages++) - _pagewin[_pages] = create(xpos, ypos, cols, rows, title, WSF_CLOSE, WD_MODAL); - set_win(NULL_WIN); - add_buttons(); -} - - -void TMask::read_mask(const char* name, int num, int max) -{ - if (max <= 0) max = MAX_PAGES; - - _source_file = name; - _source_file.ext(MASK_EXT); - TScanner scanner(_source_file); - - _sheetmask = num > 0; - - long start_t = clock(); - if (!_sheetmask) - _total_time = _build_time = _init_time = 0; - - for (int i = 0; i < num; i++) - { - while (scanner.ok()) - if (scanner.line() == "ENDMASK") break; - } - - init_mask(); - - main_app().begin_wait(); - while (scanner.ok() && scanner.popkey() != "EN") - { - if (scanner.key() == "PA") - { - CHECKD(_pages < MAX_PAGES, "Maschera con troppe pagine: ", _pages); - _pagewin[_pages++] = read_page(scanner, FALSE); - if (_pages >= max) - break; - } else - if (scanner.key() == "TO") - { - CHECK(toolwin() == NULL_WIN, "La maschera puo' avere una sola TOOLBAR"); - _pagewin[MAX_PAGES] = read_page(scanner, TRUE); - } - } - main_app().end_wait(); - - if (_pages < 1) - fatal_box("Impossibile leggere la maschera %s", name); - - add_buttons(); - - if (!_sheetmask) - _total_time = clock()-start_t; -} - - -void TMask::add_buttons() -{ -#if XVT_OS == XVT_OS_WIN - for (int p = 0; p < _pages; p++) - { - if (_pages > 1) - { - const long flags = (p < _pages-1 ? 0x1 : 0x0) | (p > 0 ? 0x2 : 0x0); - _pagepag[p] = xvt_create_control(WC_PUSHBUTTON, 0, 0, 1, 1, "", - _pagewin[p], flags, 0, DLG_PAGE); - } - if (toolwin()) - _pagetag[p] = xvt_create_control(WC_PUSHBUTTON, 0, 0, 0, 1, "", - _pagewin[p], p, _pages, DLG_PAGETAGS); - } -#else - if (toolwin()) - { - TString80 t; - for (int p = 0; p < _pages; p++) - t << ' ' << p+1; - t << ' '; - for (p = 0; p < _pages; p++) - { - const int k = p*2; - t[k] = '['; t[k+2] = ']'; - RCT r; set_rect(&r, 0, 0, t.size()*CHARX, CHARY); - create_control(WC_TEXT, &r, t, _pagewin[p], 0, 0, DLG_NULL); - t[k] = ' '; - } - } -#endif -} - - -TMask::TMask(const char* maskname, int num, int max) -{ - if (maskname && *maskname) - read_mask(maskname, num, max); -} - - -TMask::~TMask() -{ - for (int p = 0; p <= MAX_PAGES; p++) - if (_pagewin[p]) - { - close_window(_pagewin[p]); - _pagewin[p] = NULL_WIN; - } -} - - -void TMask::open() -{ - set_mask_fields(); - - _focus = first_focus(0); - if (toolwin() && _focus < 1) - _focus = find_first_field(_pagewin[0], +1); - - if (!_open || _page != 0) - { - _open = TRUE; - if (toolwin()) - show_window(toolwin(), TRUE); - next_page(0); - } - else - { - set_focus(); - } -} - - -int TMask::first_focus(short id) -{ - static int tempfirstfocus = 0; - - int f = _first_focus; - if (id == 0) - { - if (tempfirstfocus) - { - f = tempfirstfocus; - if (fld(f).dirty() == FALSE) - fld(f).set_dirty(); - } - tempfirstfocus = 0; - } - else - { - if (id > 0) - { - _first_focus = id2pos(id); - tempfirstfocus = 0; - } - else - tempfirstfocus = id2pos(-id); - } - - return f; -} - -bool TMask::can_be_closed() const -{ - bool ok = TRUE; - if (!query_mode() && is_running() && dirty()) - ok = yesno_box("Annullare i dati inseriti?"); - return ok; -} - -void TMask::close() -{ - _open = FALSE; - _page = -1; - for (int p = 0; p <= MAX_PAGES; p++) - if (_pagewin[p]) show_window(_pagewin[p], FALSE); -} - -void TMask::set_mask_fields() const -{ - for (int i = 0; i < fields(); i++) - { - TMask_field& f = fld(i); - const word id = f.class_id(); - if (id != CLASS_FIELD && id != CLASS_BUTTON_FIELD) - f.set_window_data(f.get_field_data()); - } -} - -short TMask::dirty() const -{ - const int max = fields(); - for (int i = 0; i < max; i++) - { - const TMask_field& f = fld(i); - const word id = f.class_id(); - if (f.dirty() && id != CLASS_FIELD && id != CLASS_BUTTON_FIELD && f.active()) - return f.dlg(); - } - return 0; -} - -void TMask::load_checks() const -{ - const int max = fields(); - for (int i = 0; i < max; i++) - { - TMask_field& f = fld(i); - if (f.has_check()) - f.check(STARTING_CHECK); - } -} - -// Dis/abilita una pagina e tutte le successive -void TMask::enable_page(byte page, bool on) -{ - CHECK(page > 0, "Can't enable/disable first page"); - - if (_enabled[page] != on) - { - for (byte i = page; i < _pages; i++) - _enabled.set(i, on); - -#if XVT_OS == XVT_OS_WIN - const byte p = on ? _pages : page; - for (i = 0; i < page-1; i++) - xvt_change_page_tags(NULL_WIN, FALSE, _pagetag[i], p); - - xvt_change_page_tags(_pagepag[page-1], on, _pagetag[page-1], p); -#endif - } -} - -// Controlla lo stato di abilitazione di una pagina -// Certified 100% -bool TMask::page_enabled(byte page) const -{ - return _enabled[page]; -} - - -void TMask::start_run() -{ - const long start = clock(); - - load_checks(); - - const int max = fields(); - for (int i = 0; i < max; i++) - { - TMask_field& f = fld(i); - if ((f.active() || f.ghost()) && - f.class_id() != CLASS_BUTTON_FIELD && f.dirty() <= TRUE) - { - f.set_dirty(FALSE); - f.on_hit(); // Lancia messaggio di inizializzazione - } - } - - // Make sure that "nearly" all fields are clean! - for (i = 0; i < max; i++) - { - TMask_field& f = fld(i); - if (query_mode() && f.is_edit() && f.in_key(1) && - !f.automagic() && !f.get().empty()) - { - f.set_dirty(TRUE); - } - else - { - if (f.dirty() == TRUE) - f.set_dirty(FALSE); - } - } - - _init_time = clock()-start; -} - -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); - if (!f.active()) continue; // 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 sheets - - if (f.on_key(K_ENTER) == FALSE) - { - if (is_open()) f.set_focus(); - return FALSE; - } - } - return TRUE; -} - - -void TMask::get_mask_fields() -{ - TString256 window_data; - for (int i = 0; i < fields(); i++) - { - TMask_field& f = fld(i); - - const int acqua = f.class_id(); - if (acqua != CLASS_FIELD && acqua != CLASS_BUTTON_FIELD && acqua != CLASS_SHEET_FIELD) - { - window_data = f.get_window_data(); - if (f.dirty() == TRUE) - { - const char* fd = f.get_field_data(); - CHECK(fd, "NULL pointer comparison"); - if (window_data == fd) - f.set_dirty(FALSE); - } - f.set_field_data(window_data); - } - } -} - - -int TMask::id2pos(short id) const -{ - const int MAX_FIELDS = 256; - static byte positions[MAX_FIELDS]; // 100 <= id < MAX_FIELDS - const int max = fields(); - - const int j = id-100; - int pos = -1; - if (j >= 0 && j < MAX_FIELDS) // Try using cache - { - pos = positions[j]; - if (pos >= 0 && pos < max) - { - const TMask_field& f = fld(pos); - if (f.dlg() == id) // Mask could have been changed! - return pos; - } - } - - for (pos = 0; pos < max; pos++) // Standard linear search - { - const TMask_field& f = fld(pos); - if (f.dlg() == id) - { - if (j >= 0 && j < MAX_FIELDS) // Store position for the next time - positions[j] = pos; - return pos; - } - } - - return -1; // Not found! -} - - -TMask_field& TMask::field(short id) const -{ - int pos = id2pos(id); - -#ifdef DBG - if (pos < 0) - { - yesnofatal_box("Il campo %d non esiste", id); - pos = 0; - } -#endif - - return fld(pos); -} - - -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; -} - - -int TMask::find_field_win(WINDOW win) const -{ - if (fld(_focus).win() == win) - return _focus; - - const int max = fields(); - for (int i = 0; i < max; i++) - if (fld(i).win() == win) return i; - -#ifdef DBG - yesnofatal_box("Can't find the field given the child window"); -#endif - return 0; -} - - -void TMask::set_focus_win(WINDOW win, bool force) -{ - _focus = find_field_win(win); - if (force) set_focus(); -} - - -int TMask::find_parent_page(const TMask_field& f) const -{ - const WINDOW pw = f.parent(); - for (int p = 0; p < _pages; p++) - if (pw == _pagewin[p]) return p; - return MAX_PAGES; // Toolbar button -} - - -int TMask::find_active_field(int first, int dir) const -{ - const int max = fields()-1; - WINDOW w, old = fld(_focus).parent(); - - for (int i = first; ; i += dir) - { - if (i > max) i = 0; - else if (i < 0) i = max; - if (fld(i).active() && page_enabled(find_parent_page(fld(i)))) - { - w = fld(i).parent(); - break; - } - } - - if (w != old) - { - int p = _page; - if (old == toolwin()) - { - if (dir > 0) - { if (++p >= _pages) p = 0; } - } - else - { - if (dir < 0) - { if (--p < 0) p = _pages-1; } - else p = MAX_PAGES; - } - w = _pagewin[p]; - i = find_first_field(w, dir); - } - return i; -} - -void TMask::set_focus() -{ - _focus = find_active_field(_focus, +1); - const TMask_field& f = fld(_focus); - const int page = find_parent_page(f); - - if (page != _page && page != MAX_PAGES) - { - const WINDOW pw = win(); // previous window - _page = page; // update page number - show_window(win(), TRUE); // show new page - if (pw) show_window(pw, FALSE); // hide old page - } - - f.highlight(); -} - - -// Move the focus to the next (+1) or previous(-1) valid control -void TMask::move_focus_field(int d) -{ - if (!test_focus_change()) - return; - - TMask_field& f = fld(_focus); - if (f.class_id() == CLASS_RADIO_FIELD) - { - TRadio_field& radio = (TRadio_field&)f; - moving_focus = TRUE; - bool cont = radio.move_focus(d); - moving_focus = FALSE; - if (!cont) return; - } - - const int focus = find_active_field(_focus+d, d); - if (fld(focus).parent() == f.parent() || check_current_page()) - _focus = focus; - - set_focus(); -} - -bool TMask::stop_run(KEY key) -{ - if (key != K_AUTO_ENTER && key != K_FORCE_CLOSE) - { - const int last = fields(); - bool found = FALSE; - for (int i = 0; i < last; i++) - { - const TMask_field& f = fld(i); - if (f.class_id() != CLASS_BUTTON_FIELD) continue; - const TButton_field& b = (const TButton_field&)f; - if (b.exit_key() == key) - { - if (b.active()) - { - found = TRUE; - break; - } - } - } - if (!found) - { -#ifdef DBG - return error_box("Non e' attivo il bottone associato a %d", key); -#else - return FALSE; -#endif - } - } - - if (key == K_CTRL_ENTER || key == K_AUTO_ENTER) key = K_ENTER; else - if (key == K_FORCE_CLOSE) key = K_QUIT; - - if (key != K_ESC && key != K_QUIT && key != K_DEL && key != K_F9) - { - const bool ok = check_fields(); - if (!ok) return FALSE; - } - if (is_running()) // Gestisce correttamenete le maschere chiuse - get_mask_fields(); - - return TWindow::stop_run(key); -} - -bool TMask::on_key(KEY key) -{ - if (_handler) - { - 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_UP: - case K_BTAB: - case K_SHIFT_TAB: - case K_LEFT: - move_focus_field(-1); - break; - case K_DOWN: - case K_TAB: - case K_RIGHT: - case K_ENTER: - move_focus_field(+1); - break; - case K_PREV: - next_page(-1); - break; - case K_NEXT: - next_page(+1); - break; - case K_F12: - message_box("Carissimo cronometrista, eccoti i tempi:\n" - "lettura + creazione = totale : init\n" - "%ld + %ld = %ld : %ld", - _total_time-_build_time, _build_time, _total_time, _init_time); - break; - default: - if (key > K_CTRL) - { - key -= K_CTRL; - if (key >= K_F1 && key <= K_F12) - next_page(1000 + key - K_F1); - else - { - const int last = fields(); - for (int i = 0; i < last; i++) - { - TMask_field& f = fld(i); - if (f.class_id() != CLASS_BUTTON_FIELD || !f.active()) continue; - TButton_field& b = (TButton_field&)f; - if (b.virtual_key() == key) - { - bool ok = b.dlg() != DLG_CANCEL && b.dlg() != DLG_QUIT && b.dlg() != DLG_F9; - if (!ok) ok = test_focus_change(b.win()); - if (ok) - f.on_key(K_SPACE); - break; - } - } - } - } - else - return fld(_focus).on_key(key); - } - - return TRUE; -} - - -TMask_field* TMask::parse_field(TScanner& scanner) -{ - if (scanner.key() == "ST") return new TEdit_field(this); - if (scanner.key() == "NU") return new TReal_field(this); - if (scanner.key() == "DA") return new TDate_field(this); - if (scanner.key() == "BO") return new TBoolean_field(this); - if (scanner.key() == "LI") return new TList_field(this); - if (scanner.key() == "BU") return new TButton_field(this); - if (scanner.key() == "TE") return new TMask_field(this); - if (scanner.key() == "RA") return new TRadio_field(this); - if (scanner.key() == "GR") return new TGroup_field(this); - if (scanner.key() == "SP") - { - _sheets++; - return new TSheet_field(this); - } - if (scanner.key() == "BR") return new TBrowsefile_field(this); - - - return NULL; -} - -WINDOW TMask::read_page(TScanner& scanner, bool toolbar) -{ - static int tooly; - static RCT rect; - - TString80 title(scanner.string()); - - RCT r; - if (toolwin()) - { - scanner.line(); - set_rect(&r, 0, 0, 0, tooly); - } - else - { - scanner.rectangle(r); - if (toolbar) - { - tooly = r.top; - } - else - { - if (_pages == 0) rect = r; - else r = rect; - } - } - - WINDOW w; - - if (toolbar || toolwin()) - { - w = create(0, r.top, 0, r.bottom, - title, toolbar ? 0 : WSF_INVISIBLE, W_PLAIN); - } - else - { - w = create(r.left, r.top, r.right, r.bottom, - title, WSF_CLOSE | WSF_INVISIBLE, WD_MODAL); - } - - while (scanner.popkey() != "EN") - { - - TMask_field* f = parse_field(scanner); -#ifdef DBG - if (f == NULL) - { - const int f = fields(); - TString256 e("Unknown control at pos."); e << f; - if (f) e << ". Last good was " << fld(f-1).dlg() << ": " << fld(f-1).prompt(); - fatal_box(e); - } -#endif - - const long start = clock(); - - f->construct(scanner, w); - _field.add(f); - - _build_time += clock()-start; - } - - set_win(NULL_WIN); - return w; -} - -int TMask::find_first_field(WINDOW w, int dir) const -{ - const int last = fields()-1; - const int fi = (dir > 0) ? 0 : last; - const int la = last-fi; - for (int i = fi; i != la; i += dir) - { - const TMask_field& f = fld(i); - if (f.parent() == w && f.active()) break; - } - return i; -} - - -bool TMask::check_current_page() -{ - if (!test_focus_change()) - return FALSE; - /* - - if (sheets() > 0) - return TRUE; - - const int last = fields(); - const WINDOW page = win(); - - for (int i = 0; i < last; i++) - { - TMask_field& f = fld(i); - if (f.parent() == page && f.active() && f.on_key(K_ENTER) == FALSE) - return FALSE; - } - */ - return TRUE; -} - - -void TMask::next_page(int p) -{ - const int prev = _page; // Previous page - - if (p != 0) - { - if (check_current_page() == FALSE) // New style - return; - - const int k = (p < 1000) ? _page+p : p-1000; - if (k < 0 || k >= _pages || !page_enabled(k)) - { - beep(); - return; - } - _page = k; - } else _page = 0; - - const WINDOW w = win(); // Current page window - if (_page != prev) - { - show_window(w, TRUE); - if (prev >= 0) - { - show_window(_pagewin[prev], FALSE); - _focus = find_first_field(w, +1); - } - } - - set_focus(); -} - - -void TMask::reset(short fld_id) -{ - if (fld_id < 1) - { - for (int f = 0; f < fields(); f++) - { - TMask_field& c = fld(f); - c._flags.dirty = FALSE; - c.reset(); - } - } - else field(fld_id).reset(); -} - - -void TMask::undo(short fld_id) -{ - if (fld_id < 1) - { - for (int f = 0; f < fields(); f++) - fld(f).undo(); - } else field(fld_id).undo(); -} - - -const TString& TMask::get(short fld_id) const -{ - return field(fld_id).get(); -} - -long TMask::get_long(short fld_id) const -{ - return atol(field(fld_id).get()); -} - -bool TMask::get_bool(short fld_id) const -{ - return field(fld_id).get().not_empty(); -} - -void TMask::set(short fld_id, const char* s, bool hit) -{ - TMask_field& f = field(fld_id); - f.set(s); - if (hit && (f.active() || f.ghost())) - f.on_key(K_TAB); -} - -void TMask::set(short fld_id, long n, bool hit) -{ - char s[16]; - sprintf(s, "%ld", n); - set(fld_id, s, hit); -} - - -void TMask::activate(bool on) -{ - TWindow::activate(on); - if (toolwin() != NULL_WIN) - show_window(toolwin(), on); -} - - -void TMask::enable(short fld_id, bool on) -{ - if (fld_id <= 0) - { - const int gr = -fld_id; - for (int i = 0; i < fields(); 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 < 1) - { - for (int i = 0; i < fields(); i++) - fld(i).enable_default(); - } else field(fld_id).enable_default(); -} - - -byte TMask::num_keys() const -{ - word max = 0; - for (int i = 0; i < fields(); i++) - { - word k = fld(i).last_key(); - if (k > max) max = k; - } - return max; -} - -void TMask::enable_key(byte key, bool on) -{ - for (int i = 0; i < fields(); i++) - if (fld(i).in_key(key)) - { - if (on) - { - fld(i).enable_default(); - if (!fld(i).shown()) - fld(i).show_default(); - } - else fld(i).disable(); - } -} - - -short TMask::get_key_field(byte key, bool first) const -{ - static int last = 0; - - if (first) last = 0; - - for (int i = last; i < fields(); i++) - { - if (fld(i).in_key(key)) - { - last = i+1; - return fld(i).dlg(); - } - } - - return -1; -} - -bool TMask::key_valid(int key) const -{ - for (short f = 0; f < fields(); f++) - { - TMask_field& c = fld(f); - if (c.in_key(key) && c.required()) - { - const TString & value = c.get(); - if (c.class_id() == CLASS_REAL_FIELD) - { - real z(value); - if (z.is_zero()) - { - c.reset(); - return FALSE; - } - } - if (value.empty()) - return FALSE; - } - } - return TRUE; -} - - -void TMask::show(short fld_id, bool on) -{ - if (fld_id <= 0) - { - const int gr = -fld_id; - for (int i = 0; i < fields(); i++) - { - TMask_field& f = fld(i); - if (gr == 0 || f.in_group(gr)) - f.show(on); - } - } - else field(fld_id).show(on); -} - - - -void TMask::show_default(short fld_id) -{ - if (fld_id <= 0) - { - for (int i = 0; i < fields(); i++) - fld(i).show_default(); - } else field(fld_id).show_default(); -} - - -void TMask::autoload(const TRelation* r) -{ - const int max = fields(); - for (int i = 0; i < max; i++) - { - TMask_field& f = fld(i); - if (f.field() != NULL) - f.autoload(r); - } -} - - -void TMask::autosave(TRelation* r) const -{ - const int max = fields(); - for (int i = 0; i < max; i++) - { - TMask_field& f = fld(i); - const TFieldref* fr =f.field(); - if (fr != NULL) - { - if (f.shown() || *fr->read(r) == '\0') - f.autosave(r); - } - } -} - -void TMask::on_firm_change() -{ - TString16 firm; firm << main_app().get_firm(); - - for (int i = 0; i < fields(); i++) - { - TMask_field& f = fld(i); - if (f._flags.firm) - { - f.set(firm); - f.check(STARTING_CHECK); - f.on_hit(); - } - } -} - - -void TMask::send_key(KEY key, short to, TMask_field* from) -{ - if (to == 0) - { - WINDOW w = from ? from->parent() : _pagewin[0]; - 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) fld(pos).on_key(key); -#ifdef DBG - else - yesnofatal_box("Can't send key %u to field %d", key, to); -#endif - } - } - else - { - const int gr = -to; - for (int i = 0; i < fields(); i++) - { - TMask_field& campo = fld(i); - if (campo.in_group(gr)) - campo.on_key(key); - } - } -} - -void TMask::set_handler(short fld_id, CONTROL_HANDLER handler) -{ - field(fld_id).set_handler(handler); -} - -void TMask::set_handler(MASK_HANDLER handler) -{ - _handler = handler; -} - -// aggiunta campi a runtime - -WINDOW TMask::add_static (short id, int page, const char* prompt, int x, - int y, const char* flags) -{ - TMask_field* f = new TMask_field(this); - f->construct(id, prompt, x, y, strlen(prompt), _pagewin[page], flags); - _field.add(f); - return f->win(); -} - -WINDOW TMask::add_string (short id, int page, const char* prompt, int x, - int y, int dim, const char* flags, int width) -{ - TEdit_field* f = new TEdit_field(this); - f->construct(id, prompt, x, y, dim, _pagewin[page], flags, width); - _field.add(f); - return f->win(); -} - -WINDOW TMask::add_number (short id, int page, const char* prompt, int x, - int y, int dim, const char* flags, int ndec) -{ - TReal_field* f = new TReal_field(this); - f->construct(id, prompt, x, y, dim, _pagewin[page], flags, ndec); - _field.add(f); - return f->win(); -} - -WINDOW TMask::add_date (short id, int page, const char* prompt, int x, - int y, const char* flags) -{ - TDate_field* f = new TDate_field(this); - f->construct(id, prompt, x, y, 10, _pagewin[page], flags); - _field.add(f); - return f->win(); -} - -WINDOW TMask::add_button (short id, int page, const char* prompt, int x, - int y, int dx, int dy, const char* flags) -{ - TButton_field* f = new TButton_field(this); - f->construct(id, prompt, x, y, dy, _pagewin[page], flags, dx); - _field.add(f); - return f->win(); -} - - -WINDOW TMask::add_radio(short id, int page, const char* prompt, int x, - int y, int dx, const char* codes, const char* items, const char* flags) -{ - TRadio_field* f = new TRadio_field(this); - f->replace_items(codes, items); - f->construct(id, prompt, x, y, dx, _pagewin[page], flags, dx); - _field.add(f); - return ((TMask_field*)f)->win(); -} - -bool TMask::save(bool append) const - -{ - FILE* f = fopen((const char *) _workfile, append ? "a" : "w"); - - if (f == NULL) - return yesnofatal_box("Non posso aprire %s ", (const char*) _workfile); - - for (int i = 0; i < fields(); i++) - { - const short id = fld(i).dlg(); - if (id >= 100) - fprintf(f, "%d|%s\n", id, (const char*) fld(i).get()); - } - fprintf(f, "[EOM]\n"); - fclose(f); - return TRUE; -} - - -bool TMask::load(bool reset) - -{ - FILE* f = fopen((const char *) _workfile, "r"); - - if (f == NULL) return FALSE; - if (reset) _lastpos = 0; - fseek(f, _lastpos, SEEK_SET); - TToken_string t(256); - char s[256]; - while (fgets(s, 255, f) != NULL && strncmp(s, "[EOM]", 5) != 0) - { - if (*s) s[strlen(s) - 1] = '\0'; - t = s; - const short id = t.get_int(); - if (id >= 100) - { - const int pos = id2pos(id); - if (pos >= 0) fld(pos).set(t.get()); - } - } - _lastpos = ftell(f); - fclose(f); - return TRUE; -} - - -const char* TMask::get_caption() const -{ - char* title = &__tmp_string[512]; - get_title(_pagewin[0], title, 80); - return title; -} - -void TMask::set_caption(const char* c) -{ - for (int p = 0; p < _pages; p++) - set_title(_pagewin[p], (char*)c); -} - - -void TMask::set_exchange(bool show_value, const real& n) -{ - const real nuo = (n.sign() <= 0) ? _exchange : n; - - main_app().begin_wait(); - for (int i = 0; i < fields(); i++) - { - TMask_field& f = fld(i); - const word id = f.class_id(); - if (id == CLASS_SHEET_FIELD || id == CLASS_REAL_FIELD && f.exchangeable()) - f.exchange(show_value, nuo); - } - - _exchange = nuo; // Update current exchange - main_app().end_wait(); -} +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define NULL_PAGE 256 + +HIDDEN const char* const MASK_EXT = "msk"; + +/////////////////////////////////////////////////////////// +// TMask methods +/////////////////////////////////////////////////////////// + +HIDDEN bool moving_focus = FALSE; + + +bool TMask::test_focus_change(WINDOW next) +{ + bool ok = TRUE; + + TMask_field& prev = fld(_focus); + if (prev.win() != next) + { + ok = prev.test_focus_change(); + if (!ok) // Test if previous field agrees ... + { + set_focus(); + prev.set_focusdirty(FALSE); + } + } + return ok; +} + +void TMask::control_handler(EVENT* ep) +{ + const WINDOW win = ep->v.ctl.ci.win; + const WIN_TYPE type = ep->v.ctl.ci.type; + + TMask_field* f = (TMask_field*)get_app_data(win); + CHECK(f != NULL, "Invalid field pointer in control"); + + if (type == WC_CHECKBOX) + { + if (test_focus_change(win)) + { + xvt_check_box(win, !xvt_get_checked_state(win)); + set_focus_win(win, FALSE); + f->on_key(K_SPACE); + } + return; + } + + if (type == WC_RADIOBUTTON) + { + if (moving_focus == FALSE) + { + if (test_focus_change(win)) + { + ((TRadio_field*)f)->check_radiobutton(win); + set_focus_win(win, FALSE); + f->on_key(K_SPACE); + } + } else moving_focus = FALSE; + return; + } + + if (type == WC_PUSHBUTTON) + { + if (test_focus_change(win)) + { + set_focus_win(win, FALSE); + f->on_hit(); + } + return; + } + + if (type == WC_LISTBUTTON) + { + if (test_focus_change(win)) + { + set_focus_win(win, FALSE); + f->on_key(K_SPACE); + } + return; + } + + if (ep->v.ctl.ci.v.edit.focus_change) + { + if (ep->v.ctl.ci.v.edit.active) + { + if (test_focus_change(win)) + { + set_focus_win(win, FALSE); + f->set_focusdirty(FALSE); + } + } + } + else + { // Contents of control were changed + f->on_key(K_SPACE); + } +} + +void TMask::handler(WINDOW win, EVENT* ep) +{ + switch (ep->type) + { + case E_UPDATE: +#if XVT_OS == XVT_OS_WIN + if (win != toolwin()) + { + clear_window(win, MASK_BACK_COLOR); + RCT r; get_client_rect(win, &r); r.right--; r.bottom--; + xvt_draw_rect(win, r, MASK_LIGHT_COLOR, MASK_DARK_COLOR, 1); + } + else clear_window(win, MASK_DARK_COLOR); +#else + clear_window(win, MASK_BACK_COLOR); +#endif + update(); + return; + case E_COMMAND: + if (ep->v.cmd.tag == M_FILE_NEW) + on_firm_change(); + break; + case E_CONTROL: + switch(ep->v.ctl.id) + { + case DLG_OK: + if (test_focus_change(ep->v.ctl.ci.win)) + stop_run(K_AUTO_ENTER); + break; + case DLG_CANCEL : + if (test_focus_change(ep->v.ctl.ci.win)) + stop_run(K_ESC); + break; + case DLG_QUIT : + if (test_focus_change(ep->v.ctl.ci.win)) + stop_run(K_FORCE_CLOSE); + break; + case DLG_F9: + { + WINDOW w = ep->v.ctl.ci.win; + TMask_field* f = (TMask_field*)get_app_data(w); + w = f->win(); + if (test_focus_change(w)) + f->on_key(K_F9); // Attiva ricerca sul campo associato al bottone + } + break; + default: + control_handler(ep); + break; + } + break; + default: + break; + } + TWindow::handler(win, ep); +} + +void TMask::init_mask() +{ + _sheets = _pages = 0; // Azzera numero pagine e sheets + + _enabled.set(MAX_PAGES); + _enabled.set(); // Abilita tutte le pagine + + _focus = _first_focus = 0; // Nessuno ha il focus + _page = -1; // Nessuna pagina corrente + _handler = NULL; // Nessun handler utente + _mode = NO_MODE; // Inizializza modo + _exchange = 1.0; // Il cambio per la valuta e' la lira + + memset(_pagewin, 0, sizeof(_pagewin)); + memset(_pagepag, 0, sizeof(_pagepag)); + memset(_pagetag, 0, sizeof(_pagetag)); +} + + +TMask::TMask(const char* title, int pages, int cols, int rows, int xpos, + int ypos) +{ + init_mask(); + for (_pages = 0; _pages < pages; _pages++) + _pagewin[_pages] = create(xpos, ypos, cols, rows, title, WSF_CLOSE, WD_MODAL); + set_win(NULL_WIN); + add_buttons(); +} + + +void TMask::read_mask(const char* name, int num, int max) +{ + if (max <= 0) max = MAX_PAGES; + + _source_file = name; + _source_file.ext(MASK_EXT); + TScanner scanner(_source_file); + + _sheetmask = num > 0; + + long start_t = clock(); + if (!_sheetmask) + _total_time = _build_time = _init_time = 0; + + for (int i = 0; i < num; i++) + { + while (scanner.ok()) + if (scanner.line() == "ENDMASK") break; + } + + init_mask(); + + main_app().begin_wait(); + while (scanner.ok() && scanner.popkey() != "EN") + { + if (scanner.key() == "PA") + { + CHECKD(_pages < MAX_PAGES, "Maschera con troppe pagine: ", _pages); + _pagewin[_pages++] = read_page(scanner, FALSE); + if (_pages >= max) + break; + } else + if (scanner.key() == "TO") + { + CHECK(toolwin() == NULL_WIN, "La maschera puo' avere una sola TOOLBAR"); + _pagewin[MAX_PAGES] = read_page(scanner, TRUE); + } + } + main_app().end_wait(); + + if (_pages < 1) + fatal_box("Impossibile leggere la maschera %s", name); + + add_buttons(); + + if (!_sheetmask) + _total_time = clock()-start_t; +} + + +void TMask::add_buttons() +{ +#if XVT_OS == XVT_OS_WIN + for (int p = 0; p < _pages; p++) + { + if (_pages > 1) + { + const long flags = (p < _pages-1 ? 0x1 : 0x0) | (p > 0 ? 0x2 : 0x0); + _pagepag[p] = xvt_create_control(WC_PUSHBUTTON, 0, 0, 1, 1, "", + _pagewin[p], flags, 0, DLG_PAGE); + } + if (toolwin()) + _pagetag[p] = xvt_create_control(WC_PUSHBUTTON, 0, 0, 0, 1, "", + _pagewin[p], p, _pages, DLG_PAGETAGS); + } +#else + if (toolwin()) + { + TString80 t; + for (int p = 0; p < _pages; p++) + t << ' ' << p+1; + t << ' '; + for (p = 0; p < _pages; p++) + { + const int k = p*2; + t[k] = '['; t[k+2] = ']'; + RCT r; set_rect(&r, 0, 0, t.size()*CHARX, CHARY); + create_control(WC_TEXT, &r, t, _pagewin[p], 0, 0, DLG_NULL); + t[k] = ' '; + } + } +#endif +} + + +TMask::TMask(const char* maskname, int num, int max) +{ + if (maskname && *maskname) + read_mask(maskname, num, max); +} + + +TMask::~TMask() +{ + for (int p = 0; p <= MAX_PAGES; p++) + if (_pagewin[p]) + { + close_window(_pagewin[p]); + _pagewin[p] = NULL_WIN; + } +} + + +void TMask::open() +{ + set_mask_fields(); + + _focus = first_focus(0); + if (toolwin() && _focus < 1) + _focus = find_first_field(_pagewin[0], +1); + + if (!_open || _page != 0) + { + _open = TRUE; + if (toolwin()) + show_window(toolwin(), TRUE); + next_page(0); + } + else + { + set_focus(); + } +} + + +int TMask::first_focus(short id) +{ + static int tempfirstfocus = 0; + + int f = _first_focus; + if (id == 0) + { + if (tempfirstfocus) + { + f = tempfirstfocus; + if (fld(f).dirty() == FALSE) + fld(f).set_dirty(); + } + tempfirstfocus = 0; + } + else + { + if (id > 0) + { + _first_focus = id2pos(id); + tempfirstfocus = 0; + } + else + tempfirstfocus = id2pos(-id); + } + + return f; +} + +bool TMask::can_be_closed() const +{ + bool ok = TRUE; + if (!query_mode() && is_running() && dirty()) + ok = yesno_box("Annullare i dati inseriti?"); + return ok; +} + +void TMask::close() +{ + _open = FALSE; + _page = -1; + for (int p = 0; p <= MAX_PAGES; p++) + if (_pagewin[p]) show_window(_pagewin[p], FALSE); +} + +void TMask::set_mask_fields() const +{ + for (int i = 0; i < fields(); i++) + { + TMask_field& f = fld(i); + const word id = f.class_id(); + if (id != CLASS_FIELD && id != CLASS_BUTTON_FIELD) + f.set_window_data(f.get_field_data()); + } +} + +short TMask::dirty() const +{ + const int max = fields(); + for (int i = 0; i < max; i++) + { + const TMask_field& f = fld(i); + const word id = f.class_id(); + if (f.dirty() && id != CLASS_FIELD && id != CLASS_BUTTON_FIELD && f.active()) + return f.dlg(); + } + return 0; +} + +void TMask::load_checks() const +{ + const int max = fields(); + for (int i = 0; i < max; i++) + { + TMask_field& f = fld(i); + if (f.has_check()) + f.check(STARTING_CHECK); + } +} + +// Dis/abilita una pagina e tutte le successive +void TMask::enable_page(byte page, bool on) +{ + CHECK(page > 0, "Can't enable/disable first page"); + + if (_enabled[page] != on) + { + for (byte i = page; i < _pages; i++) + _enabled.set(i, on); + +#if XVT_OS == XVT_OS_WIN + const byte p = on ? _pages : page; + for (i = 0; i < page-1; i++) + xvt_change_page_tags(NULL_WIN, FALSE, _pagetag[i], p); + + xvt_change_page_tags(_pagepag[page-1], on, _pagetag[page-1], p); +#endif + } +} + +// Controlla lo stato di abilitazione di una pagina +// Certified 100% +bool TMask::page_enabled(byte page) const +{ + return _enabled[page]; +} + + +void TMask::start_run() +{ + const long start = clock(); + + load_checks(); + + const int max = fields(); + for (int i = 0; i < max; i++) + { + TMask_field& f = fld(i); + if ((f.active() || f.ghost()) && + f.class_id() != CLASS_BUTTON_FIELD && f.dirty() <= TRUE) + { + f.set_dirty(FALSE); + f.on_hit(); // Lancia messaggio di inizializzazione + } + } + + // Make sure that "nearly" all fields are clean! + for (i = 0; i < max; i++) + { + TMask_field& f = fld(i); + if (query_mode() && f.is_edit() && f.in_key(1) && + !f.automagic() && !f.get().empty()) + { + f.set_dirty(TRUE); + } + else + { + if (f.dirty() == TRUE) + f.set_dirty(FALSE); + } + } + + _init_time = clock()-start; +} + +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); + if (!f.active()) continue; // 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 sheets + + if (f.on_key(K_ENTER) == FALSE) + { + if (is_open()) f.set_focus(); + return FALSE; + } + } + return TRUE; +} + + +void TMask::get_mask_fields() +{ + TString256 window_data; + for (int i = 0; i < fields(); i++) + { + TMask_field& f = fld(i); + + const int acqua = f.class_id(); + if (acqua != CLASS_FIELD && acqua != CLASS_BUTTON_FIELD && acqua != CLASS_SHEET_FIELD) + { + window_data = f.get_window_data(); + if (f.dirty() == TRUE) + { + const char* fd = f.get_field_data(); + CHECK(fd, "NULL pointer comparison"); + if (window_data == fd) + f.set_dirty(FALSE); + } + f.set_field_data(window_data); + } + } +} + + +int TMask::id2pos(short id) const +{ + const int MAX_FIELDS = 256; + static byte positions[MAX_FIELDS]; // 100 <= id < MAX_FIELDS + const int max = fields(); + + const int j = id-100; + int pos = -1; + if (j >= 0 && j < MAX_FIELDS) // Try using cache + { + pos = positions[j]; + if (pos >= 0 && pos < max) + { + const TMask_field& f = fld(pos); + if (f.dlg() == id) // Mask could have been changed! + return pos; + } + } + + for (pos = 0; pos < max; pos++) // Standard linear search + { + const TMask_field& f = fld(pos); + if (f.dlg() == id) + { + if (j >= 0 && j < MAX_FIELDS) // Store position for the next time + positions[j] = pos; + return pos; + } + } + + return -1; // Not found! +} + + +TMask_field& TMask::field(short id) const +{ + int pos = id2pos(id); + +#ifdef DBG + if (pos < 0) + { + yesnofatal_box("Il campo %d non esiste", id); + pos = 0; + } +#endif + + return fld(pos); +} + + +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; +} + + +int TMask::find_field_win(WINDOW win) const +{ + if (fld(_focus).win() == win) + return _focus; + + const int max = fields(); + for (int i = 0; i < max; i++) + if (fld(i).win() == win) return i; + +#ifdef DBG + yesnofatal_box("Can't find the field given the child window"); +#endif + return 0; +} + + +void TMask::set_focus_win(WINDOW win, bool force) +{ + _focus = find_field_win(win); + if (force) set_focus(); +} + + +int TMask::find_parent_page(const TMask_field& f) const +{ + const WINDOW pw = f.parent(); + for (int p = 0; p < _pages; p++) + if (pw == _pagewin[p]) return p; + return MAX_PAGES; // Toolbar button +} + + +int TMask::find_active_field(int first, int dir) const +{ + const int max = fields()-1; + WINDOW w, old = fld(_focus).parent(); + + for (int i = first; ; i += dir) + { + if (i > max) i = 0; + else if (i < 0) i = max; + if (fld(i).active() && page_enabled(find_parent_page(fld(i)))) + { + w = fld(i).parent(); + break; + } + } + + if (w != old) + { + int p = _page; + if (old == toolwin()) + { + if (dir > 0) + { if (++p >= _pages) p = 0; } + } + else + { + if (dir < 0) + { if (--p < 0) p = _pages-1; } + else p = MAX_PAGES; + } + w = _pagewin[p]; + i = find_first_field(w, dir); + } + return i; +} + +void TMask::set_focus() +{ + _focus = find_active_field(_focus, +1); + const TMask_field& f = fld(_focus); + const int page = find_parent_page(f); + + if (page != _page && page != MAX_PAGES) + { + const WINDOW pw = win(); // previous window + _page = page; // update page number + show_window(win(), TRUE); // show new page + if (pw) show_window(pw, FALSE); // hide old page + } + + f.highlight(); +} + + +// Move the focus to the next (+1) or previous(-1) valid control +void TMask::move_focus_field(int d) +{ + if (!test_focus_change()) + return; + + TMask_field& f = fld(_focus); + if (f.class_id() == CLASS_RADIO_FIELD) + { + TRadio_field& radio = (TRadio_field&)f; + moving_focus = TRUE; + bool cont = radio.move_focus(d); + moving_focus = FALSE; + if (!cont) return; + } + + const int focus = find_active_field(_focus+d, d); + if (fld(focus).parent() == f.parent() || check_current_page()) + _focus = focus; + + set_focus(); +} + +bool TMask::stop_run(KEY key) +{ + if (key != K_AUTO_ENTER && key != K_FORCE_CLOSE) + { + const int last = fields(); + bool found = FALSE; + for (int i = 0; i < last; i++) + { + const TMask_field& f = fld(i); + if (f.class_id() != CLASS_BUTTON_FIELD) continue; + const TButton_field& b = (const TButton_field&)f; + if (b.exit_key() == key) + { + if (b.active()) + { + found = TRUE; + break; + } + } + } + if (!found) + { +#ifdef DBG + return error_box("Non e' attivo il bottone associato a %d", key); +#else + return FALSE; +#endif + } + } + + if (key == K_CTRL_ENTER || key == K_AUTO_ENTER) key = K_ENTER; else + if (key == K_FORCE_CLOSE) key = K_QUIT; + + if (key != K_ESC && key != K_QUIT && key != K_DEL && key != K_F9) + { + const bool ok = check_fields(); + if (!ok) return FALSE; + } + if (is_running()) // Gestisce correttamenete le maschere chiuse + get_mask_fields(); + + return TWindow::stop_run(key); +} + +bool TMask::on_key(KEY key) +{ + if (_handler) + { + 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_UP: + case K_BTAB: + case K_SHIFT_TAB: + case K_LEFT: + move_focus_field(-1); + break; + case K_DOWN: + case K_TAB: + case K_RIGHT: + case K_ENTER: + move_focus_field(+1); + break; + case K_PREV: + next_page(-1); + break; + case K_NEXT: + next_page(+1); + break; + case K_F12: + message_box("Carissimo cronometrista, eccoti i tempi:\n" + "lettura + creazione = totale : init\n" + "%ld + %ld = %ld : %ld", + _total_time-_build_time, _build_time, _total_time, _init_time); + break; + default: + if (key > K_CTRL) + { + key -= K_CTRL; + if (key >= K_F1 && key <= K_F12) + next_page(1000 + key - K_F1); + else + { + const int last = fields(); + for (int i = 0; i < last; i++) + { + TMask_field& f = fld(i); + if (f.class_id() != CLASS_BUTTON_FIELD || !f.active()) continue; + TButton_field& b = (TButton_field&)f; + if (b.virtual_key() == key) + { + bool ok = b.dlg() != DLG_CANCEL && b.dlg() != DLG_QUIT && b.dlg() != DLG_F9; + if (!ok) ok = test_focus_change(b.win()); + if (ok) + f.on_key(K_SPACE); + break; + } + } + } + } + else + return fld(_focus).on_key(key); + } + + return TRUE; +} + + +TMask_field* TMask::parse_field(TScanner& scanner) +{ + if (scanner.key() == "ST") return new TEdit_field(this); + if (scanner.key() == "NU") return new TReal_field(this); + if (scanner.key() == "DA") return new TDate_field(this); + if (scanner.key() == "BO") return new TBoolean_field(this); + if (scanner.key() == "LI") return new TList_field(this); + if (scanner.key() == "BU") return new TButton_field(this); + if (scanner.key() == "TE") return new TMask_field(this); + if (scanner.key() == "RA") return new TRadio_field(this); + if (scanner.key() == "GR") return new TGroup_field(this); + if (scanner.key() == "SP") + { + _sheets++; + return new TSheet_field(this); + } + if (scanner.key() == "BR") return new TBrowsefile_field(this); + + + return NULL; +} + +WINDOW TMask::read_page(TScanner& scanner, bool toolbar) +{ + static int tooly; + static RCT rect; + + TString80 title(scanner.string()); + + RCT r; + if (toolwin()) + { + scanner.line(); + set_rect(&r, 0, 0, 0, tooly); + } + else + { + scanner.rectangle(r); + if (toolbar) + { + tooly = r.top; + } + else + { + if (_pages == 0) rect = r; + else r = rect; + } + } + + WINDOW w; + + if (toolbar || toolwin()) + { + w = create(0, r.top, 0, r.bottom, + title, toolbar ? 0 : WSF_INVISIBLE, W_PLAIN); + } + else + { + w = create(r.left, r.top, r.right, r.bottom, + title, WSF_CLOSE | WSF_INVISIBLE, WD_MODAL); + } + + while (scanner.popkey() != "EN") + { + + TMask_field* f = parse_field(scanner); +#ifdef DBG + if (f == NULL) + { + const int f = fields(); + TString256 e("Unknown control at pos."); e << f; + if (f) e << ". Last good was " << fld(f-1).dlg() << ": " << fld(f-1).prompt(); + fatal_box(e); + } +#endif + + const long start = clock(); + + f->construct(scanner, w); + _field.add(f); + + _build_time += clock()-start; + } + + set_win(NULL_WIN); + return w; +} + +int TMask::find_first_field(WINDOW w, int dir) const +{ + const int last = fields()-1; + const int fi = (dir > 0) ? 0 : last; + const int la = last-fi; + for (int i = fi; i != la; i += dir) + { + const TMask_field& f = fld(i); + if (f.parent() == w && f.active()) break; + } + return i; +} + + +bool TMask::check_current_page() +{ + if (!test_focus_change()) + return FALSE; + /* + + if (sheets() > 0) + return TRUE; + + const int last = fields(); + const WINDOW page = win(); + + for (int i = 0; i < last; i++) + { + TMask_field& f = fld(i); + if (f.parent() == page && f.active() && f.on_key(K_ENTER) == FALSE) + return FALSE; + } + */ + return TRUE; +} + + +void TMask::next_page(int p) +{ + const int prev = _page; // Previous page + + if (p != 0) + { + if (check_current_page() == FALSE) // New style + return; + + const int k = (p < 1000) ? _page+p : p-1000; + if (k < 0 || k >= _pages || !page_enabled(k)) + { + beep(); + return; + } + _page = k; + } else _page = 0; + + const WINDOW w = win(); // Current page window + if (_page != prev) + { + show_window(w, TRUE); + if (prev >= 0) + { + show_window(_pagewin[prev], FALSE); + _focus = find_first_field(w, +1); + } + } + + set_focus(); +} + + +void TMask::reset(short fld_id) +{ + if (fld_id < 1) + { + for (int f = 0; f < fields(); f++) + { + TMask_field& c = fld(f); + c._flags.dirty = FALSE; + c.reset(); + } + } + else field(fld_id).reset(); +} + + +void TMask::undo(short fld_id) +{ + if (fld_id < 1) + { + for (int f = 0; f < fields(); f++) + fld(f).undo(); + } else field(fld_id).undo(); +} + + +const TString& TMask::get(short fld_id) const +{ + return field(fld_id).get(); +} + +long TMask::get_long(short fld_id) const +{ + return atol(field(fld_id).get()); +} + +bool TMask::get_bool(short fld_id) const +{ + return field(fld_id).get().not_empty(); +} + +void TMask::set(short fld_id, const char* s, bool hit) +{ + TMask_field& f = field(fld_id); + f.set(s); + if (hit && (f.active() || f.ghost())) + f.on_key(K_TAB); +} + +void TMask::set(short fld_id, long n, bool hit) +{ + char s[16]; + sprintf(s, "%ld", n); + set(fld_id, s, hit); +} + + +void TMask::activate(bool on) +{ + TWindow::activate(on); + if (toolwin() != NULL_WIN) + show_window(toolwin(), on); +} + + +void TMask::enable(short fld_id, bool on) +{ + if (fld_id <= 0) + { + const int gr = -fld_id; + for (int i = 0; i < fields(); 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 < 1) + { + for (int i = 0; i < fields(); i++) + fld(i).enable_default(); + } else field(fld_id).enable_default(); +} + + +byte TMask::num_keys() const +{ + word max = 0; + for (int i = 0; i < fields(); i++) + { + word k = fld(i).last_key(); + if (k > max) max = k; + } + return max; +} + +void TMask::enable_key(byte key, bool on) +{ + for (int i = 0; i < fields(); i++) + if (fld(i).in_key(key)) + { + if (on) + { + fld(i).enable_default(); + if (!fld(i).shown()) + fld(i).show_default(); + } + else fld(i).disable(); + } +} + + +short TMask::get_key_field(byte key, bool first) const +{ + static int last = 0; + + if (first) last = 0; + + for (int i = last; i < fields(); i++) + { + if (fld(i).in_key(key)) + { + last = i+1; + return fld(i).dlg(); + } + } + + return -1; +} + +bool TMask::key_valid(int key) const +{ + for (short f = 0; f < fields(); f++) + { + TMask_field& c = fld(f); + if (c.in_key(key) && c.required()) + { + const TString & value = c.get(); + if (c.class_id() == CLASS_REAL_FIELD) + { + real z(value); + if (z.is_zero()) + { + c.reset(); + return FALSE; + } + } + if (value.empty()) + return FALSE; + } + } + return TRUE; +} + + +void TMask::show(short fld_id, bool on) +{ + if (fld_id <= 0) + { + const int gr = -fld_id; + for (int i = 0; i < fields(); i++) + { + TMask_field& f = fld(i); + if (gr == 0 || f.in_group(gr)) + f.show(on); + } + } + else field(fld_id).show(on); +} + + + +void TMask::show_default(short fld_id) +{ + if (fld_id <= 0) + { + for (int i = 0; i < fields(); i++) + fld(i).show_default(); + } else field(fld_id).show_default(); +} + + +void TMask::autoload(const TRelation* r) +{ + const int max = fields(); + for (int i = 0; i < max; i++) + { + TMask_field& f = fld(i); + if (f.field() != NULL) + f.autoload(r); + } +} + + +void TMask::autosave(TRelation* r) const +{ + const int max = fields(); + for (int i = 0; i < max; i++) + { + TMask_field& f = fld(i); + const TFieldref* fr =f.field(); + if (fr != NULL) + { + if (f.shown() || *fr->read(r) == '\0') + f.autosave(r); + } + } +} + +void TMask::on_firm_change() +{ + TString16 firm; firm << main_app().get_firm(); + + for (int i = 0; i < fields(); i++) + { + TMask_field& f = fld(i); + if (f._flags.firm) + { + f.set(firm); + f.check(STARTING_CHECK); + f.on_hit(); + } + } +} + + +void TMask::send_key(KEY key, short to, TMask_field* from) +{ + if (to == 0) + { + WINDOW w = from ? from->parent() : _pagewin[0]; + 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) fld(pos).on_key(key); +#ifdef DBG + else + yesnofatal_box("Can't send key %u to field %d", key, to); +#endif + } + } + else + { + const int gr = -to; + for (int i = 0; i < fields(); i++) + { + TMask_field& campo = fld(i); + if (campo.in_group(gr)) + campo.on_key(key); + } + } +} + +void TMask::set_handler(short fld_id, CONTROL_HANDLER handler) +{ + field(fld_id).set_handler(handler); +} + +void TMask::set_handler(MASK_HANDLER handler) +{ + _handler = handler; +} + +// aggiunta campi a runtime + +WINDOW TMask::add_static (short id, int page, const char* prompt, int x, + int y, const char* flags) +{ + TMask_field* f = new TMask_field(this); + f->construct(id, prompt, x, y, strlen(prompt), _pagewin[page], flags); + _field.add(f); + return f->win(); +} + +WINDOW TMask::add_string (short id, int page, const char* prompt, int x, + int y, int dim, const char* flags, int width) +{ + TEdit_field* f = new TEdit_field(this); + f->construct(id, prompt, x, y, dim, _pagewin[page], flags, width); + _field.add(f); + return f->win(); +} + +WINDOW TMask::add_number (short id, int page, const char* prompt, int x, + int y, int dim, const char* flags, int ndec) +{ + TReal_field* f = new TReal_field(this); + f->construct(id, prompt, x, y, dim, _pagewin[page], flags, ndec); + _field.add(f); + return f->win(); +} + +WINDOW TMask::add_date (short id, int page, const char* prompt, int x, + int y, const char* flags) +{ + TDate_field* f = new TDate_field(this); + f->construct(id, prompt, x, y, 10, _pagewin[page], flags); + _field.add(f); + return f->win(); +} + +WINDOW TMask::add_button (short id, int page, const char* prompt, int x, + int y, int dx, int dy, const char* flags) +{ + TButton_field* f = new TButton_field(this); + f->construct(id, prompt, x, y, dy, _pagewin[page], flags, dx); + _field.add(f); + return f->win(); +} + + +WINDOW TMask::add_radio(short id, int page, const char* prompt, int x, + int y, int dx, const char* codes, const char* items, const char* flags) +{ + TRadio_field* f = new TRadio_field(this); + f->replace_items(codes, items); + f->construct(id, prompt, x, y, dx, _pagewin[page], flags, dx); + _field.add(f); + return ((TMask_field*)f)->win(); +} + +bool TMask::save(bool append) const + +{ + FILE* f = fopen((const char *) _workfile, append ? "a" : "w"); + + if (f == NULL) + return yesnofatal_box("Non posso aprire %s ", (const char*) _workfile); + + for (int i = 0; i < fields(); i++) + { + const short id = fld(i).dlg(); + if (id >= 100) + fprintf(f, "%d|%s\n", id, (const char*) fld(i).get()); + } + fprintf(f, "[EOM]\n"); + fclose(f); + return TRUE; +} + + +bool TMask::load(bool reset) + +{ + FILE* f = fopen((const char *) _workfile, "r"); + + if (f == NULL) return FALSE; + if (reset) _lastpos = 0; + fseek(f, _lastpos, SEEK_SET); + TToken_string t(256); + char s[256]; + while (fgets(s, 255, f) != NULL && strncmp(s, "[EOM]", 5) != 0) + { + if (*s) s[strlen(s) - 1] = '\0'; + t = s; + const short id = t.get_int(); + if (id >= 100) + { + const int pos = id2pos(id); + if (pos >= 0) fld(pos).set(t.get()); + } + } + _lastpos = ftell(f); + fclose(f); + return TRUE; +} + + +const char* TMask::get_caption() const +{ + char* title = &__tmp_string[512]; + get_title(_pagewin[0], title, 80); + return title; +} + +void TMask::set_caption(const char* c) +{ + for (int p = 0; p < _pages; p++) + set_title(_pagewin[p], (char*)c); +} + + +void TMask::set_exchange(bool show_value, const real& n) +{ + const real nuo = (n.sign() <= 0) ? _exchange : n; + + main_app().begin_wait(); + for (int i = 0; i < fields(); i++) + { + TMask_field& f = fld(i); + const word id = f.class_id(); + if (id == CLASS_SHEET_FIELD || id == CLASS_REAL_FIELD && f.exchangeable()) + f.exchange(show_value, nuo); + } + + _exchange = nuo; // Update current exchange + main_app().end_wait(); +} diff --git a/include/maskfld.cpp b/include/maskfld.cpp index 3faf7ca59..456a0e010 100755 --- a/include/maskfld.cpp +++ b/include/maskfld.cpp @@ -1,4 +1,4 @@ -// $Id: maskfld.cpp,v 1.72 1995-01-26 13:57:35 guy Exp $ +// $Id: maskfld.cpp,v 1.73 1995-01-30 13:45:59 guy Exp $ #include #include @@ -808,8 +808,7 @@ bool TMask_field::on_key(KEY key) TFilename hlp("prassi.hlp"); const TString16 mod(topic.left(2)); - if (mod != "ba") - hlp.insert(mod, 6); + if (mod != "ba") hlp.insert(mod, 0); HWND hwnd = (HWND)get_value(TASK_WIN, ATTR_NATIVE_WINDOW); WinHelp(hwnd, hlp, HELP_MULTIKEY, (DWORD)&mk); diff --git a/include/tabapp.cpp b/include/tabapp.cpp index 19d5107a0..211af9d5f 100755 --- a/include/tabapp.cpp +++ b/include/tabapp.cpp @@ -42,7 +42,7 @@ bool Tab_application::user_create() if (_tabname.empty()) return FALSE; - + _tabname.upper(); TString16 m, t(_tabname); @@ -60,6 +60,9 @@ bool Tab_application::user_create() _rel = new TRelation(_tabname); set_title(_msk->get_caption()); + + TFilename rpt("batb"); rpt << t << ".rpt"; + if (fexist(rpt)) enable_menu_item(M_FILE_PRINT); return TRUE; }