colors.h Aggiunto colore della toolbar controls.cpp Aggiunto supporto per il colore di sfondo controls.h Aggiunti metodi set/get_back_color form.cpp Reindentato mask.cpp Aggiunto supporto per il colore della toolbar mask.h Resa pubblica la funzione toolwin() maskfld.cpp Aggiunto supporto per il colore dello sfondo maskfld.h Aggiunta funzione set_back_color ai campi msksheet.cpp Corretto metodi insert e destroy pagsca.h Aggiunto campo PASSATT relapp.cpp Cambiati messaggi di richiesta di proseguire in caso d'errore relation.cpp Corretta lfile che non falliva mai anche se avrebbe dovuto xvtility.cpp Aggiunta funzione xvt_ctrl_set_back_color xvtility.h Come sopra git-svn-id: svn://10.65.10.50/trunk@2005 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1743 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1743 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <time.h>
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#include <applicat.h>
 | 
						|
#include <browfile.h>
 | 
						|
#include <colors.h>
 | 
						|
#include <msksheet.h>
 | 
						|
#include <relation.h>
 | 
						|
#include <urldefid.h>
 | 
						|
#include <utility.h>
 | 
						|
 | 
						|
#define NULL_PAGE 256
 | 
						|
 | 
						|
HIDDEN const char* const MASK_EXT = "msk";
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMask methods
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
HIDDEN bool moving_focus = FALSE;
 | 
						|
 | 
						|
// @mfunc Controlla se e' possibile dare il focus alla finestra <p next>
 | 
						|
//
 | 
						|
// @rdesc Ritorna la possibilita' di lasciare il focus
 | 
						|
//
 | 
						|
// @flag TRUE | Se e' possibile cedere il focus a <p next>
 | 
						|
// @flag FALSE | Se non e' possibile cedere il focus a <p next>
 | 
						|
bool TMask::test_focus_change(
 | 
						|
  WINDOW next) // @parm Finestra che dovrebbe ricevere il focus
 | 
						|
  
 | 
						|
  // @comm Controlla se il contenuto del campo attuale e' valido e quindi puo' perdere il focus
 | 
						|
{
 | 
						|
  bool ok = TRUE;
 | 
						|
 | 
						|
  TMask_field& prev = fld(_focus);
 | 
						|
  _next_fld = next == NULL_WIN ? DLG_NULL : fld(find_field_win(next)).dlg();
 | 
						|
 | 
						|
  if (prev.win() != next)
 | 
						|
  {
 | 
						|
    ok = prev.test_focus_change();
 | 
						|
    if (!ok)                        // Test if previous field agrees ...
 | 
						|
    {
 | 
						|
      set_focus();
 | 
						|
      prev.set_focusdirty(FALSE);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if ( prev.focusdirty() )
 | 
						|
        ok = on_dirty( prev );
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
  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*)xvt_vobj_get_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(f->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())
 | 
						|
    {
 | 
						|
      xvt_dwin_clear(win, MASK_BACK_COLOR);
 | 
						|
      RCT r; xvt_vobj_get_client_rect(win, &r); r.right--; r.bottom--;
 | 
						|
      xvt_draw_rect(win, r, MASK_LIGHT_COLOR, MASK_DARK_COLOR, 1);
 | 
						|
    }
 | 
						|
    else xvt_dwin_clear(win, TOOL_BACK_COLOR);
 | 
						|
    xvt_tx_process_event(win, ep);
 | 
						|
#else
 | 
						|
    xvt_dwin_clear(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  :
 | 
						|
      stop_run(K_ESC);
 | 
						|
      break;
 | 
						|
    case DLG_QUIT    :
 | 
						|
      stop_run(K_FORCE_CLOSE);
 | 
						|
      break;
 | 
						|
    case DLG_F9:
 | 
						|
    {
 | 
						|
      WINDOW w = ep->v.ctl.ci.win;
 | 
						|
      TMask_field* f = (TMask_field*)xvt_vobj_get_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:
 | 
						|
    if (_focus >= 0 && _focus < fields() && fld(_focus).class_id() == CLASS_MEMO_FIELD)
 | 
						|
    {
 | 
						|
      bool ok = TRUE;
 | 
						|
      if (ep->type == E_CHAR)
 | 
						|
      {
 | 
						|
        const KEY k = e_char_to_key(ep);
 | 
						|
        ok = k != K_TAB && k != K_BTAB;
 | 
						|
        if (ok) fld(_focus).set_dirty();
 | 
						|
      }
 | 
						|
      if (ok)
 | 
						|
      {
 | 
						|
        ok = xvt_tx_process_event(win, ep) == TRUE;
 | 
						|
        if (ok) return;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  TWindow::handler(win, ep);
 | 
						|
}
 | 
						|
 | 
						|
void TMask::init_mask()
 | 
						|
{
 | 
						|
  _sheets = _pages = 0;                       // Azzera numero pagine e sheets
 | 
						|
  _sheet = NULL;                              // Non appartiene a nessuno sheet
 | 
						|
 | 
						|
  _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();
 | 
						|
}
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @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
 | 
						|
 | 
						|
  // @comm Permette di aggiornare i tempi di caricamento della maschera stessa
 | 
						|
{
 | 
						|
  if (max <= 0) max = MAX_PAGES;
 | 
						|
 | 
						|
  _source_file = name;
 | 
						|
  _source_file.ext(MASK_EXT);
 | 
						|
  _source_file.lower();
 | 
						|
  TScanner scanner(_source_file);
 | 
						|
 | 
						|
  long start_t = clock();
 | 
						|
  while (clock() == start_t) continue;   // Attende scatto timer
 | 
						|
  start_t = clock();
 | 
						|
 | 
						|
  if (num == 0)
 | 
						|
    _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);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  if (_pages < 1)
 | 
						|
    fatal_box("Impossibile leggere la maschera %s", name);
 | 
						|
 | 
						|
  add_buttons();
 | 
						|
 | 
						|
  if (num == 0)
 | 
						|
    _total_time = clock()-start_t;
 | 
						|
 | 
						|
  main_app().end_wait();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
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; xvt_rect_set(&r, 0, 0, t.size()*CHARX, CHARY);
 | 
						|
      xvt_ctl_create(WC_TEXT, &r, t, _pagewin[p], 0, 0, DLG_NULL);
 | 
						|
      t[k] = ' ';
 | 
						|
    }
 | 
						|
  }
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TMask::TMask(const char* maskname, int num, int max) : _should_check(TRUE)
 | 
						|
{
 | 
						|
 | 
						|
  if (maskname && *maskname)
 | 
						|
    read_mask(maskname, num, max);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TMask::~TMask()
 | 
						|
{
 | 
						|
  for (int p = 0; p <= MAX_PAGES; p++)
 | 
						|
    if (_pagewin[p])
 | 
						|
    {
 | 
						|
      xvt_vobj_destroy(_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())
 | 
						|
      xvt_vobj_set_visible(toolwin(), TRUE);
 | 
						|
    show_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]) xvt_vobj_set_visible(_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
 | 
						|
{
 | 
						|
  if (_should_check)
 | 
						|
  {
 | 
						|
    const int max = fields();
 | 
						|
    for (int i = 0; i < max; i++)
 | 
						|
    {
 | 
						|
      TMask_field& f = fld(i);
 | 
						|
      if (f.has_check())
 | 
						|
        f.check(STARTING_CHECK);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// @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 <p p> (default)
 | 
						|
  // @flag FALSE | Disabilita la pagina <p p>
 | 
						|
{
 | 
						|
  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();
 | 
						|
  _should_check = TRUE;
 | 
						|
 | 
						|
  const int max = fields();
 | 
						|
 | 
						|
  _next_fld = DLG_NULL;
 | 
						|
  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()
 | 
						|
{
 | 
						|
  for (int i = 0; i < fields(); i++)
 | 
						|
  {
 | 
						|
    TMask_field& f = fld(i);
 | 
						|
    const char* fd = f.get_field_data();
 | 
						|
    if (fd != NULL)                             // NULL per testi fissi, bottoni e sheets
 | 
						|
    {
 | 
						|
      const char* wd = f.get_window_data();
 | 
						|
      CHECKD(wd, "NULL window data in field ", f.dlg());
 | 
						|
      if (f.dirty() == TRUE)
 | 
						|
      {
 | 
						|
        if (strcmp(wd, fd) == 0)
 | 
						|
          f.set_dirty(FALSE);
 | 
						|
      }
 | 
						|
      f.set_field_data(wd);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @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 <p id> e ne ritorna il numero ordinale
 | 
						|
  //                     (es. il campo 120 e' il quarto della maschera)
 | 
						|
{
 | 
						|
  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;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Setta il focus al campo la cui finestra e' <p win>
 | 
						|
void TMask::set_focus_win(
 | 
						|
  WINDOW win, // @parm Finestra del controllo che riceve il focus
 | 
						|
  bool force) // @parm Forza la chiamata alla <mf TMask::set_focus>
 | 
						|
  
 | 
						|
  // @comm Il parametro <p force>       puo' assumere i seguenti valori:
 | 
						|
  //
 | 
						|
  // @flag TRUE | Se occorre attivare il focus interno (quello di Windows e' automatico)
 | 
						|
  // @flag FALSE | Se non occorre attivare il focus interno (e' possibile conoscere il focus
 | 
						|
  //                             interno della classe)
 | 
						|
{
 | 
						|
  _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
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Ritorna il prossimo campo attivabile
 | 
						|
//
 | 
						|
// @rdesc Riorna il numero del campo cercato
 | 
						|
int TMask::find_active_field(
 | 
						|
  int first,     // @parm Campo da cui cominciare la ricerca
 | 
						|
  int dir) const // @parm Direzione della ricerca. Puo assumere i valori:
 | 
						|
  // 
 | 
						|
  // @flag +1 | Ricerca in avanti                                  
 | 
						|
  // @flag -1 | Ricerca in dietro
 | 
						|
  
 | 
						|
  // @comm Serve per la ricerca del campo attivabil al momento della pressione dei tasti
 | 
						|
  //             TAB (o ENTER) e SHIFT+TAB
 | 
						|
{
 | 
						|
  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
 | 
						|
    xvt_vobj_set_visible(win(), TRUE);         // show new page
 | 
						|
    if (pw) xvt_vobj_set_visible(pw, FALSE);   // hide old page
 | 
						|
  }
 | 
						|
 | 
						|
  f.highlight();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Muove il focus al prossimo o al precedente controllo valido
 | 
						|
void TMask::move_focus_field(
 | 
						|
  int d) // @parm Indica lo spostamento relativo del focus rispetto
 | 
						|
  //        al campo attuale:
 | 
						|
  //
 | 
						|
  // @flag +1 | Si sposta sul campo successivo
 | 
						|
  // @flag -1 | Si sposta sul campo precedente
 | 
						|
  //
 | 
						|
  // @comm E' possibile che il parametro <p d> assuma valori diversi da -1 o +1. In questo caso
 | 
						|
  //               sposta il focus di piu' di una posizione.
 | 
						|
 | 
						|
{
 | 
						|
 | 
						|
  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 (!test_focus_change(fld(focus).win()))
 | 
						|
    return;
 | 
						|
 | 
						|
  if (fld(focus).parent() == f.parent() || check_current_page())
 | 
						|
    _focus = focus;
 | 
						|
 | 
						|
  set_focus();
 | 
						|
}
 | 
						|
 | 
						|
// @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 <p key>.
 | 
						|
  //                     Nela 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();
 | 
						|
    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();
 | 
						|
    _next_fld = DLG_NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  return TWindow::stop_run(key);
 | 
						|
}
 | 
						|
 | 
						|
// @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)
 | 
						|
  {
 | 
						|
    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("Lettura          = %ld\n"
 | 
						|
                "Creazione        = %ld\n"
 | 
						|
                "Inizializzazione = %ld",
 | 
						|
                _total_time-_build_time, _build_time, _init_time);
 | 
						|
    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)
 | 
						|
          show_page(key - K_F1);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        for (int i = 0; i < fields(); 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;
 | 
						|
}
 | 
						|
 | 
						|
bool TMask::on_dirty(TMask_field&)
 | 
						|
{
 | 
						|
  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);
 | 
						|
  if (scanner.key() == "ME") return new TMemo_field(this);
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Legge la pagina dal file
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'andle della finestra creata
 | 
						|
WINDOW TMask::read_page(
 | 
						|
  TScanner& scanner, // @parm File dal quale leggere la pagina
 | 
						|
  bool toolbar)      // @parm Indica se e' la toolbar
 | 
						|
  
 | 
						|
  // @comm Il parametro <p toolbar> e' utilizzato per indicare se la pagina deve essere visualizzata
 | 
						|
  //                     a tutto schermo (TRUE) oppure no
 | 
						|
{
 | 
						|
  static int tooly;
 | 
						|
  static RCT rect;
 | 
						|
 | 
						|
  TString80 title(scanner.string());
 | 
						|
 | 
						|
  RCT r;
 | 
						|
  if (toolwin())
 | 
						|
  {
 | 
						|
    scanner.line();
 | 
						|
    xvt_rect_set(&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);
 | 
						|
    
 | 
						|
    if (toolbar)
 | 
						|
      f->set_back_color(TOOL_BACK_COLOR);
 | 
						|
 | 
						|
    _build_time += clock()-start;
 | 
						|
  }
 | 
						|
  
 | 
						|
 | 
						|
  set_win(NULL_WIN);
 | 
						|
  return w;
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Ritorna la posizione del primo campo attivo nella direzione specificata
 | 
						|
//
 | 
						|
// @rdesc Ritorna il primo campo attivo
 | 
						|
int TMask::find_first_field(
 | 
						|
  WINDOW w,      // @parm handle della finestra (pagina) nel quale cercare
 | 
						|
  int dir) const // @parm Direzione di ricerca. Puo' assumere i valori:
 | 
						|
  //
 | 
						|
  // @flag +1 | Direzione in avanti
 | 
						|
  // @flag -1 | Direzione in dietro
 | 
						|
{
 | 
						|
  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;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Mostra la prossima/precedente pagina 
 | 
						|
void TMask::next_page(
 | 
						|
  int p) // @parm Pagina alla quale saltare
 | 
						|
  
 | 
						|
  // @comm Il valore <p p> 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)
 | 
						|
  {
 | 
						|
    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;
 | 
						|
 | 
						|
  if (_page != prev)
 | 
						|
  {
 | 
						|
    const WINDOW w = _pagewin[_page];
 | 
						|
    xvt_vobj_set_visible(w, TRUE);
 | 
						|
    if (prev >= 0)
 | 
						|
    {
 | 
						|
      xvt_vobj_set_visible(_pagewin[prev], FALSE);
 | 
						|
      _focus = find_first_field(w, +1);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  set_focus();
 | 
						|
}
 | 
						|
 | 
						|
void TMask::show_page(int p)
 | 
						|
{
 | 
						|
  CHECKD(p >= 0 && p < _pages, "Pagina del cazzo", p);
 | 
						|
  next_page(1000 + p);
 | 
						|
}
 | 
						|
 | 
						|
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();
 | 
						|
}
 | 
						|
 | 
						|
// @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
 | 
						|
  bool 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 (hit && (f.active() || f.ghost()))
 | 
						|
    f.on_hit();
 | 
						|
}
 | 
						|
 | 
						|
void TMask::set(short fld_id, long n, bool hit)
 | 
						|
{          
 | 
						|
  char s[16];
 | 
						|
  sprintf(s, "%ld", n);
 | 
						|
  set(fld_id, s, hit);
 | 
						|
}
 | 
						|
 | 
						|
void TMask::set(short fld_id, const real& n, bool hit)
 | 
						|
{
 | 
						|
  CHECK(field(fld_id).class_id() == CLASS_REAL_FIELD, "Can't set a real value in a non-number field");
 | 
						|
  set(fld_id, n.string(), hit);
 | 
						|
}
 | 
						|
 | 
						|
void TMask::set(short fld_id, const TDate& d, bool hit)
 | 
						|
{
 | 
						|
  CHECK(field(fld_id).class_id() == CLASS_DATE_FIELD, "Can't set a date in a non-date field");
 | 
						|
  set(fld_id, d.string(), hit);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// @mfunc Permette di attivare/disattivare tutta la pagina
 | 
						|
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);
 | 
						|
  if (toolwin() != NULL_WIN)
 | 
						|
    xvt_vobj_set_visible(toolwin(), on);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Abilita/disabilita un campo
 | 
						|
void TMask::enable(
 | 
						|
  short fld_id, // @parm Identificatore del campo da abilitare (-1 tutti i campi)
 | 
						|
  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 = 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;
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Abilita/disabilita i campi di una chiave sulla maschera
 | 
						|
void TMask::enable_key(
 | 
						|
  byte 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 = 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();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Ritorna il l'identificatore di un campo della chiave <p key>
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'identificatore del campo cercato
 | 
						|
short TMask::get_key_field(
 | 
						|
  byte 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;
 | 
						|
 | 
						|
  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.required() && c.shown() && c.in_key(key))
 | 
						|
    {
 | 
						|
      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;
 | 
						|
}
 | 
						|
 | 
						|
// @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 <p fld_id> e' -1 allora permette di operare su tutti i campi della maschera
 | 
						|
 | 
						|
{
 | 
						|
  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);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// @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 <p parm> Assume il valore -1 vuole dire che vengono risettati tutti i campi della amschera         
 | 
						|
{
 | 
						|
  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::on_idle()
 | 
						|
{
 | 
						|
  if (_focus >= 0 && _focus < fields())
 | 
						|
  {
 | 
						|
    const word acqua = fld(_focus).class_id();
 | 
						|
    if (acqua == CLASS_SHEET_FIELD)
 | 
						|
    {
 | 
						|
      TSheet_field& s = (TSheet_field&)fld(_focus);
 | 
						|
      s.on_idle();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @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() : _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);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// @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 <t CONTROL_HANDLER> al campo indicato
 | 
						|
  //       da <p fld_id>, mentre nel secondo viene mandato un <t MASK_HANDLER>
 | 
						|
  //       alla maschera corrente
 | 
						|
 | 
						|
{
 | 
						|
  field(fld_id).set_handler(handler);
 | 
						|
}
 | 
						|
 | 
						|
void TMask::set_handler(MASK_HANDLER handler)
 | 
						|
{
 | 
						|
  _handler = handler;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Aggiunge runtime un campo testo alla maschera
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'handle del campo creato
 | 
						|
WINDOW 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 <mf TMask::add_string> <mf TMask::add_number> <mf TMask::add_date>
 | 
						|
  //     <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
 | 
						|
{
 | 
						|
  TMask_field* f = new TMask_field(this);
 | 
						|
  f->construct(id, prompt, x, y, strlen(prompt), _pagewin[page], flags);
 | 
						|
  _field.add(f);
 | 
						|
  return f->win();
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Aggiunge runtime un campo stringa alla maschera
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'handle del campo creato
 | 
						|
WINDOW 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 <mf TMask::add_static> <mf TMask::add_number> <mf TMask::add_date>
 | 
						|
  //     <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
 | 
						|
{
 | 
						|
  TEdit_field* f = new TEdit_field(this);
 | 
						|
  f->construct(id, prompt, x, y, dim, _pagewin[page], flags, width);
 | 
						|
  _field.add(f);
 | 
						|
  return f->win();
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Aggiunge runtime un campo numerico alla maschera
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'handle del campo creato
 | 
						|
WINDOW 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 <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_date>
 | 
						|
  //     <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
 | 
						|
{
 | 
						|
  TReal_field* f = new TReal_field(this);
 | 
						|
  f->construct(id, prompt, x, y, dim, _pagewin[page], flags, ndec);
 | 
						|
  _field.add(f);
 | 
						|
  return f->win();
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Aggiunge runtime un campo data alla maschera
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'handle del campo creato
 | 
						|
WINDOW 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 <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
 | 
						|
  //     <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
 | 
						|
{
 | 
						|
  TDate_field* f = new TDate_field(this);
 | 
						|
  f->construct(id, prompt, x, y, 10, _pagewin[page], flags);
 | 
						|
  _field.add(f);
 | 
						|
  return f->win();
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Aggiunge runtime un campo bottone alla maschera
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'handle del campo creato
 | 
						|
WINDOW 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, defailt 9)
 | 
						|
  int dy,                  // @parm Altezza del campo (in caratteri, default 1)
 | 
						|
  const char* flags)  // @parm Flag di controllo del campo (default "")
 | 
						|
 | 
						|
  // @xref <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
 | 
						|
  //     <mf TMask::add_date> <mf TMask::add_radio> <mf TMask::add_memo>
 | 
						|
{
 | 
						|
  TButton_field* f = new TButton_field(this);
 | 
						|
  f->construct(id, prompt, x, y, dy, _pagewin[page], flags, dx);
 | 
						|
  _field.add(f);
 | 
						|
  return f->win();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Aggiunge runtime un campo radio button alla maschera
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'handle del campo creato
 | 
						|
WINDOW 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 <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
 | 
						|
  //     <mf TMask::add_date> <mf TMask::add_button> <mf TMask::add_memo>
 | 
						|
{
 | 
						|
  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();
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Aggiunge runtime un campo memo alla maschera
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'handle del campo creato
 | 
						|
WINDOW 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 <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
 | 
						|
  //     <mf TMask::add_date> <mf TMask::add_button> <mf TMask::add_radio>
 | 
						|
{
 | 
						|
  TMemo_field* f = new TMemo_field(this);
 | 
						|
  f->construct(id, prompt, x, y, dy, _pagewin[page], flags, dx);
 | 
						|
  _field.add(f);
 | 
						|
  return ((TMask_field*)f)->win();
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Permette di salvare il 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((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;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Permette di leggere il file di salvataggio
 | 
						|
//
 | 
						|
 | 
						|
// @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((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];
 | 
						|
  xvt_vobj_get_title(_pagewin[0], title, 80);
 | 
						|
  return title;
 | 
						|
}
 | 
						|
 | 
						|
void TMask::set_caption(const char* c)
 | 
						|
{
 | 
						|
  for (int p = 0; p < _pages; p++)
 | 
						|
    xvt_vobj_set_title(_pagewin[p], (char*)c);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Setta il valore attuale della valuta
 | 
						|
void TMask::set_exchange(
 | 
						|
  bool show_value, // @parm Indica se il deve essere visibile l'importo in valuta
 | 
						|
  const real& n)   // @parm Indica il cambio attuale della valuta
 | 
						|
{
 | 
						|
  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();
 | 
						|
}
 | 
						|
 | 
						|
 |