#include #include #include #include #include #include #include #include #define NULL_PAGE 256 HIDDEN const char* MASK_EXT = "msk"; #ifdef DBG clock_t clock1, clock2, clock3; #endif /////////////////////////////////////////////////////////// // TMask methods /////////////////////////////////////////////////////////// HIDDEN bool moving_focus = FALSE; 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) { 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) { ((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) { set_focus_win(win, FALSE); f->on_hit(); return; } if (ep->v.ctl.ci.v.edit.focus_change) { if (ep->v.ctl.ci.v.edit.active) { TMask_field& old = fld(_focus); if (old.dlg() != f->dlg() && old.on_key(K_TAB) == FALSE) set_focus_win(old.win(), TRUE); else { 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); xvt_draw_rect(win, r, COLOR_CYAN, COLOR_GRAY, 1); } else clear_window(win, COLOR_GRAY); #else clear_window(win, MASK_BACK_COLOR); #endif update(); return; case E_CONTROL: switch(ep->v.ctl.id) { case DLG_OK : stop_run(K_AUTO_ENTER); break; case DLG_BAR : case DLG_CANCEL : stop_run(K_ESC); break; case DLG_QUIT : stop_run(K_FORCE_CLOSE); break; /* case DLG_PGDN : on_key(K_NEXT); break; case DLG_PGUP : on_key(K_PREV); break; case DLG_FIRSTREC: stop_run(K_HOME); break; case DLG_PREVREC : stop_run(K_PREV); break; case DLG_NEXTREC : stop_run(K_NEXT); break; case DLG_FINDREC : stop_run(K_F9); break; case DLG_LASTREC : stop_run(K_END); break; case DLG_NEWREC : stop_run(K_INS); break; case DLG_DELREC : stop_run(K_DEL); break; case DLG_SAVEREC : stop_run(K_SAVE); break; */ case DLG_F9: { // Attiva ricerca sul campo associato al bottone TMask_field* f = (TMask_field*)get_app_data(ep->v.ctl.ci.win); f->on_key(K_F9); } break; default: control_handler(ep); break; } break; default: break; } TWindow::handler(win, ep); } void TMask::init_mask(int mode) { _sheets = _pages = 0; // Azzera numero pagine e sheets _enabled = 0xffff; // Abilita tutte le pagine _focus = _first_focus = 0; // Nessuna ha il focus _page = -1; // Nessuan pagina corrente _handler = NULL; // Nessun handler utente _mode = mode; // Inizializza modo _exchange = 1.0; // Il cambio per la valuta e' la lira for (int i = 0; i <= MAX_PAGES; i++) _pagewin[i] = NULL_WIN; // Azzera le finestre delle varie pagine } TMask::TMask(const char* title, int pages, int cols, int rows, int xpos, int ypos, int mode) { init_mask(mode); for (_pages = 0; _pages < pages; _pages++) _pagewin[_pages] = create(xpos, ypos, cols, rows, title, WSF_CLOSE | WSF_SIZE, WD_MODAL); set_win(NULL_WIN); add_buttons(); } void TMask::read_mask(const char* name, int mode, int num) { #ifdef DBG clock1 = clock(); #endif _source_file = name; _source_file.ext(MASK_EXT); TScanner scanner(_source_file); for (int i = 0; i < num; i++) { while (scanner.ok()) if (scanner.line() == "ENDMASK") break; } init_mask(mode); const CURSOR old = get_cursor(TASK_WIN); set_cursor(TASK_WIN, CURSOR_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); } else if (scanner.key() == "TO") { CHECK(toolwin() == NULL_WIN, "La maschera puo' avere una sola TOOLBAR"); _pagewin[MAX_PAGES] = read_page(scanner, TRUE); } } set_cursor(TASK_WIN, old); if (_pages < 1) fatal_box("Impossibile leggere la maschera %s", name); add_buttons(); #ifdef DBG clock1 = clock()-clock1; #endif } void TMask::add_buttons() { #if XVT_OS == XVT_OS_WIN for (int p = 0; p < _pages; p++) { if (_pages > 1) { const byte flag = (p < _pages-1 ? 0x1 : 0x0) | (p > 0 ? 0x2 : 0x0); xvt_create_control(WC_PUSHBUTTON, 0,0,1,1, "", _pagewin[p], flag, 0, DLG_PAGE); } if (toolwin()) 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 mode, int num) { if (maskname && *maskname) read_mask(maskname, mode, num); } 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; next_page(0); if (toolwin()) show_window(toolwin(), TRUE); } else { set_focus(); } } int TMask::first_focus(short id) { static int tempfirstfocus = 0; int f = _first_focus; if (id == 0) { if (tempfirstfocus) { f = tempfirstfocus; fld(f).set_dirty(); } tempfirstfocus = 0; } else { if (id > 0) _first_focus = id2pos(id); else tempfirstfocus = id2pos(-id); } return f; } 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); } } void TMask::enable_page(int page, bool on) { int first = (page >= 0) ? page : 1; int last = (page >= 0) ? page+1 : _pages; for (int p = first; p < last; p++) { const word n = 1 << p; if (on) _enabled |= n; else _enabled &= ~n; } } bool TMask::page_enabled(int page) const { unsigned long n = 1 << page; return (_enabled & n) > 0; } void TMask::start_run() { #ifdef DBG clock2 = clock(); #endif 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.set_dirty(FALSE); f.on_hit(); } } // Make sure that "nearly" all fields are clean! for (i = 0; i < max; i++) { TMask_field& f = fld(i); if (mode() == MODE_QUERY && f.is_edit() && f.in_key(1) && !f.automagic() && !f.get().empty() ) f.set_dirty(TRUE); else { f.set_dirty(FALSE); } } #ifdef DBG clock2 = clock() - clock2; #endif } bool TMask::check_fields() { const int max = fields(); for (int i = 0; i < max; i++) { TMask_field& f = fld(i); if (f.active() && !f.on_key(K_ENTER)) { if (is_open()) f.set_focus(); return FALSE; } } return TRUE; } void TMask::get_mask_fields() { for (int i = 0; i < fields(); i++) { TMask_field& f = fld(i); f.set_field_data(f.get_window_data()); } } int TMask::id2pos(short id) const { const int MAX_FIELDS = 128; 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 clock 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); } int TMask::find_field_win(WINDOW win) const { 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()) { 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 } set_front_window(f.win()); } // Move the focus to the next (+1) or previous(-1) valid control void TMask::move_focus_field(int d) { TMask_field& f = fld(_focus); if (f.on_key(K_TAB) == FALSE) // Don't you agree to lose focus? ... { set_focus(); // ... Keep it return; } 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_ENTER; else if (key == K_FORCE_CLOSE) key = K_QUIT; if (key != K_ESC && key != K_QUIT && key != K_DEL) { 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_SHIFT_F3: if (yesno_box("Confermare il ripristino della maschera")) undo(); break; #ifdef DBG case K_F11: message_box("Siete fortunati utenti del campo %d della maschera '%s'\n" "caricata nell'incredibile tempo di %ld millisecondi\n" "ed inizializzata mostruosamente in %ld millisecondi\n" "Grazie per la comprensione", fld(_focus).dlg(), (const char*)source_file(), clock1, clock2); break; #endif 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 && fld(_focus).on_key(K_TAB) == TRUE) { 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); } 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; } } if (mode() == MODE_SEARCH) { title.insert("RICERCA: ", 0); r.bottom = 12; } 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_SIZE | WSF_INVISIBLE, WD_MODAL); } while (scanner.popkey() != "EN") { TMask_field* f = parse_field(scanner); if (f != NULL) { f->construct(scanner, w); _field.add(f); } else error_box("Can't create a %s", (const char*)scanner.token()); } 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 (fld(_focus).on_key(K_TAB) == FALSE) 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.reset(); c.set_dirty(FALSE); } } 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::enable(bool on) const { TWindow::enable(on); if (toolwin() != NULL_WIN) show_window(toolwin(), on); } void TMask::enable(short fld_id, bool on) { if (fld_id < 1) { for (int i = 0; i < fields(); i++) { TMask_field& f = fld(i); if (f.dlg() > 100) fld(i).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).showed()) 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 TFixed_string 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 < 1) { for (int i = 0; i < fields(); i++) fld(i).show(on); } else field(fld_id).show(on); } void TMask::show_default(short fld_id) { if (fld_id < 1) { 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()) 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) { if (f.showed() || *fr->read(r) == '\0') f.autosave(r); } } } void TMask::send_key(KEY key, short to) const { if (to == 0) { dispatch_e_char(win(), key); return; } if (to > 0) { const int pos = id2pos(to); if (pos >= 0) fld(pos).on_key(key); #ifdef DBG else if (mode() != MODE_SEARCH) yesnofatal_box("Can't send key to field %d", to); #endif } else { to = -to; for (int i = 0; i < fields(); i++) { TMask_field& campo = fld(i); if (campo.in_group((int)to)) 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 runclock void 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); } void 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); } void 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); } void 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); } void 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); } void 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); } 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(const real& e) { const real nuo = (e.sign() <= 0) ? real(1.0) : e; const bool run = is_running(); if (run && _exchange == nuo) return; const CURSOR oldcur = get_cursor(TASK_WIN); // Store current cursor set_cursor(TASK_WIN, CURSOR_WAIT); for (int i = 0; i < fields(); i++) { TMask_field& f = fld(i); const word id = f.class_id(); if (id == CLASS_SHEET_FIELD) { TSheet_field& s = (TSheet_field&)f; TMask& m = s.sheet_mask(); m.set_exchange(nuo); if (run) s.force_update(); } else if (id == CLASS_REAL_FIELD && f._flags.exchange) { TReal_field& r = (TReal_field&)f; r.exchange(_exchange, nuo); } } _exchange = nuo; // Update current exchange set_cursor(TASK_WIN, oldcur); // Restore cursor }